postmaster: Update pmState via a wrapper function
authorAndres Freund <[email protected]>
Fri, 10 Jan 2025 16:08:17 +0000 (11:08 -0500)
committerAndres Freund <[email protected]>
Fri, 10 Jan 2025 16:42:56 +0000 (11:42 -0500)
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 <[email protected]>
Reviewed-by: Bertrand Drouvot <[email protected]>
Reviewed-by: Nazir Bilal Yavuz <[email protected]>
Discussion: https://postgr.es/m/kgng5nrvnlv335evmsuvpnh354rw7qyazl73kdysev2cr2v5zu@m3cfzxicm5kp

src/backend/postmaster/postmaster.c

index 0a915dac4f76ddd0b8edc0754ab3fbe5b45eec6c..3a9ad897837fed80327e7e1791517bd96178c8bf 100644 (file)
@@ -411,6 +411,7 @@ static void HandleChildCrash(int pid, int exitstatus, const char *procname);
 static void LogChildExit(int lev, const char *procname,
                                                 int pid, int exitstatus);
 static void PostmasterStateMachine(void);
+static void UpdatePMState(PMState newState);
 
 static void ExitPostmaster(int status) pg_attribute_noreturn();
 static int     ServerLoop(void);
@@ -1363,7 +1364,7 @@ PostmasterMain(int argc, char *argv[])
        StartupPMChild = StartChildProcess(B_STARTUP);
        Assert(StartupPMChild != NULL);
        StartupStatus = STARTUP_RUNNING;
-       pmState = PM_STARTUP;
+       UpdatePMState(PM_STARTUP);
 
        /* Some workers may be scheduled to start now */
        maybe_start_bgworkers();
@@ -2099,7 +2100,7 @@ process_pm_shutdown_request(void)
                        else if (pmState == PM_STARTUP || pmState == PM_RECOVERY)
                        {
                                /* 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)
                        {
                                /* Just shut down background processes silently */
-                               pmState = PM_STOP_BACKENDS;
+                               UpdatePMState(PM_STOP_BACKENDS);
                        }
                        else if (pmState == PM_RUN ||
                                         pmState == PM_HOT_STANDBY)
@@ -2141,7 +2142,7 @@ process_pm_shutdown_request(void)
                                /* Report that we're about to zap live client sessions */
                                ereport(LOG,
                                                (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) */
                        SetQuitSignalReason(PMQUIT_FOR_STOP);
                        TerminateChildren(SIGQUIT);
-                       pmState = PM_WAIT_BACKENDS;
+                       UpdatePMState(PM_WAIT_BACKENDS);
 
                        /* set stopwatch for them to die */
                        AbortStartTime = time(NULL);
@@ -2231,7 +2232,7 @@ process_pm_child_exit(void)
                                (EXIT_STATUS_0(exitstatus) || EXIT_STATUS_1(exitstatus)))
                        {
                                StartupStatus = STARTUP_NOT_RUNNING;
-                               pmState = PM_WAIT_BACKENDS;
+                               UpdatePMState(PM_WAIT_BACKENDS);
                                /* PostmasterStateMachine logic does the rest */
                                continue;
                        }
@@ -2243,7 +2244,7 @@ process_pm_child_exit(void)
                                StartupStatus = STARTUP_NOT_RUNNING;
                                Shutdown = Max(Shutdown, SmartShutdown);
                                TerminateChildren(SIGTERM);
-                               pmState = PM_WAIT_BACKENDS;
+                               UpdatePMState(PM_WAIT_BACKENDS);
                                /* PostmasterStateMachine logic does the rest */
                                continue;
                        }
@@ -2288,7 +2289,7 @@ process_pm_child_exit(void)
                                {
                                        StartupStatus = STARTUP_NOT_RUNNING;
                                        if (pmState == PM_STARTUP)
-                                               pmState = PM_WAIT_BACKENDS;
+                                               UpdatePMState(PM_WAIT_BACKENDS);
                                }
                                else
                                        StartupStatus = STARTUP_CRASHED;
@@ -2304,7 +2305,7 @@ process_pm_child_exit(void)
                        FatalError = false;
                        AbortStartTime = 0;
                        ReachedNormalRunning = true;
-                       pmState = PM_RUN;
+                       UpdatePMState(PM_RUN);
                        connsAllowed = true;
 
                        /*
@@ -2377,7 +2378,7 @@ process_pm_child_exit(void)
                                 */
                                SignalChildren(SIGUSR2, btmask(B_WAL_SENDER));
 
