From: Robert Haas Date: Wed, 27 Oct 2021 16:56:34 +0000 (-0400) Subject: Keep shared-memory copy of ThisTimeLineID in sync at all times. X-Git-Url: http://git.postgresql.org/gitweb/static/developers.postgresql.org?a=commitdiff_plain;h=f06ced35cd9efd54056516f03b3680976dfa74bd;p=users%2Frhaas%2Fpostgres.git Keep shared-memory copy of ThisTimeLineID in sync at all times. Previously, the startup process set the global variable ThisTimeLineID for each record replayed, while leaving the corresponding shared-memory variable uninitialized. Now, XLogCtl->ThisTimeLineID is always the same as ThisTimeLineID, and XLogCtl->PrevTimeLineID is also the same unless a promotion has occurred since server startup. --- diff --git a/src/backend/access/transam/xlog.c b/src/backend/access/transam/xlog.c index f547efd294..c94ddd3756 100644 --- a/src/backend/access/transam/xlog.c +++ b/src/backend/access/transam/xlog.c @@ -634,9 +634,19 @@ typedef struct XLogCtlData /* * Shared copy of ThisTimeLineID. Does not change after end-of-recovery. - * If we created a new timeline when the system was started up, - * PrevTimeLineID is the old timeline's ID that we forked off from. - * Otherwise it's equal to ThisTimeLineID. + * + * During recovery, ThisTimeLineID and PrevTimeLineID both hold the + * timeline of the last record we replayed; they will always be equal. + * + * At the end of recovery, if we create a new time line, ThisTimeLineID + * will be set to the newly-created timeline, and PrevTimeLineID will be + * the timeline from which it branched off. If we do not create a new + * timeline, ThisTimeLineID will be equal to PrevTimeLineID, and both + * will be equal either to the timeline of the last WAL record we replayed, + * or the timeline in the checkpoint from which we started up. + * + * At any point when it's possible to insert new WAL, ThisTimeLineID is + * always the timeline that should be used to do that. */ TimeLineID ThisTimeLineID; TimeLineID PrevTimeLineID; @@ -6627,7 +6637,6 @@ StartupXLOG(void) checkPointLoc, EndOfLog; TimeLineID EndOfLogTLI; - TimeLineID PrevTimeLineID; XLogRecord *record; TransactionId oldestActiveXID; bool backupEndRequired = false; @@ -7140,9 +7149,11 @@ StartupXLOG(void) /* * We must replay WAL entries using the same TimeLineID they were created * under, so temporarily adopt the TLI indicated by the checkpoint (see - * also xlog_redo()). + * also xlog_redo()). Update shared memory, too. */ ThisTimeLineID = checkPoint.ThisTimeLineID; + XLogCtl->ThisTimeLineID = ThisTimeLineID; + XLogCtl->PrevTimeLineID = ThisTimeLineID; /* * Copy any missing timeline history files between 'now' and the recovery @@ -7628,6 +7639,8 @@ StartupXLOG(void) /* Following WAL records should be run with new TLI */ ThisTimeLineID = newTLI; + XLogCtl->ThisTimeLineID = ThisTimeLineID; + XLogCtl->PrevTimeLineID = ThisTimeLineID; switchedTLI = true; } } @@ -7917,7 +7930,6 @@ StartupXLOG(void) * * In a normal crash recovery, we can just extend the timeline we were in. */ - PrevTimeLineID = ThisTimeLineID; if (ArchiveRecoveryRequested) { char *reason; @@ -7926,6 +7938,7 @@ StartupXLOG(void) Assert(InArchiveRecovery); ThisTimeLineID = findNewestTimeLine(recoveryTargetTLI) + 1; + XLogCtl->ThisTimeLineID = ThisTimeLineID; ereport(LOG, (errmsg("selected new timeline ID: %u", ThisTimeLineID))); @@ -7964,10 +7977,6 @@ StartupXLOG(void) unlink(recoveryPath); /* ignore any error */ } - /* Save the selected TimeLineID in shared memory, too */ - XLogCtl->ThisTimeLineID = ThisTimeLineID; - XLogCtl->PrevTimeLineID = PrevTimeLineID; - /* * Actually, if WAL ended in an incomplete record, skip the parts that * made it through and start writing after the portion that persisted.