summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRobert Haas2021-11-01 15:42:55 +0000
committerRobert Haas2021-11-01 16:45:31 +0000
commite5910978a754b3bfa9d2905584cc81a0cfb82cd8 (patch)
tree6029e28d5b9757361b32921c6a3a6897edbfebdb
parentf905cfd9d2ee9962038ed00435eef47b0ced144c (diff)
xlog.c: Use XLogCtl->ThisTimeLineID in various places.
Where appropriate, instead of using ThisTimeLineID, use the value from shared memory instead, to reduce dependencies on the global variable. This is only safe after recovery is complete, because prior to that, the global variable and the shared state don't match. This allows removal of some ugly logic in CreatRestartPoint() to temporarily set ThisTimeLineID for purposes of tricking RemoveOldXlogFiles and PreallocXlogFiles into doing the right thing, and then clearing it again afterwards.
-rw-r--r--src/backend/access/transam/xlog.c68
1 files changed, 39 insertions, 29 deletions
diff --git a/src/backend/access/transam/xlog.c b/src/backend/access/transam/xlog.c
index 95b64e6093..054241403c 100644
--- a/src/backend/access/transam/xlog.c
+++ b/src/backend/access/transam/xlog.c
@@ -1035,6 +1035,7 @@ XLogInsertRecord(XLogRecData *rdata,
XLogRecPtr StartPos;
XLogRecPtr EndPos;
bool prevDoPageWrites = doPageWrites;
+ TimeLineID insertTLI;
/* we assume that all of the record header is in the first chunk */
Assert(rdata->len >= SizeOfXLogRecord);
@@ -1043,6 +1044,12 @@ XLogInsertRecord(XLogRecData *rdata,
if (!XLogInsertAllowed())
elog(ERROR, "cannot make new WAL entries during recovery");
+ /*
+ * Given that we're not in recovery, ThisTimeLineID is set and can't
+ * change, so we can read it without a lock.
+ */
+ insertTLI = XLogCtl->ThisTimeLineID;
+
/*----------
*
* We have now done all the preparatory work we can without holding a
@@ -1146,7 +1153,7 @@ XLogInsertRecord(XLogRecData *rdata,
* inserted. Copy the record in the space reserved.
*/
CopyXLogRecordToWAL(rechdr->xl_tot_len, isLogSwitch, rdata,
- StartPos, EndPos, ThisTimeLineID);
+ StartPos, EndPos, insertTLI);
/*
* Unless record is flagged as not important, update LSN of last
@@ -2901,6 +2908,7 @@ XLogFlush(XLogRecPtr record)
{
XLogRecPtr WriteRqstPtr;
XLogwrtRqst WriteRqst;
+ TimeLineID insertTLI = XLogCtl->ThisTimeLineID;
/*
* During REDO, we are reading not writing WAL. Therefore, instead of
@@ -3021,7 +3029,7 @@ XLogFlush(XLogRecPtr record)
WriteRqst.Write = insertpos;
WriteRqst.Flush = insertpos;
- XLogWrite(WriteRqst, ThisTimeLineID, false);
+ XLogWrite(WriteRqst, insertTLI, false);
LWLockRelease(WALWriteLock);
/* done */
@@ -3093,11 +3101,18 @@ XLogBackgroundFlush(void)
static TimestampTz lastflush;
TimestampTz now;
int flushbytes;
+ TimeLineID insertTLI;
/* XLOG doesn't need flushing during recovery */
if (RecoveryInProgress())
return false;
+ /*
+ * Since we're not in recovery, ThisTimeLineID is set and can't change,
+ * so we can read it without a lock.
+ */
+ insertTLI = XLogCtl->ThisTimeLineID;
+
/* read LogwrtResult and update local state */
SpinLockAcquire(&XLogCtl->info_lck);
LogwrtResult = XLogCtl->LogwrtResult;
@@ -3188,7 +3203,7 @@ XLogBackgroundFlush(void)
if (WriteRqst.Write > LogwrtResult.Write ||
WriteRqst.Flush > LogwrtResult.Flush)
{
- XLogWrite(WriteRqst, ThisTimeLineID, flexible);
+ XLogWrite(WriteRqst, insertTLI, flexible);
}
LWLockRelease(WALWriteLock);
@@ -3201,7 +3216,7 @@ XLogBackgroundFlush(void)
* Great, done. To take some work off the critical path, try to initialize
* as many of the no-longer-needed WAL buffers for future use as we can.
*/
- AdvanceXLInsertBuffer(InvalidXLogRecPtr, ThisTimeLineID, true);
+ AdvanceXLInsertBuffer(InvalidXLogRecPtr, insertTLI, true);
/*
* If we determined that we need to write data, but somebody else
@@ -9196,17 +9211,16 @@ CreateCheckPoint(int flags)
/*
* An end-of-recovery checkpoint is created before anyone is allowed to
* write WAL. To allow us to write the checkpoint record, temporarily
- * enable XLogInsertAllowed. (This also ensures ThisTimeLineID is
- * initialized, which we need here and in AdvanceXLInsertBuffer.)
+ * enable XLogInsertAllowed.
*/
if (flags & CHECKPOINT_END_OF_RECOVERY)
oldXLogAllowed = LocalSetXLogInsertAllowed();
- checkPoint.ThisTimeLineID = ThisTimeLineID;
+ checkPoint.ThisTimeLineID = XLogCtl->ThisTimeLineID;
if (flags & CHECKPOINT_END_OF_RECOVERY)
checkPoint.PrevTimeLineID = XLogCtl->PrevTimeLineID;
else
- checkPoint.PrevTimeLineID = ThisTimeLineID;
+ checkPoint.PrevTimeLineID = checkPoint.ThisTimeLineID;
checkPoint.fullPageWrites = Insert->fullPageWrites;
@@ -9463,14 +9477,15 @@ CreateCheckPoint(int flags)
KeepLogSeg(recptr, &_logSegNo);
}
_logSegNo--;
- RemoveOldXlogFiles(_logSegNo, RedoRecPtr, recptr, ThisTimeLineID);
+ RemoveOldXlogFiles(_logSegNo, RedoRecPtr, recptr,
+ checkPoint.ThisTimeLineID);
/*
* Make more log segments if needed. (Do this after recycling old log
* segments, since that may supply some of the needed files.)
*/
if (!shutdown)
- PreallocXlogFiles(recptr, ThisTimeLineID);
+ PreallocXlogFiles(recptr, checkPoint.ThisTimeLineID);
/*
* Truncate pg_subtrans if possible. We can throw away all data before
@@ -9516,7 +9531,7 @@ CreateEndOfRecoveryRecord(void)
xlrec.end_time = GetCurrentTimestamp();
WALInsertLockAcquireExclusive();
- xlrec.ThisTimeLineID = ThisTimeLineID;
+ xlrec.ThisTimeLineID = XLogCtl->ThisTimeLineID;
xlrec.PrevTimeLineID = XLogCtl->PrevTimeLineID;
WALInsertLockRelease();
@@ -9535,7 +9550,7 @@ CreateEndOfRecoveryRecord(void)
LWLockAcquire(ControlFileLock, LW_EXCLUSIVE);
ControlFile->time = (pg_time_t) time(NULL);
ControlFile->minRecoveryPoint = recptr;
- ControlFile->minRecoveryPointTLI = ThisTimeLineID;
+ ControlFile->minRecoveryPointTLI = xlrec.ThisTimeLineID;
UpdateControlFile();
LWLockRelease(ControlFileLock);
@@ -9858,9 +9873,8 @@ CreateRestartPoint(int flags)
/*
* Try to recycle segments on a useful timeline. If we've been promoted
* since the beginning of this restartpoint, use the new timeline chosen
- * at end of recovery (RecoveryInProgress() sets ThisTimeLineID in that
- * case). If we're still in recovery, use the timeline we're currently
- * replaying.
+ * at end of recovery. If we're still in recovery, use the timeline we're
+ * currently replaying.
*
* There is no guarantee that the WAL segments will be useful on the
* current timeline; if recovery proceeds to a new timeline right after
@@ -9868,25 +9882,16 @@ CreateRestartPoint(int flags)
* and will go wasted until recycled on the next restartpoint. We'll live
* with that.
*/
- if (RecoveryInProgress())
- ThisTimeLineID = replayTLI;
+ if (!RecoveryInProgress())
+ replayTLI = XLogCtl->ThisTimeLineID;
- RemoveOldXlogFiles(_logSegNo, RedoRecPtr, endptr, ThisTimeLineID);
+ RemoveOldXlogFiles(_logSegNo, RedoRecPtr, endptr, replayTLI);
/*
* Make more log segments if needed. (Do this after recycling old log
* segments, since that may supply some of the needed files.)
*/
- PreallocXlogFiles(endptr, ThisTimeLineID);
-
- /*
- * ThisTimeLineID is normally not set when we're still in recovery.
- * However, recycling/preallocating segments above needed ThisTimeLineID
- * to determine which timeline to install the segments on. Reset it now,
- * to restore the normal state of affairs for debugging purposes.
- */
- if (RecoveryInProgress())
- ThisTimeLineID = 0;
+ PreallocXlogFiles(endptr, replayTLI);
/*
* Truncate pg_subtrans if possible. We can throw away all data before
@@ -11792,7 +11797,12 @@ do_pg_stop_backup(char *labelfile, bool waitforarchive, TimeLineID *stoptli_p)
XLogBeginInsert();
XLogRegisterData((char *) (&startpoint), sizeof(startpoint));
stoppoint = XLogInsert(RM_XLOG_ID, XLOG_BACKUP_END);
- stoptli = ThisTimeLineID;
+
+ /*
+ * Given that we're not in recovery, ThisTimeLineID is set and can't
+ * change, so we can read it without a lock.
+ */
+ stoptli = XLogCtl->ThisTimeLineID;
/*
* Force a switch to a new xlog segment file, so that the backup is