Delay updating control file to "in production"

Move the updating of the control file to "in production" status until
the point where WAL writes are allowed.  Before, there could be a
significant gap between the control file update and write transactions
actually being allowed.  This makes it more reliable to use the control
status to verify the end of a promotion.

From: Michael Paquier <michael.paquier@gmail.com>
This commit is contained in:
Peter Eisentraut 2016-07-26 12:08:49 -04:00
parent c1dc51d484
commit ebdf5bf7d1
1 changed files with 21 additions and 10 deletions

View File

@ -7431,12 +7431,6 @@ StartupXLOG(void)
*/
InRecovery = false;
LWLockAcquire(ControlFileLock, LW_EXCLUSIVE);
ControlFile->state = DB_IN_PRODUCTION;
ControlFile->time = (pg_time_t) time(NULL);
UpdateControlFile();
LWLockRelease(ControlFileLock);
/* start the archive_timeout timer running */
XLogCtl->lastSegSwitchTime = (pg_time_t) time(NULL);
@ -7494,15 +7488,32 @@ StartupXLOG(void)
CompleteCommitTsInitialization();
/*
* All done. Allow backends to write WAL. (Although the bool flag is
* probably atomic in itself, we use the info_lck here to ensure that
* there are no race conditions concerning visibility of other recent
* updates to shared memory.)
* All done with end-of-recovery actions.
*
* Now allow backends to write WAL and update the control file status in
* consequence. The boolean flag allowing backends to write WAL is
* updated while holding ControlFileLock to prevent other backends to look
* at an inconsistent state of the control file in shared memory. There
* is still a small window during which backends can write WAL and the
* control file is still referring to a system not in DB_IN_PRODUCTION
* state while looking at the on-disk control file.
*
* Also, although the boolean flag to allow WAL is probably atomic in
* itself, we use the info_lck here to ensure that there are no race
* conditions concerning visibility of other recent updates to shared
* memory.
*/
LWLockAcquire(ControlFileLock, LW_EXCLUSIVE);
ControlFile->state = DB_IN_PRODUCTION;
ControlFile->time = (pg_time_t) time(NULL);
SpinLockAcquire(&XLogCtl->info_lck);
XLogCtl->SharedRecoveryInProgress = false;
SpinLockRelease(&XLogCtl->info_lck);
UpdateControlFile();
LWLockRelease(ControlFileLock);
/*
* If there were cascading standby servers connected to us, nudge any wal
* sender processes to notice that we've been promoted.