Ensure that any memory leaked during an error inside the bgwriter is
authorTom Lane <[email protected]>
Mon, 12 Sep 2005 22:20:30 +0000 (22:20 +0000)
committerTom Lane <[email protected]>
Mon, 12 Sep 2005 22:20:30 +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 e2c3f39537903c8ed8cf23dd5d8b9f627aa04c2c..4394a2f637121f8ce7792c6dec36ce4e86c12766 100644 (file)
@@ -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();