]> granicus.if.org Git - postgresql/commitdiff
Avoid possible hang during smart shutdown.
authorRobert Haas <rhaas@postgresql.org>
Sun, 3 Apr 2011 23:42:00 +0000 (19:42 -0400)
committerRobert Haas <rhaas@postgresql.org>
Sun, 3 Apr 2011 23:42:00 +0000 (19:42 -0400)
If a smart shutdown occurs just as a child is starting up, and the
child subsequently becomes a walsender, there is a race condition:
the postmaster might count the exstant backends, determine that there
is one normal backend, and wait for it to die off.  Had the walsender
transition already occurred before the postmaster counted, it would
have proceeded with the shutdown.

To fix this, have each child that transforms into a walsender kick
the postmaster just after doing so, so that the state machine is
certain to advance.

Fujii Masao

src/backend/postmaster/postmaster.c
src/backend/replication/walsender.c
src/include/storage/pmsignal.h

index 997af5bf07243e8239cc389dee5980c72de0f3ae..93e59258cc514c75ec29a7687e08eea3834b6aad 100644 (file)
@@ -2890,8 +2890,8 @@ LogChildExit(int lev, const char *procname, int pid, int exitstatus)
 /*
  * Advance the postmaster's state machine and take actions as appropriate
  *
- * This is common code for pmdie() and reaper(), which receive the signals
- * that might mean we need to change state.
+ * This is common code for pmdie(), reaper() and sigusr1_handler(), which
+ * receive the signals that might mean we need to change state.
  */
 static void
 PostmasterStateMachine(void)
@@ -4284,6 +4284,13 @@ sigusr1_handler(SIGNAL_ARGS)
                WalReceiverPID = StartWalReceiver();
        }
 
+       if (CheckPostmasterSignal(PMSIGNAL_ADVANCE_STATE_MACHINE) &&
+               (pmState == PM_WAIT_BACKUP || pmState == PM_WAIT_BACKENDS))
+       {
+               /* Advance postmaster's state machine */
+               PostmasterStateMachine();
+       }
+
        if (CheckPromoteSignal() && StartupPID != 0 &&
                (pmState == PM_STARTUP || pmState == PM_RECOVERY ||
                 pmState == PM_HOT_STANDBY || pmState == PM_WAIT_READONLY))
index dde773d79e18de8122d372abc59e0f967a639698..1c11e7ff7a21e24aa5056b630bef711dd1d22402 100644 (file)
@@ -361,6 +361,7 @@ StartReplication(StartReplicationCmd * cmd)
         * after this.
         */
        MarkPostmasterChildWalSender();
+       SendPostmasterSignal(PMSIGNAL_ADVANCE_STATE_MACHINE);
 
        /*
         * Check that we're logging enough information in the WAL for
index 97bdc7bc86d7f5d78e8ede1eee4edd8742e94ad8..0ca8ca0cc7e55e3a672807e13fdce08fffc2ad0b 100644 (file)
@@ -29,6 +29,7 @@ typedef enum
        PMSIGNAL_START_AUTOVAC_LAUNCHER,        /* start an autovacuum launcher */
        PMSIGNAL_START_AUTOVAC_WORKER,          /* start an autovacuum worker */
        PMSIGNAL_START_WALRECEIVER, /* start a walreceiver */
+       PMSIGNAL_ADVANCE_STATE_MACHINE, /* advance postmaster's state machine */
 
        NUM_PMSIGNALS                           /* Must be last value of enum! */
 } PMSignalReason;