3737 *
3838 *
3939 * IDENTIFICATION
40- * $PostgreSQL: pgsql/src/backend/postmaster/postmaster.c,v 1.555 2008/04/23 13:44:59 mha Exp $
40+ * $PostgreSQL: pgsql/src/backend/postmaster/postmaster.c,v 1.556 2008/04/26 22:47:40 tgl Exp $
4141 *
4242 * NOTES
4343 *
@@ -230,6 +230,7 @@ static bool FatalError = false; /* T if recovering from backend crash */
230230 * crash recovery (which is rather like shutdown followed by startup).
231231 *
232232 * Normal child backends can only be launched when we are in PM_RUN state.
233+ * (We also allow it in PM_WAIT_BACKUP state, but only for superusers.)
233234 * In other states we handle connection requests by launching "dead_end"
234235 * child processes, which will simply send the client an error message and
235236 * quit. (We track these in the BackendList so that we can know when they
@@ -242,9 +243,9 @@ static bool FatalError = false; /* T if recovering from backend crash */
242243 * will not be very long).
243244 *
244245 * Notice that this state variable does not distinguish *why* we entered
245- *PM_WAIT_BACKENDS or laterstates --- Shutdown and FatalError must be
246- *consulted to find that out. FatalError is never true in PM_RUN state, nor
247- *in PM_SHUTDOWN states (because we don't enter those states when trying to
246+ *states laterthan PM_RUN --- Shutdown and FatalError must be consulted
247+ * to find that out. FatalError is never true in PM_RUN state, nor in
248+ * PM_SHUTDOWN states (because we don't enter those states when trying to
248249 * recover from a crash). It can be true in PM_STARTUP state, because we
249250 * don't clear it until we've successfully recovered.
250251 */
@@ -1650,6 +1651,9 @@ ProcessStartupPacket(Port *port, bool SSLdone)
16501651(errcode (ERRCODE_TOO_MANY_CONNECTIONS ),
16511652errmsg ("sorry, too many clients already" )));
16521653break ;
1654+ case CAC_WAITBACKUP :
1655+ /* OK for now, will check in InitPostgres */
1656+ break ;
16531657case CAC_OK :
16541658break ;
16551659}
@@ -1727,11 +1731,15 @@ canAcceptConnections(void)
17271731{
17281732/*
17291733 * Can't start backends when in startup/shutdown/recovery state.
1730- * In state PM_WAIT_BACKUP we must allow connections so that
1731- * a superuser can end online backup mode.
1734+ *
1735+ * In state PM_WAIT_BACKUP only superusers can connect (this must be
1736+ * allowed so that a superuser can end online backup mode); we return
1737+ * CAC_WAITBACKUP code to indicate that this must be checked later.
17321738 */
1733- if (( pmState != PM_RUN ) && ( pmState != PM_WAIT_BACKUP ) )
1739+ if (pmState != PM_RUN )
17341740{
1741+ if (pmState == PM_WAIT_BACKUP )
1742+ return CAC_WAITBACKUP ;/* allow superusers only */
17351743if (Shutdown > NoShutdown )
17361744return CAC_SHUTDOWN ;/* shutdown is pending */
17371745if (pmState == PM_STARTUP && !FatalError )
@@ -1997,7 +2005,7 @@ pmdie(SIGNAL_ARGS)
19972005
19982006if (StartupPID != 0 )
19992007signal_child (StartupPID ,SIGTERM );
2000- if (pmState == PM_RUN )
2008+ if (pmState == PM_RUN || pmState == PM_WAIT_BACKUP )
20012009{
20022010ereport (LOG ,
20032011(errmsg ("aborting any active transactions" )));
@@ -2017,13 +2025,6 @@ pmdie(SIGNAL_ARGS)
20172025 * PostmasterStateMachine will take the next step.
20182026 */
20192027PostmasterStateMachine ();
2020-
2021- /*
2022- * Terminate backup mode to avoid recovery after a
2023- * clean fast shutdown.
2024- */
2025- CancelBackup ();
2026-
20272028break ;
20282029
20292030case SIGQUIT :
@@ -2499,7 +2500,9 @@ HandleChildCrash(int pid, int exitstatus, const char *procname)
24992500
25002501FatalError = true;
25012502/* We now transit into a state of waiting for children to die */
2502- if (pmState == PM_RUN || pmState == PM_SHUTDOWN )
2503+ if (pmState == PM_RUN ||
2504+ pmState == PM_WAIT_BACKUP ||
2505+ pmState == PM_SHUTDOWN )
25032506pmState = PM_WAIT_BACKENDS ;
25042507}
25052508
@@ -2568,15 +2571,10 @@ PostmasterStateMachine(void)
25682571if (pmState == PM_WAIT_BACKUP )
25692572{
25702573/*
2571- * PM_WAIT_BACKUP state ends when online backup mode is no longer
2572- * active. In this state canAcceptConnections() will still allow
2573- * client connections, which is necessary because a superuser
2574- * has to call pg_stop_backup() to end online backup mode.
2574+ * PM_WAIT_BACKUP state ends when online backup mode is not active.
25752575 */
25762576if (!BackupInProgress ())
2577- {
25782577pmState = PM_WAIT_BACKENDS ;
2579- }
25802578}
25812579
25822580/*
@@ -2699,6 +2697,12 @@ PostmasterStateMachine(void)
26992697}
27002698else
27012699{
2700+ /*
2701+ * Terminate backup mode to avoid recovery after a
2702+ * clean fast shutdown.
2703+ */
2704+ CancelBackup ();
2705+
27022706/* Normal exit from the postmaster is here */
27032707ExitPostmaster (0 );
27042708}
@@ -2819,7 +2823,7 @@ BackendStartup(Port *port)
28192823return STATUS_ERROR ;
28202824}
28212825
2822- /* Pass down canAcceptConnections state(kluge for EXEC_BACKEND case) */
2826+ /* Pass down canAcceptConnections state */
28232827port -> canAcceptConnections = canAcceptConnections ();
28242828
28252829#ifdef EXEC_BACKEND
@@ -2880,7 +2884,8 @@ BackendStartup(Port *port)
28802884bn -> pid = pid ;
28812885bn -> cancel_key = MyCancelKey ;
28822886bn -> is_autovacuum = false;
2883- bn -> dead_end = (port -> canAcceptConnections != CAC_OK );
2887+ bn -> dead_end = (port -> canAcceptConnections != CAC_OK &&
2888+ port -> canAcceptConnections != CAC_WAITBACKUP );
28842889DLAddHead (BackendList ,DLNewElem (bn ));
28852890#ifdef EXEC_BACKEND
28862891if (!bn -> dead_end )