-                               pmState = PM_SHUTDOWN_2;
+                               UpdatePMState(PM_SHUTDOWN_2);
                        }
                        else
                        {
@@ -2729,7 +2730,7 @@ HandleChildCrash(int pid, int exitstatus, const char *procname)
                pmState == PM_RUN ||
                pmState == PM_STOP_BACKENDS ||
                pmState == PM_SHUTDOWN)
-               pmState = PM_WAIT_BACKENDS;
+               UpdatePMState(PM_WAIT_BACKENDS);
 
        /*
         * .. 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.
                         */
                        if (CountChildren(btmask(B_BACKEND)) == 0)
-                               pmState = PM_STOP_BACKENDS;
+                               UpdatePMState(PM_STOP_BACKENDS);
                }
        }
 
@@ -2909,7 +2910,7 @@ PostmasterStateMachine(void)
 
                        SignalChildren(SIGTERM, targetMask);
 
-                       pmState = PM_WAIT_BACKENDS;
+                       UpdatePMState(PM_WAIT_BACKENDS);
                }
 
                /* Are any of the target processes still running? */
@@ -2920,7 +2921,7 @@ PostmasterStateMachine(void)
                                /*
                                 * Stop any dead-end children and stop creating new ones.
                                 */
-                               pmState = PM_WAIT_DEAD_END;
+                               UpdatePMState(PM_WAIT_DEAD_END);
                                ConfigurePostmasterWaitSet(false);
                                SignalChildren(SIGQUIT, btmask(B_DEAD_END_BACKEND));
 
@@ -2945,7 +2946,7 @@ PostmasterStateMachine(void)
                                if (CheckpointerPMChild != NULL)
                                {
                                        signal_child(CheckpointerPMChild, SIGUSR2);
-                                       pmState = PM_SHUTDOWN;
+                                       UpdatePMState(PM_SHUTDOWN);
                                }
                                else
                                {
@@ -2960,7 +2961,7 @@ PostmasterStateMachine(void)
                                         * for checkpointer fork failure.
                                         */
                                        FatalError = true;
-                                       pmState = PM_WAIT_DEAD_END;
+                                       UpdatePMState(PM_WAIT_DEAD_END);
                                        ConfigurePostmasterWaitSet(false);
 
                                        /* Kill the walsenders and archiver too */
@@ -2980,7 +2981,7 @@ PostmasterStateMachine(void)
                 */
                if (CountChildren(btmask_all_except2(B_LOGGER, B_DEAD_END_BACKEND)) == 0)
                {
-                       pmState = PM_WAIT_DEAD_END;
+                       UpdatePMState(PM_WAIT_DEAD_END);
                        ConfigurePostmasterWaitSet(false);
                        SignalChildren(SIGTERM, btmask_all_except(B_LOGGER));
                }
@@ -3013,7 +3014,7 @@ PostmasterStateMachine(void)
                        Assert(AutoVacLauncherPMChild == NULL);
                        Assert(SlotSyncWorkerPMChild == NULL);
                        /* syslogger is not considered here */
-                       pmState = PM_NO_CHILDREN;
+                       UpdatePMState(PM_NO_CHILDREN);
                }
        }
 
@@ -3097,7 +3098,7 @@ PostmasterStateMachine(void)
                StartupPMChild = StartChildProcess(B_STARTUP);
                Assert(StartupPMChild != NULL);
                StartupStatus = STARTUP_RUNNING;
-               pmState = PM_STARTUP;
+               UpdatePMState(PM_STARTUP);
                /* crash recovery started, reset SIGKILL flag */
                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
  * existing process has exited.
@@ -3524,7 +3561,7 @@ process_pm_pmsignal(void)
 #endif
                }
 
-               pmState = PM_RECOVERY;
+               UpdatePMState(PM_RECOVERY);
        }
 
        if (CheckPostmasterSignal(PMSIGNAL_BEGIN_HOT_STANDBY) &&
@@ -3539,7 +3576,7 @@ process_pm_pmsignal(void)
                sd_notify(0, "READY=1");
 #endif
 
-               pmState = PM_HOT_STANDBY;
+               UpdatePMState(PM_HOT_STANDBY);
                connsAllowed = true;
 
                /* Some workers may be scheduled to start now */