Ensure that any memory leaked during an error inside the bgwriter is
authorTom Lane
Mon, 12 Sep 2005 22:20:16 +0000 (22:20 +0000)
committerTom Lane
Mon, 12 Sep 2005 22:20:16 +0000 (22:20 +0000)
recovered.  I did not see any actual leak while testing this in CVS tip,
but 8.0 definitely has a problem with leaking the space temporarily
palloc'd by BufferSync().  In any case this seems a good idea to forestall
similar problems in future.  Per report from Arjen van der Meijden.

src/backend/postmaster/bgwriter.c

index 830cb897d98fb38f6df68c861ccfa4a90fbc90ca..ed1a7b2f2712aa24eef74bfda48ad93596beee86 100644 (file)
@@ -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();