]> granicus.if.org Git - postgresql/commitdiff
Ensure that any memory leaked during an error inside the bgwriter is
authorTom Lane <tgl@sss.pgh.pa.us>
Mon, 12 Sep 2005 22:20:16 +0000 (22:20 +0000)
committerTom Lane <tgl@sss.pgh.pa.us>
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();