]> granicus.if.org Git - postgresql/commitdiff
Rework activation of commit timestamps during recovery
authorMichael Paquier <michael@paquier.xyz>
Wed, 26 Sep 2018 01:29:49 +0000 (10:29 +0900)
committerMichael Paquier <michael@paquier.xyz>
Wed, 26 Sep 2018 01:29:49 +0000 (10:29 +0900)
The activation and deactivation of commit timestamp tracking has not
been handled consistently for a primary or standbys at recovery.  The
facility can be activated at three different moments of recovery:
- The beginning, where a primary would use the GUC value for the
decision-making, and where a standby relies on the contents of the
control file.
- When replaying a XLOG_PARAMETER_CHANGE record at redo.
- The end, where both primary and standby rely on the GUC value.

Using the GUC value for a primary at the beginning of recovery causes
problems with commit timestamp access when doing crash recovery.
Particularly, when replaying transaction commits, it could be possible
that an attempt to read commit timestamps is done for a transaction
which committed at a moment when track_commit_timestamp was disabled.

A test case is added to reproduce the failure.  The test works down to
v11 as it takes advantage of transaction commits within procedures.

Reported-by: Hailong Li
Author: Masahiko Sawasa, Michael Paquier
Reviewed-by: Kyotaro Horiguchi
Discussion: https://postgr.es/m/11224478-a782-203b-1f17-e4797b39bdf0@qunar.com
Backpatch-through: 9.5, where commit timestamps have been introduced.

src/backend/access/transam/commit_ts.c
src/backend/access/transam/xlog.c

index 11424c2257250c3ae72ad0a818df7f8816b4b568..e460efd8fb08462ee67f560d32c3ca1fd8632ebd 100644 (file)
@@ -572,10 +572,9 @@ CompleteCommitTsInitialization(void)
         * any leftover data.
         *
         * Conversely, we activate the module if the feature is enabled.  This is
-        * not necessary in a master system because we already did it earlier, but
-        * if we're in a standby server that got promoted which had the feature
-        * enabled and was following a master that had the feature disabled, this
-        * is where we turn it on locally.
+        * necessary for primary and standby as the activation depends on the
+        * control file contents at the beginning of recovery or when a
+        * XLOG_PARAMETER_CHANGE is replayed.
         */
        if (!track_commit_timestamp)
                DeactivateCommitTs();
@@ -585,7 +584,7 @@ CompleteCommitTsInitialization(void)
 
 /*
  * Activate or deactivate CommitTs' upon reception of a XLOG_PARAMETER_CHANGE
- * XLog record in a standby.
+ * XLog record during recovery.
  */
 void
 CommitTsParameterChange(bool newvalue, bool oldvalue)
index 2ac51856460ab017c282c12887a77d46e716b6b7..969d1c6c461ab0c63db4ee875b5d691a7941fefa 100644 (file)
@@ -6467,11 +6467,12 @@ StartupXLOG(void)
        StartupMultiXact();
 
        /*
-        * Ditto commit timestamps.  In a standby, we do it if setting is enabled
-        * in ControlFile; in a master we base the decision on the GUC itself.
+        * Ditto for commit timestamps.  Activate the facility if the setting is
+        * enabled in the control file, as there should be no tracking of commit
+        * timestamps done when the setting was disabled.  This facility can be
+        * started or stopped when replaying a XLOG_PARAMETER_CHANGE record.
         */
-       if (ArchiveRecoveryRequested ?
-               ControlFile->track_commit_timestamp : track_commit_timestamp)
+       if (ControlFile->track_commit_timestamp)
                StartupCommitTs();
 
        /*