diff --git a/src/backend/access/transam/commit_ts.c b/src/backend/access/transam/commit_ts.c index ca074da..fcfccf8 100644 --- a/src/backend/access/transam/commit_ts.c +++ b/src/backend/access/transam/commit_ts.c @@ -557,6 +557,12 @@ StartupCommitTs(void) TransactionId xid = ShmemVariableCache->nextXid; int pageno = TransactionIdToCTsPage(xid); + if (track_commit_timestamp) + { + ActivateCommitTs(); + return; + } + LWLockAcquire(CommitTsControlLock, LW_EXCLUSIVE); /* @@ -571,14 +577,25 @@ StartupCommitTs(void) * This must be called ONCE during postmaster or standalone-backend startup, * when commit timestamp is enabled. Must be called after recovery has * finished. + */ +void +CompleteCommitTsInitialization(void) +{ + if (!track_commit_timestamp) + DeactivateCommitTs(true); +} + +/* + * This must be called when track_commit_timestamp is turned on. + * Note that this only happens during postmaster or standalone-backend startup + * or during WAL replay. * * This is in charge of creating the currently active segment, if it's not * already there. The reason for this is that the server might have been * running with this module disabled for a while and thus might have skipped * the normal creation point. */ -void -CompleteCommitTsInitialization(void) +void ActivateCommitTs(void) { TransactionId xid = ShmemVariableCache->nextXid; int pageno = TransactionIdToCTsPage(xid); @@ -591,22 +608,6 @@ CompleteCommitTsInitialization(void) LWLockRelease(CommitTsControlLock); /* - * If this module is not currently enabled, make sure we don't hand back - * possibly-invalid data; also remove segments of old data. - */ - if (!track_commit_timestamp) - { - LWLockAcquire(CommitTsLock, LW_EXCLUSIVE); - ShmemVariableCache->oldestCommitTs = InvalidTransactionId; - ShmemVariableCache->newestCommitTs = InvalidTransactionId; - LWLockRelease(CommitTsLock); - - TruncateCommitTs(ReadNewTransactionId()); - - return; - } - - /* * If CommitTs is enabled, but it wasn't in the previous server run, we * need to set the oldest and newest values to the next Xid; that way, we * will not try to read data that might not have been set. @@ -641,6 +642,35 @@ CompleteCommitTsInitialization(void) } /* + * This must be called when track_commit_timestamp is turned off. + * Note that this only happens during postmaster or standalone-backend startup + * or during WAL replay. + * + * Resets CommitTs into invalid state to make sure we don't hand back + * possibly-invalid data; also removes segments of old data. + */ +void +DeactivateCommitTs(bool do_wal) +{ + TransactionId xid = ShmemVariableCache->nextXid; + int pageno = TransactionIdToCTsPage(xid); + + /* + * Re-Initialize our idea of the latest page number. + */ + LWLockAcquire(CommitTsControlLock, LW_EXCLUSIVE); + CommitTsCtl->shared->latest_page_number = pageno; + LWLockRelease(CommitTsControlLock); + + LWLockAcquire(CommitTsLock, LW_EXCLUSIVE); + ShmemVariableCache->oldestCommitTs = InvalidTransactionId; + ShmemVariableCache->newestCommitTs = InvalidTransactionId; + LWLockRelease(CommitTsLock); + + TruncateCommitTs(ReadNewTransactionId(), do_wal); +} + +/* * This must be called ONCE during postmaster or standalone-backend shutdown */ void @@ -705,7 +735,7 @@ ExtendCommitTs(TransactionId newestXact) * Note that we don't need to flush XLOG here. */ void -TruncateCommitTs(TransactionId oldestXact) +TruncateCommitTs(TransactionId oldestXact, bool do_wal) { int cutoffPage; @@ -721,7 +751,8 @@ TruncateCommitTs(TransactionId oldestXact) return; /* nothing to remove */ /* Write XLOG record */ - WriteTruncateXlogRec(cutoffPage); + if (do_wal) + WriteTruncateXlogRec(cutoffPage); /* Now we can remove the old CommitTs segment(s) */ SimpleLruTruncate(CommitTsCtl, cutoffPage); diff --git a/src/backend/access/transam/xlog.c b/src/backend/access/transam/xlog.c index 5cc7e47..7ba7436 100644 --- a/src/backend/access/transam/xlog.c +++ b/src/backend/access/transam/xlog.c @@ -5587,6 +5587,16 @@ do { \ minValue))); \ } while(0) +#define RecoveryRequiresBoolParameter(param_name, currValue, masterValue) \ +do { \ + if (!(currValue) && (masterValue)) \ + ereport(ERROR, \ + (errcode(ERRCODE_INVALID_PARAMETER_VALUE), \ + errmsg("hot standby is not possible because " \ + "%s is disabled but master server has it enabled ", \ + param_name))); \ +} while(0) + /* * Check to see if required parameters are set high enough on this server * for various aspects of recovery operation. @@ -5629,6 +5639,9 @@ CheckRequiredParameterValues(void) RecoveryRequiresIntParameter("max_locks_per_transaction", max_locks_per_xact, ControlFile->max_locks_per_xact); + RecoveryRequiresBoolParameter("track_commit_timestamp", + track_commit_timestamp, + ControlFile->track_commit_timestamp); } } @@ -8968,7 +8981,6 @@ xlog_redo(XLogReaderState *record) ControlFile->max_locks_per_xact = xlrec.max_locks_per_xact; ControlFile->wal_level = xlrec.wal_level; ControlFile->wal_log_hints = wal_log_hints; - ControlFile->track_commit_timestamp = track_commit_timestamp; /* * Update minRecoveryPoint to ensure that if recovery is aborted, we @@ -8986,6 +8998,20 @@ xlog_redo(XLogReaderState *record) ControlFile->minRecoveryPointTLI = ThisTimeLineID; } + /* + * Update the commit timestamp tracking. If there was a change + * it needs to be activated or deactivated accordingly. + */ + if (track_commit_timestamp != xlrec.track_commit_timestamp) + { + track_commit_timestamp = xlrec.track_commit_timestamp; + ControlFile->track_commit_timestamp = track_commit_timestamp; + if (track_commit_timestamp) + ActivateCommitTs(); + else + DeactivateCommitTs(false); + } + UpdateControlFile(); LWLockRelease(ControlFileLock); diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c index e32e039..ced78ff 100644 --- a/src/backend/commands/vacuum.c +++ b/src/backend/commands/vacuum.c @@ -1077,7 +1077,7 @@ vac_truncate_clog(TransactionId frozenXID, * checkpoint. */ TruncateCLOG(frozenXID); - TruncateCommitTs(frozenXID); + TruncateCommitTs(frozenXID, true); /* * Update the wrap limit for GetNewTransactionId and creation of new diff --git a/src/include/access/commit_ts.h b/src/include/access/commit_ts.h index 903c82c..70ca968 100644 --- a/src/include/access/commit_ts.h +++ b/src/include/access/commit_ts.h @@ -39,11 +39,13 @@ extern Size CommitTsShmemSize(void); extern void CommitTsShmemInit(void); extern void BootStrapCommitTs(void); extern void StartupCommitTs(void); +extern void ActivateCommitTs(void); +extern void DeactivateCommitTs(bool do_wal); extern void CompleteCommitTsInitialization(void); extern void ShutdownCommitTs(void); extern void CheckPointCommitTs(void); extern void ExtendCommitTs(TransactionId newestXact); -extern void TruncateCommitTs(TransactionId oldestXact); +extern void TruncateCommitTs(TransactionId oldestXact, bool do_wal); extern void SetCommitTsLimit(TransactionId oldestXact, TransactionId newestXact); extern void AdvanceOldestCommitTs(TransactionId oldestXact);