aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/backend/access/transam/commit_ts.c39
-rw-r--r--src/backend/access/transam/xlog.c22
-rw-r--r--src/include/access/commit_ts.h2
3 files changed, 40 insertions, 23 deletions
diff --git a/src/backend/access/transam/commit_ts.c b/src/backend/access/transam/commit_ts.c
index 834010ff716..8f09dc83ae7 100644
--- a/src/backend/access/transam/commit_ts.c
+++ b/src/backend/access/transam/commit_ts.c
@@ -545,19 +545,11 @@ ZeroCommitTsPage(int pageno, bool writeXlog)
/*
* This must be called ONCE during postmaster or standalone-backend startup,
* after StartupXLOG has initialized ShmemVariableCache->nextXid.
- *
- * Caller may choose to enable the feature even when it is turned off in the
- * configuration.
*/
void
-StartupCommitTs(bool enabled)
+StartupCommitTs(void)
{
- /*
- * If the module is not enabled, there's nothing to do here. The module
- * could still be activated from elsewhere.
- */
- if (enabled)
- ActivateCommitTs();
+ ActivateCommitTs();
}
/*
@@ -570,9 +562,17 @@ CompleteCommitTsInitialization(void)
/*
* If the feature is not enabled, turn it off for good. This also removes
* 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.
*/
if (!track_commit_timestamp)
DeactivateCommitTs();
+ else
+ ActivateCommitTs();
}
/*
@@ -591,6 +591,9 @@ CommitTsParameterChange(bool newvalue, bool oldvalue)
*
* If the module is disabled in the master, disable it here too, unless
* the module is enabled locally.
+ *
+ * Note this only runs in the recovery process, so an unlocked read is
+ * fine.
*/
if (newvalue)
{
@@ -620,8 +623,20 @@ CommitTsParameterChange(bool newvalue, bool oldvalue)
static void
ActivateCommitTs(void)
{
- TransactionId xid = ShmemVariableCache->nextXid;
- int pageno = TransactionIdToCTsPage(xid);
+ TransactionId xid;
+ int pageno;
+
+ /* If we've done this already, there's nothing to do */
+ LWLockAcquire(CommitTsLock, LW_EXCLUSIVE);
+ if (commitTsShared->commitTsActive)
+ {
+ LWLockRelease(CommitTsLock);
+ return;
+ }
+ LWLockRelease(CommitTsLock);
+
+ xid = ShmemVariableCache->nextXid;
+ pageno = TransactionIdToCTsPage(xid);
/*
* Re-Initialize our idea of the latest page number.
diff --git a/src/backend/access/transam/xlog.c b/src/backend/access/transam/xlog.c
index 86debf44123..71fc8ffa272 100644
--- a/src/backend/access/transam/xlog.c
+++ b/src/backend/access/transam/xlog.c
@@ -6339,6 +6339,14 @@ 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.
+ */
+ if (ArchiveRecoveryRequested ?
+ ControlFile->track_commit_timestamp : track_commit_timestamp)
+ StartupCommitTs();
+
+ /*
* Recover knowledge about replay progress of known replication partners.
*/
StartupReplicationOrigin();
@@ -6565,16 +6573,11 @@ StartupXLOG(void)
ProcArrayInitRecovery(ShmemVariableCache->nextXid);
/*
- * Startup commit log, commit timestamp and subtrans only.
- * MultiXact has already been started up and other SLRUs are not
+ * Startup commit log and subtrans only. MultiXact and commit
+ * timestamp have already been started up and other SLRUs are not
* maintained during recovery and need not be started yet.
- *
- * For commit timestamps, we do this based on the control file
- * info: in a standby, we want to drive it off the state of the
- * master, not local configuration.
*/
StartupCLOG();
- StartupCommitTs(ControlFile->track_commit_timestamp);
StartupSUBTRANS(oldestActiveXID);
/*
@@ -7337,13 +7340,12 @@ StartupXLOG(void)
LWLockRelease(ProcArrayLock);
/*
- * Start up the commit log, commit timestamp and subtrans, if not already
- * done for hot standby.
+ * Start up the commit log and subtrans, if not already done for hot
+ * standby. (commit timestamps are started below, if necessary.)
*/
if (standbyState == STANDBY_DISABLED)
{
StartupCLOG();
- StartupCommitTs(track_commit_timestamp);
StartupSUBTRANS(oldestActiveXID);
}
diff --git a/src/include/access/commit_ts.h b/src/include/access/commit_ts.h
index f5b39691e71..425f25870fd 100644
--- a/src/include/access/commit_ts.h
+++ b/src/include/access/commit_ts.h
@@ -34,7 +34,7 @@ extern Size CommitTsShmemBuffers(void);
extern Size CommitTsShmemSize(void);
extern void CommitTsShmemInit(void);
extern void BootStrapCommitTs(void);
-extern void StartupCommitTs(bool enabled);
+extern void StartupCommitTs(void);
extern void CommitTsParameterChange(bool xlrecvalue, bool pgcontrolvalue);
extern void CompleteCommitTsInitialization(void);
extern void ShutdownCommitTs(void);