diff --git a/src/backend/access/transam/commit_ts.c b/src/backend/access/transam/commit_ts.c index 834010ff71..8f09dc83ae 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 86debf4412..71fc8ffa27 100644 --- a/src/backend/access/transam/xlog.c +++ b/src/backend/access/transam/xlog.c @@ -6338,6 +6338,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. */ @@ -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 f5b39691e7..425f25870f 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);