diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/backend/postmaster/postmaster.c | 74 |
1 files changed, 51 insertions, 23 deletions
diff --git a/src/backend/postmaster/postmaster.c b/src/backend/postmaster/postmaster.c index a24c0385fe6..a92fe4240b2 100644 --- a/src/backend/postmaster/postmaster.c +++ b/src/backend/postmaster/postmaster.c @@ -2674,40 +2674,35 @@ CleanupBackend(PMChild *bp, } /* - * HandleChildCrash -- cleanup after failed backend, bgwriter, checkpointer, - * walwriter, autovacuum, archiver, slot sync worker, or background worker. + * Transition into FatalError state, in response to something bad having + * happened. Commonly the caller will have logged the reason for entering + * FatalError state. * - * The objectives here are to clean up our local state about the child - * process, and to signal all other remaining children to quickdie. - * - * The caller has already released its PMChild slot. + * This should only be called when not already in FatalError or + * ImmediateShutdown state. */ static void -HandleChildCrash(int pid, int exitstatus, const char *procname) +HandleFatalError(QuitSignalReason reason, bool consider_sigabrt) { - /* - * We only log messages and send signals if this is the first process - * crash and we're not doing an immediate shutdown; otherwise, we're only - * here to update postmaster's idea of live processes. If we have already - * signaled children, nonzero exit status is to be expected, so don't - * clutter log. - */ - if (FatalError || Shutdown == ImmediateShutdown) - return; + int sigtosend; - LogChildExit(LOG, procname, pid, exitstatus); - ereport(LOG, - (errmsg("terminating any other active server processes"))); - SetQuitSignalReason(PMQUIT_FOR_CRASH); + Assert(!FatalError); + Assert(Shutdown != ImmediateShutdown); + + SetQuitSignalReason(reason); + + if (consider_sigabrt && send_abort_for_crash) + sigtosend = SIGABRT; + else + sigtosend = SIGQUIT; /* - * Signal all other child processes to exit. The crashed process has - * already been removed from ActiveChildList. + * Signal all other child processes to exit. * * We could exclude dead-end children here, but at least when sending * SIGABRT it seems better to include them. */ - TerminateChildren(send_abort_for_crash ? SIGABRT : SIGQUIT); + TerminateChildren(sigtosend); FatalError = true; @@ -2728,6 +2723,39 @@ HandleChildCrash(int pid, int exitstatus, const char *procname) } /* + * HandleChildCrash -- cleanup after failed backend, bgwriter, checkpointer, + * walwriter, autovacuum, archiver, slot sync worker, or background worker. + * + * The objectives here are to clean up our local state about the child + * process, and to signal all other remaining children to quickdie. + * + * The caller has already released its PMChild slot. + */ +static void +HandleChildCrash(int pid, int exitstatus, const char *procname) +{ + /* + * We only log messages and send signals if this is the first process + * crash and we're not doing an immediate shutdown; otherwise, we're only + * here to update postmaster's idea of live processes. If we have already + * signaled children, nonzero exit status is to be expected, so don't + * clutter log. + */ + if (FatalError || Shutdown == ImmediateShutdown) + return; + + LogChildExit(LOG, procname, pid, exitstatus); + ereport(LOG, + (errmsg("terminating any other active server processes"))); + + /* + * Switch into error state. The crashed process has already been removed + * from ActiveChildList. + */ + HandleFatalError(PMQUIT_FOR_CRASH, true); +} + +/* * Log the death of a child process. */ static void |