/*
* 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();
}
/*
/*
* 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();
}
/*
*
* 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)
{
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.
*/
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.
*/
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);
/*
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);
}
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);