aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorPeter Eisentraut <peter_e@gmx.net>2016-07-26 12:08:49 -0400
committerPeter Eisentraut <peter_e@gmx.net>2016-09-21 12:00:00 -0400
commitebdf5bf7d1c97a926e2b0cb6523344c2643623c7 (patch)
tree164297b4f90515a4ffad9da6ca7cb98e1e974c04 /src
parentc1dc51d4844e2a37412b034c07c1c5a439ba0b9d (diff)
downloadpostgresql-ebdf5bf7d1c97a926e2b0cb6523344c2643623c7.tar.gz
postgresql-ebdf5bf7d1c97a926e2b0cb6523344c2643623c7.zip
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>
Diffstat (limited to 'src')
-rw-r--r--src/backend/access/transam/xlog.c31
1 files changed, 21 insertions, 10 deletions
diff --git a/src/backend/access/transam/xlog.c b/src/backend/access/transam/xlog.c
index 2189c22c649..c1b9a97147c 100644
--- a/src/backend/access/transam/xlog.c
+++ b/src/backend/access/transam/xlog.c
@@ -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.