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.
This commit is contained in:
Tom Lane 2005-09-12 22:20:16 +00:00
parent 9813fc1bae
commit f59b05c95d

View File

@ -37,7 +37,7 @@
* *
* *
* IDENTIFICATION * 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) BackgroundWriterMain(void)
{ {
sigjmp_buf local_sigjmp_buf; sigjmp_buf local_sigjmp_buf;
MemoryContext bgwriter_context;
Assert(BgWriterShmem != NULL); Assert(BgWriterShmem != NULL);
BgWriterShmem->bgwriter_pid = MyProcPid; BgWriterShmem->bgwriter_pid = MyProcPid;
@ -207,6 +208,19 @@ BackgroundWriterMain(void)
*/ */
last_checkpoint_time = time(NULL); 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. * If an exception is encountered, processing resumes here.
* *
@ -247,9 +261,12 @@ BackgroundWriterMain(void)
* Now return to normal top-level context and clear ErrorContext * Now return to normal top-level context and clear ErrorContext
* for next time. * for next time.
*/ */
MemoryContextSwitchTo(TopMemoryContext); MemoryContextSwitchTo(bgwriter_context);
FlushErrorState(); FlushErrorState();
/* Flush any leaked data in the top-level context */
MemoryContextResetAndDeleteChildren(bgwriter_context);
/* Now we can allow interrupts again */ /* Now we can allow interrupts again */
RESUME_INTERRUPTS(); RESUME_INTERRUPTS();