]> granicus.if.org Git - postgresql/commitdiff
Delay updating control file to "in production"
authorPeter Eisentraut <peter_e@gmx.net>
Tue, 26 Jul 2016 16:08:49 +0000 (12:08 -0400)
committerPeter Eisentraut <peter_e@gmx.net>
Wed, 21 Sep 2016 16:00:00 +0000 (12:00 -0400)
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>

src/backend/access/transam/xlog.c

index 2189c22c649314fb3739cf8dc2da590377251321..c1b9a97147cfe04b0be04a36603fbd68a9c219bd 100644 (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.