diff --git a/src/backend/postmaster/bgwriter.c b/src/backend/postmaster/bgwriter.c
index 830cb897d98fb38f6df68c861ccfa4a90fbc90ca..ed1a7b2f2712aa24eef74bfda48ad93596beee86 100644
--- a/src/backend/postmaster/bgwriter.c
+++ b/src/backend/postmaster/bgwriter.c
@@ -37,7 +37,7 @@
  *
  *
  * IDENTIFICATION
- *	  $PostgreSQL: pgsql/src/backend/postmaster/bgwriter.c,v 1.19 2005/08/20 23:26:17 tgl Exp $
+ *	  $PostgreSQL: pgsql/src/backend/postmaster/bgwriter.c,v 1.20 2005/09/12 22:20:16 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -160,6 +160,7 @@ void
 BackgroundWriterMain(void)
 {
 	sigjmp_buf	local_sigjmp_buf;
+	MemoryContext bgwriter_context;
 
 	Assert(BgWriterShmem != NULL);
 	BgWriterShmem->bgwriter_pid = MyProcPid;
@@ -207,6 +208,19 @@ BackgroundWriterMain(void)
 	 */
 	last_checkpoint_time = time(NULL);
 
+	/*
+	 * Create a memory context that we will do all our work in.  We do this
+	 * so that we can reset the context during error recovery and thereby
+	 * avoid possible memory leaks.  Formerly this code just ran in
+	 * TopMemoryContext, but resetting that would be a really bad idea.
+	 */
+	bgwriter_context = AllocSetContextCreate(TopMemoryContext,
+											 "Background Writer",
+											 ALLOCSET_DEFAULT_MINSIZE,
+											 ALLOCSET_DEFAULT_INITSIZE,
+											 ALLOCSET_DEFAULT_MAXSIZE);
+	MemoryContextSwitchTo(bgwriter_context);
+
 	/*
 	 * If an exception is encountered, processing resumes here.
 	 *
@@ -247,9 +261,12 @@ BackgroundWriterMain(void)
 		 * Now return to normal top-level context and clear ErrorContext
 		 * for next time.
 		 */
-		MemoryContextSwitchTo(TopMemoryContext);
+		MemoryContextSwitchTo(bgwriter_context);
 		FlushErrorState();
 
+		/* Flush any leaked data in the top-level context */
+		MemoryContextResetAndDeleteChildren(bgwriter_context);
+
 		/* Now we can allow interrupts again */
 		RESUME_INTERRUPTS();