diff options
author | Robert Haas | 2010-04-08 01:39:37 +0000 |
---|---|---|
committer | Robert Haas | 2010-04-08 01:39:37 +0000 |
commit | 1c850fa80727180d03bdb6a8c2f672eeda7fa818 (patch) | |
tree | 246905862626a014a449187a6a7fb82193e90db4 /src | |
parent | 2c0870ff7ab9bda44f39dd332836d0928afb2297 (diff) |
Make smart shutdown work in combination with Hot Standby/Streaming Replication.
At present, killing the startup process does not release any locks it holds,
so we must wait to stop the startup and walreceiver processes until all
read-only backends have exited. Without this patch, the startup and
walreceiver processes never exit, so the server gets permanently stuck in
a half-shutdown state.
Fujii Masao, with review, docs, and comment adjustments by me.
Diffstat (limited to 'src')
-rw-r--r-- | src/backend/postmaster/postmaster.c | 37 |
1 files changed, 35 insertions, 2 deletions
diff --git a/src/backend/postmaster/postmaster.c b/src/backend/postmaster/postmaster.c index 43ecfac65b4..d77ffd07438 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.604 2010/03/25 20:40:17 sriggs Exp $ + * $PostgreSQL: pgsql/src/backend/postmaster/postmaster.c,v 1.605 2010/04/08 01:39:37 rhaas Exp $ * * NOTES * @@ -278,6 +278,7 @@ typedef enum PM_RECOVERY_CONSISTENT, /* consistent recovery mode */ PM_RUN, /* normal "database is alive" state */ PM_WAIT_BACKUP, /* waiting for online backup mode to end */ + PM_WAIT_READONLY, /* waiting for read only backends to exit */ PM_WAIT_BACKENDS, /* waiting for live backends to exit */ PM_SHUTDOWN, /* waiting for bgwriter to do shutdown ckpt */ PM_SHUTDOWN_2, /* waiting for archiver and walsenders to @@ -2173,7 +2174,17 @@ pmdie(SIGNAL_ARGS) /* and the walwriter too */ if (WalWriterPID != 0) signal_child(WalWriterPID, SIGTERM); - pmState = PM_WAIT_BACKUP; + /* + * If we're in recovery, we can't kill the startup process + * right away, because at present doing so does not release + * its locks. We might want to change this in a future + * release. For the time being, the PM_WAIT_READONLY state + * indicates that we're waiting for the regular (read only) + * backends to die off; once they do, we'll kill the startup + * and walreceiver processes. + */ + pmState = (pmState == PM_RUN) ? + PM_WAIT_BACKUP : PM_WAIT_READONLY; } /* @@ -2209,6 +2220,7 @@ pmdie(SIGNAL_ARGS) } if (pmState == PM_RUN || pmState == PM_WAIT_BACKUP || + pmState == PM_WAIT_READONLY || pmState == PM_WAIT_BACKENDS || pmState == PM_RECOVERY_CONSISTENT) { @@ -2771,6 +2783,7 @@ HandleChildCrash(int pid, int exitstatus, const char *procname) pmState == PM_RECOVERY_CONSISTENT || pmState == PM_RUN || pmState == PM_WAIT_BACKUP || + pmState == PM_WAIT_READONLY || pmState == PM_SHUTDOWN) pmState = PM_WAIT_BACKENDS; } @@ -2846,6 +2859,26 @@ PostmasterStateMachine(void) pmState = PM_WAIT_BACKENDS; } + if (pmState == PM_WAIT_READONLY) + { + /* + * PM_WAIT_READONLY state ends when we have no regular backends that + * have been started during recovery. We kill the startup and + * walreceiver processes and transition to PM_WAIT_BACKENDS. Ideally, + * we might like to kill these processes first and then wait for + * backends to die off, but that doesn't work at present because + * killing the startup process doesn't release its locks. + */ + if (CountChildren(BACKEND_TYPE_NORMAL) == 0) + { + if (StartupPID != 0) + signal_child(StartupPID, SIGTERM); + if (WalReceiverPID != 0) + signal_child(WalReceiverPID, SIGTERM); + pmState = PM_WAIT_BACKENDS; + } + } + /* * If we are in a state-machine state that implies waiting for backends to * exit, see if they're all gone, and change state if so. |