1
0
mirror of https://github.com/postgres/postgres.git synced 2025-04-27 22:56:53 +03:00

postmaster: Update pmState via a wrapper function

This makes logging of state changes easier - state transitions are now logged
at DEBUG1. Without that logging it was surprisingly hard to understand the
current state of the system while debugging.

Reviewed-by: Heikki Linnakangas <hlinnaka@iki.fi>
Reviewed-by: Bertrand Drouvot <bertranddrouvot.pg@gmail.com>
Reviewed-by: Nazir Bilal Yavuz <byavuz81@gmail.com>
Discussion: https://postgr.es/m/kgng5nrvnlv335evmsuvpnh354rw7qyazl73kdysev2cr2v5zu@m3cfzxicm5kp
This commit is contained in:
Andres Freund 2025-01-10 11:08:17 -05:00
parent cc811f92ba
commit 7148cbbdc6

View File

@ -411,6 +411,7 @@ static void HandleChildCrash(int pid, int exitstatus, const char *procname);
static void LogChildExit(int lev, const char *procname, static void LogChildExit(int lev, const char *procname,
int pid, int exitstatus); int pid, int exitstatus);
static void PostmasterStateMachine(void); static void PostmasterStateMachine(void);
static void UpdatePMState(PMState newState);
static void ExitPostmaster(int status) pg_attribute_noreturn(); static void ExitPostmaster(int status) pg_attribute_noreturn();
static int ServerLoop(void); static int ServerLoop(void);
@ -1363,7 +1364,7 @@ PostmasterMain(int argc, char *argv[])
StartupPMChild = StartChildProcess(B_STARTUP); StartupPMChild = StartChildProcess(B_STARTUP);
Assert(StartupPMChild != NULL); Assert(StartupPMChild != NULL);
StartupStatus = STARTUP_RUNNING; StartupStatus = STARTUP_RUNNING;
pmState = PM_STARTUP; UpdatePMState(PM_STARTUP);
/* Some workers may be scheduled to start now */ /* Some workers may be scheduled to start now */
maybe_start_bgworkers(); maybe_start_bgworkers();
@ -2099,7 +2100,7 @@ process_pm_shutdown_request(void)
else if (pmState == PM_STARTUP || pmState == PM_RECOVERY) else if (pmState == PM_STARTUP || pmState == PM_RECOVERY)
{ {
/* There should be no clients, so proceed to stop children */ /* There should be no clients, so proceed to stop children */
pmState = PM_STOP_BACKENDS; UpdatePMState(PM_STOP_BACKENDS);
} }
/* /*
@ -2133,7 +2134,7 @@ process_pm_shutdown_request(void)
if (pmState == PM_STARTUP || pmState == PM_RECOVERY) if (pmState == PM_STARTUP || pmState == PM_RECOVERY)
{ {
/* Just shut down background processes silently */ /* Just shut down background processes silently */
pmState = PM_STOP_BACKENDS; UpdatePMState(PM_STOP_BACKENDS);
} }
else if (pmState == PM_RUN || else if (pmState == PM_RUN ||
pmState == PM_HOT_STANDBY) pmState == PM_HOT_STANDBY)
@ -2141,7 +2142,7 @@ process_pm_shutdown_request(void)
/* Report that we're about to zap live client sessions */ /* Report that we're about to zap live client sessions */
ereport(LOG, ereport(LOG,
(errmsg("aborting any active transactions"))); (errmsg("aborting any active transactions")));
pmState = PM_STOP_BACKENDS; UpdatePMState(PM_STOP_BACKENDS);
} }
/* /*
@ -2176,7 +2177,7 @@ process_pm_shutdown_request(void)
/* (note we don't apply send_abort_for_crash here) */ /* (note we don't apply send_abort_for_crash here) */
SetQuitSignalReason(PMQUIT_FOR_STOP); SetQuitSignalReason(PMQUIT_FOR_STOP);
TerminateChildren(SIGQUIT); TerminateChildren(SIGQUIT);
pmState = PM_WAIT_BACKENDS; UpdatePMState(PM_WAIT_BACKENDS);
/* set stopwatch for them to die */ /* set stopwatch for them to die */
AbortStartTime = time(NULL); AbortStartTime = time(NULL);
@ -2231,7 +2232,7 @@ process_pm_child_exit(void)
(EXIT_STATUS_0(exitstatus) || EXIT_STATUS_1(exitstatus))) (EXIT_STATUS_0(exitstatus) || EXIT_STATUS_1(exitstatus)))
{ {
StartupStatus = STARTUP_NOT_RUNNING; StartupStatus = STARTUP_NOT_RUNNING;
pmState = PM_WAIT_BACKENDS; UpdatePMState(PM_WAIT_BACKENDS);
/* PostmasterStateMachine logic does the rest */ /* PostmasterStateMachine logic does the rest */
continue; continue;
} }
@ -2243,7 +2244,7 @@ process_pm_child_exit(void)
StartupStatus = STARTUP_NOT_RUNNING; StartupStatus = STARTUP_NOT_RUNNING;
Shutdown = Max(Shutdown, SmartShutdown); Shutdown = Max(Shutdown, SmartShutdown);
TerminateChildren(SIGTERM); TerminateChildren(SIGTERM);
pmState = PM_WAIT_BACKENDS; UpdatePMState(PM_WAIT_BACKENDS);
/* PostmasterStateMachine logic does the rest */ /* PostmasterStateMachine logic does the rest */
continue; continue;
} }
@ -2288,7 +2289,7 @@ process_pm_child_exit(void)
{ {
StartupStatus = STARTUP_NOT_RUNNING; StartupStatus = STARTUP_NOT_RUNNING;
if (pmState == PM_STARTUP) if (pmState == PM_STARTUP)
pmState = PM_WAIT_BACKENDS; UpdatePMState(PM_WAIT_BACKENDS);
} }
else else
StartupStatus = STARTUP_CRASHED; StartupStatus = STARTUP_CRASHED;
@ -2304,7 +2305,7 @@ process_pm_child_exit(void)
FatalError = false; FatalError = false;
AbortStartTime = 0; AbortStartTime = 0;
ReachedNormalRunning = true; ReachedNormalRunning = true;
pmState = PM_RUN; UpdatePMState(PM_RUN);
connsAllowed = true; connsAllowed = true;
/* /*
@ -2377,7 +2378,7 @@ process_pm_child_exit(void)
*/ */
SignalChildren(SIGUSR2, btmask(B_WAL_SENDER)); SignalChildren(SIGUSR2, btmask(B_WAL_SENDER));
pmState = PM_SHUTDOWN_2; UpdatePMState(PM_SHUTDOWN_2);
} }
else else
{ {
@ -2729,7 +2730,7 @@ HandleChildCrash(int pid, int exitstatus, const char *procname)
pmState == PM_RUN || pmState == PM_RUN ||
pmState == PM_STOP_BACKENDS || pmState == PM_STOP_BACKENDS ||
pmState == PM_SHUTDOWN) pmState == PM_SHUTDOWN)
pmState = PM_WAIT_BACKENDS; UpdatePMState(PM_WAIT_BACKENDS);
/* /*
* .. and if this doesn't happen quickly enough, now the clock is ticking * .. and if this doesn't happen quickly enough, now the clock is ticking
@ -2821,7 +2822,7 @@ PostmasterStateMachine(void)
* Then we're ready to stop other children. * Then we're ready to stop other children.
*/ */
if (CountChildren(btmask(B_BACKEND)) == 0) if (CountChildren(btmask(B_BACKEND)) == 0)
pmState = PM_STOP_BACKENDS; UpdatePMState(PM_STOP_BACKENDS);
} }
} }
@ -2909,7 +2910,7 @@ PostmasterStateMachine(void)
SignalChildren(SIGTERM, targetMask); SignalChildren(SIGTERM, targetMask);
pmState = PM_WAIT_BACKENDS; UpdatePMState(PM_WAIT_BACKENDS);
} }
/* Are any of the target processes still running? */ /* Are any of the target processes still running? */
@ -2920,7 +2921,7 @@ PostmasterStateMachine(void)
/* /*
* Stop any dead-end children and stop creating new ones. * Stop any dead-end children and stop creating new ones.
*/ */
pmState = PM_WAIT_DEAD_END; UpdatePMState(PM_WAIT_DEAD_END);
ConfigurePostmasterWaitSet(false); ConfigurePostmasterWaitSet(false);
SignalChildren(SIGQUIT, btmask(B_DEAD_END_BACKEND)); SignalChildren(SIGQUIT, btmask(B_DEAD_END_BACKEND));
@ -2945,7 +2946,7 @@ PostmasterStateMachine(void)
if (CheckpointerPMChild != NULL) if (CheckpointerPMChild != NULL)
{ {
signal_child(CheckpointerPMChild, SIGUSR2); signal_child(CheckpointerPMChild, SIGUSR2);
pmState = PM_SHUTDOWN; UpdatePMState(PM_SHUTDOWN);
} }
else else
{ {
@ -2960,7 +2961,7 @@ PostmasterStateMachine(void)
* for checkpointer fork failure. * for checkpointer fork failure.
*/ */
FatalError = true; FatalError = true;
pmState = PM_WAIT_DEAD_END; UpdatePMState(PM_WAIT_DEAD_END);
ConfigurePostmasterWaitSet(false); ConfigurePostmasterWaitSet(false);
/* Kill the walsenders and archiver too */ /* Kill the walsenders and archiver too */
@ -2980,7 +2981,7 @@ PostmasterStateMachine(void)
*/ */
if (CountChildren(btmask_all_except2(B_LOGGER, B_DEAD_END_BACKEND)) == 0) if (CountChildren(btmask_all_except2(B_LOGGER, B_DEAD_END_BACKEND)) == 0)
{ {
pmState = PM_WAIT_DEAD_END; UpdatePMState(PM_WAIT_DEAD_END);
ConfigurePostmasterWaitSet(false); ConfigurePostmasterWaitSet(false);
SignalChildren(SIGTERM, btmask_all_except(B_LOGGER)); SignalChildren(SIGTERM, btmask_all_except(B_LOGGER));
} }
@ -3013,7 +3014,7 @@ PostmasterStateMachine(void)
Assert(AutoVacLauncherPMChild == NULL); Assert(AutoVacLauncherPMChild == NULL);
Assert(SlotSyncWorkerPMChild == NULL); Assert(SlotSyncWorkerPMChild == NULL);
/* syslogger is not considered here */ /* syslogger is not considered here */
pmState = PM_NO_CHILDREN; UpdatePMState(PM_NO_CHILDREN);
} }
} }
@ -3097,7 +3098,7 @@ PostmasterStateMachine(void)
StartupPMChild = StartChildProcess(B_STARTUP); StartupPMChild = StartChildProcess(B_STARTUP);
Assert(StartupPMChild != NULL); Assert(StartupPMChild != NULL);
StartupStatus = STARTUP_RUNNING; StartupStatus = STARTUP_RUNNING;
pmState = PM_STARTUP; UpdatePMState(PM_STARTUP);
/* crash recovery started, reset SIGKILL flag */ /* crash recovery started, reset SIGKILL flag */
AbortStartTime = 0; AbortStartTime = 0;
@ -3106,6 +3107,42 @@ PostmasterStateMachine(void)
} }
} }
static const char *
pmstate_name(PMState state)
{
#define PM_TOSTR_CASE(sym) case sym: return #sym
switch (state)
{
PM_TOSTR_CASE(PM_INIT);
PM_TOSTR_CASE(PM_STARTUP);
PM_TOSTR_CASE(PM_RECOVERY);
PM_TOSTR_CASE(PM_HOT_STANDBY);
PM_TOSTR_CASE(PM_RUN);
PM_TOSTR_CASE(PM_STOP_BACKENDS);
PM_TOSTR_CASE(PM_WAIT_BACKENDS);
PM_TOSTR_CASE(PM_SHUTDOWN);
PM_TOSTR_CASE(PM_SHUTDOWN_2);
PM_TOSTR_CASE(PM_WAIT_DEAD_END);
PM_TOSTR_CASE(PM_NO_CHILDREN);
}
#undef PM_TOSTR_CASE
pg_unreachable();
return ""; /* silence compiler */
}
/*
* Simple wrapper for updating pmState. The main reason to have this wrapper
* is that it makes it easy to log all state transitions.
*/
static void
UpdatePMState(PMState newState)
{
elog(DEBUG1, "updating PMState from %s to %s",
pmstate_name(pmState), pmstate_name(newState));
pmState = newState;
}
/* /*
* Launch background processes after state change, or relaunch after an * Launch background processes after state change, or relaunch after an
* existing process has exited. * existing process has exited.
@ -3524,7 +3561,7 @@ process_pm_pmsignal(void)
#endif #endif
} }
pmState = PM_RECOVERY; UpdatePMState(PM_RECOVERY);
} }
if (CheckPostmasterSignal(PMSIGNAL_BEGIN_HOT_STANDBY) && if (CheckPostmasterSignal(PMSIGNAL_BEGIN_HOT_STANDBY) &&
@ -3539,7 +3576,7 @@ process_pm_pmsignal(void)
sd_notify(0, "READY=1"); sd_notify(0, "READY=1");
#endif #endif
pmState = PM_HOT_STANDBY; UpdatePMState(PM_HOT_STANDBY);
connsAllowed = true; connsAllowed = true;
/* Some workers may be scheduled to start now */ /* Some workers may be scheduled to start now */