diff options
author | Tom Lane <tgl@sss.pgh.pa.us> | 2008-04-26 22:47:40 +0000 |
---|---|---|
committer | Tom Lane <tgl@sss.pgh.pa.us> | 2008-04-26 22:47:40 +0000 |
commit | ea0382e3706ab25935c733fd452d828832e4675f (patch) | |
tree | 1bf47e84c58c9e337934b1d3bddcb707dfb7cb06 /src | |
parent | b6e2fab9788ab7cd7ca18903787dff2398441167 (diff) | |
download | postgresql-ea0382e3706ab25935c733fd452d828832e4675f.tar.gz postgresql-ea0382e3706ab25935c733fd452d828832e4675f.zip |
Code review for recent patch to terminate online backup during shutdown:
do CancelBackup at a sane place, fix some oversights in the state transitions,
allow only superusers to connect while we are waiting for backup mode to end.
Diffstat (limited to 'src')
-rw-r--r-- | src/backend/postmaster/postmaster.c | 53 | ||||
-rw-r--r-- | src/backend/utils/init/postinit.c | 13 | ||||
-rw-r--r-- | src/include/libpq/libpq-be.h | 5 |
3 files changed, 44 insertions, 27 deletions
diff --git a/src/backend/postmaster/postmaster.c b/src/backend/postmaster/postmaster.c index f3bcdd968c7..54e9173f6c6 100644 --- a/src/backend/postmaster/postmaster.c +++ b/src/backend/postmaster/postmaster.c @@ -37,7 +37,7 @@ * * * IDENTIFICATION - * $PostgreSQL: pgsql/src/backend/postmaster/postmaster.c,v 1.555 2008/04/23 13:44:59 mha Exp $ + * $PostgreSQL: pgsql/src/backend/postmaster/postmaster.c,v 1.556 2008/04/26 22:47:40 tgl Exp $ * * NOTES * @@ -230,6 +230,7 @@ static bool FatalError = false; /* T if recovering from backend crash */ * crash recovery (which is rather like shutdown followed by startup). * * Normal child backends can only be launched when we are in PM_RUN state. + * (We also allow it in PM_WAIT_BACKUP state, but only for superusers.) * In other states we handle connection requests by launching "dead_end" * child processes, which will simply send the client an error message and * 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 */ * will not be very long). * * Notice that this state variable does not distinguish *why* we entered - * PM_WAIT_BACKENDS or later states --- Shutdown and FatalError must be - * consulted to find that out. FatalError is never true in PM_RUN state, nor - * in PM_SHUTDOWN states (because we don't enter those states when trying to + * states later than PM_RUN --- Shutdown and FatalError must be consulted + * to find that out. FatalError is never true in PM_RUN state, nor in + * PM_SHUTDOWN states (because we don't enter those states when trying to * recover from a crash). It can be true in PM_STARTUP state, because we * don't clear it until we've successfully recovered. */ @@ -1650,6 +1651,9 @@ retry1: (errcode(ERRCODE_TOO_MANY_CONNECTIONS), errmsg("sorry, too many clients already"))); break; + case CAC_WAITBACKUP: + /* OK for now, will check in InitPostgres */ + break; case CAC_OK: break; } @@ -1727,11 +1731,15 @@ canAcceptConnections(void) { /* * Can't start backends when in startup/shutdown/recovery state. - * In state PM_WAIT_BACKUP we must allow connections so that - * a superuser can end online backup mode. + * + * In state PM_WAIT_BACKUP only superusers can connect (this must be + * allowed so that a superuser can end online backup mode); we return + * CAC_WAITBACKUP code to indicate that this must be checked later. */ - if ((pmState != PM_RUN) && (pmState != PM_WAIT_BACKUP)) + if (pmState != PM_RUN) { + if (pmState == PM_WAIT_BACKUP) + return CAC_WAITBACKUP; /* allow superusers only */ if (Shutdown > NoShutdown) return CAC_SHUTDOWN; /* shutdown is pending */ if (pmState == PM_STARTUP && !FatalError) @@ -1997,7 +2005,7 @@ pmdie(SIGNAL_ARGS) if (StartupPID != 0) signal_child(StartupPID, SIGTERM); - if (pmState == PM_RUN) + if (pmState == PM_RUN || pmState == PM_WAIT_BACKUP) { ereport(LOG, (errmsg("aborting any active transactions"))); @@ -2017,13 +2025,6 @@ pmdie(SIGNAL_ARGS) * PostmasterStateMachine will take the next step. */ PostmasterStateMachine(); - - /* - * Terminate backup mode to avoid recovery after a - * clean fast shutdown. - */ - CancelBackup(); - break; case SIGQUIT: @@ -2499,7 +2500,9 @@ HandleChildCrash(int pid, int exitstatus, const char *procname) FatalError = true; /* We now transit into a state of waiting for children to die */ - if (pmState == PM_RUN || pmState == PM_SHUTDOWN) + if (pmState == PM_RUN || + pmState == PM_WAIT_BACKUP || + pmState == PM_SHUTDOWN) pmState = PM_WAIT_BACKENDS; } @@ -2568,15 +2571,10 @@ PostmasterStateMachine(void) if (pmState == PM_WAIT_BACKUP) { /* - * PM_WAIT_BACKUP state ends when online backup mode is no longer - * active. In this state canAcceptConnections() will still allow - * client connections, which is necessary because a superuser - * has to call pg_stop_backup() to end online backup mode. + * PM_WAIT_BACKUP state ends when online backup mode is not active. */ if (!BackupInProgress()) - { pmState = PM_WAIT_BACKENDS; - } } /* @@ -2699,6 +2697,12 @@ PostmasterStateMachine(void) } else { + /* + * Terminate backup mode to avoid recovery after a + * clean fast shutdown. + */ + CancelBackup(); + /* Normal exit from the postmaster is here */ ExitPostmaster(0); } @@ -2819,7 +2823,7 @@ BackendStartup(Port *port) return STATUS_ERROR; } - /* Pass down canAcceptConnections state (kluge for EXEC_BACKEND case) */ + /* Pass down canAcceptConnections state */ port->canAcceptConnections = canAcceptConnections(); #ifdef EXEC_BACKEND @@ -2880,7 +2884,8 @@ BackendStartup(Port *port) bn->pid = pid; bn->cancel_key = MyCancelKey; bn->is_autovacuum = false; - bn->dead_end = (port->canAcceptConnections != CAC_OK); + bn->dead_end = (port->canAcceptConnections != CAC_OK && + port->canAcceptConnections != CAC_WAITBACKUP); DLAddHead(BackendList, DLNewElem(bn)); #ifdef EXEC_BACKEND if (!bn->dead_end) diff --git a/src/backend/utils/init/postinit.c b/src/backend/utils/init/postinit.c index 6c29ea19174..695db95c726 100644 --- a/src/backend/utils/init/postinit.c +++ b/src/backend/utils/init/postinit.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $PostgreSQL: pgsql/src/backend/utils/init/postinit.c,v 1.182 2008/03/26 21:10:39 alvherre Exp $ + * $PostgreSQL: pgsql/src/backend/utils/init/postinit.c,v 1.183 2008/04/26 22:47:40 tgl Exp $ * * *------------------------------------------------------------------------- @@ -26,6 +26,7 @@ #include "catalog/pg_database.h" #include "catalog/pg_tablespace.h" #include "libpq/hba.h" +#include "libpq/libpq-be.h" #include "mb/pg_wchar.h" #include "miscadmin.h" #include "pgstat.h" @@ -578,6 +579,16 @@ InitPostgres(const char *in_dbname, Oid dboid, const char *username, CheckMyDatabase(dbname, am_superuser); /* + * If we're trying to shut down, only superusers can connect. + */ + if (!am_superuser && + MyProcPort != NULL && + MyProcPort->canAcceptConnections == CAC_WAITBACKUP) + ereport(FATAL, + (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE), + errmsg("must be superuser to connect during database shutdown"))); + + /* * Check a normal user hasn't connected to a superuser reserved slot. */ if (!am_superuser && diff --git a/src/include/libpq/libpq-be.h b/src/include/libpq/libpq-be.h index da05b69cbdb..6927da2fd08 100644 --- a/src/include/libpq/libpq-be.h +++ b/src/include/libpq/libpq-be.h @@ -11,7 +11,7 @@ * Portions Copyright (c) 1996-2008, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * - * $PostgreSQL: pgsql/src/include/libpq/libpq-be.h,v 1.65 2008/01/01 19:45:58 momjian Exp $ + * $PostgreSQL: pgsql/src/include/libpq/libpq-be.h,v 1.66 2008/04/26 22:47:40 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -69,7 +69,8 @@ typedef struct typedef enum CAC_state { - CAC_OK, CAC_STARTUP, CAC_SHUTDOWN, CAC_RECOVERY, CAC_TOOMANY + CAC_OK, CAC_STARTUP, CAC_SHUTDOWN, CAC_RECOVERY, CAC_TOOMANY, + CAC_WAITBACKUP } CAC_state; |