diff options
author | Andres Freund <andres@anarazel.de> | 2025-01-24 17:00:10 -0500 |
---|---|---|
committer | Andres Freund <andres@anarazel.de> | 2025-01-24 17:00:10 -0500 |
commit | 8edd8c77c88e75822334ccb8376d2c151d6e5615 (patch) | |
tree | b4b4ea18865a87e4e2e2364fad947b58fb215c6d | |
parent | f0b7ab7251390544c5e79d1d9c96da254181fc4f (diff) | |
download | postgresql-8edd8c77c88e75822334ccb8376d2c151d6e5615.tar.gz postgresql-8edd8c77c88e75822334ccb8376d2c151d6e5615.zip |
postmaster: Move code to switch into FatalError state into function
There are two places switching to FatalError mode, behaving somewhat
differently. An upcoming commit will introduce a third. That doesn't seem seem
like a good idea.
This commit just moves the FatalError related code from HandleChildCrash()
into its own function, a subsequent commit will evolve the state machine
change to be suitable for other callers.
Reviewed-by: Bertrand Drouvot <bertranddrouvot.pg@gmail.com>
Discussion: https://postgr.es/m/kgng5nrvnlv335evmsuvpnh354rw7qyazl73kdysev2cr2v5zu@m3cfzxicm5kp
-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 |