diff --git a/src/gausskernel/process/postmaster/twophasecleaner.cpp b/src/gausskernel/process/postmaster/twophasecleaner.cpp index f3f5e3a7f..2f171c833 100644 --- a/src/gausskernel/process/postmaster/twophasecleaner.cpp +++ b/src/gausskernel/process/postmaster/twophasecleaner.cpp @@ -131,6 +131,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. * @@ -146,8 +159,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(); } @@ -156,19 +179,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(); @@ -285,6 +295,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.