From f59b05c95d60dd0e89a80d6ba601461f488ba669 Mon Sep 17 00:00:00 2001
From: Tom Lane <tgl@sss.pgh.pa.us>
Date: Mon, 12 Sep 2005 22:20:16 +0000
Subject: [PATCH] Ensure that any memory leaked during an error inside the
 bgwriter is 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 | 21 +++++++++++++++++++--
 1 file changed, 19 insertions(+), 2 deletions(-)

diff --git a/src/backend/postmaster/bgwriter.c b/src/backend/postmaster/bgwriter.c
index 830cb897d98..ed1a7b2f271 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();
 
-- 
GitLab