修复twophasecleaner内存泄漏

This commit is contained in:
Xiao__Ma 2022-01-19 15:04:42 +08:00
parent c3b98cd084
commit 83d10255b7
1 changed files with 25 additions and 13 deletions

View File

@ -118,6 +118,19 @@ NON_EXEC_STATIC void TwoPhaseCleanerMain()
/* We allow SIGQUIT (quickdie) at all times */
(void)sigdelset(&t_thrd.libpq_cxt.BlockSig, SIGQUIT);
/*
* 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
* t_thrd.top_mem_cxt, but resetting that would be a really bad idea.
*/
twopc_context = AllocSetContextCreate(t_thrd.top_mem_cxt,
"TwoPhase Cleaner",
ALLOCSET_DEFAULT_MINSIZE,
ALLOCSET_DEFAULT_INITSIZE,
ALLOCSET_DEFAULT_MAXSIZE);
(void)MemoryContextSwitchTo(twopc_context);
/*
* If an exception is encountered, processing resumes here.
*
@ -133,8 +146,18 @@ NON_EXEC_STATIC void TwoPhaseCleanerMain()
/* Report the error to the server log */
EmitErrorReport();
/*
* Now return to normal top-level context and clear ErrorContext for
* next time.
*/
(void)MemoryContextSwitchTo(twopc_context);
FlushErrorState();
/* Flush any leaked data in the top-level context */
MemoryContextResetAndDeleteChildren(twopc_context);
/* Now we can allow interrupts again */
RESUME_INTERRUPTS();
}
@ -143,19 +166,6 @@ NON_EXEC_STATIC void TwoPhaseCleanerMain()
/* We can now handle ereport(ERROR) */
t_thrd.log_cxt.PG_exception_stack = &local_sigjmp_buf;
/*
* 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
* t_thrd.top_mem_cxt, but resetting that would be a really bad idea.
*/
twopc_context = AllocSetContextCreate(t_thrd.top_mem_cxt,
"TwoPhase Cleaner",
ALLOCSET_DEFAULT_MINSIZE,
ALLOCSET_DEFAULT_INITSIZE,
ALLOCSET_DEFAULT_MAXSIZE);
(void)MemoryContextSwitchTo(twopc_context);
/* Unblock signals (they were blocked when the postmaster forked us) */
gs_signal_setmask(&t_thrd.libpq_cxt.UnBlockSig, NULL);
(void)gs_signal_unblock_sigusr2();
@ -271,6 +281,8 @@ NON_EXEC_STATIC void TwoPhaseCleanerMain()
pgstat_report_activity(STATE_IDLE, NULL);
rc = WaitLatch(&t_thrd.proc->procLatch, WL_LATCH_SET | WL_TIMEOUT | WL_POSTMASTER_DEATH, (long)10000 /* 10s */);
MemoryContextResetAndDeleteChildren(twopc_context);
/*
* Emergency bailout if postmaster has died. This is to avoid the
* necessity for manual cleanup of all postmaster children.