xlog.c: Change assorted functions to take an explicit TimeLineID.
authorRobert Haas <[email protected]>
Mon, 1 Nov 2021 14:44:46 +0000 (10:44 -0400)
committerRobert Haas <[email protected]>
Mon, 1 Nov 2021 16:11:53 +0000 (12:11 -0400)
It is confusing to have functions whose behavior depends on the
value of a global variable, so where possible, make the caller
pass the timeline as an explicit argument.

src/backend/access/transam/xlog.c
src/include/access/xlog.h

index 801175c177a3d98410e8b4cadfcd3495c84f320e..16f90769c28da5b555b866f386ad8036d285bfb0 100644 (file)
@@ -889,9 +889,11 @@ static MemoryContext walDebugCxt = NULL;
 
 static void readRecoverySignalFile(void);
 static void validateRecoveryParameters(void);
-static void exitArchiveRecovery(TimeLineID endTLI, XLogRecPtr endOfLog);
+static void exitArchiveRecovery(TimeLineID endTLI, XLogRecPtr endOfLog,
+                                                               TimeLineID newTLI);
 static void CleanupAfterArchiveRecovery(TimeLineID EndOfLogTLI,
-                                                                               XLogRecPtr EndOfLog);
+                                                                               XLogRecPtr EndOfLog,
+                                                                               TimeLineID newTLI);
 static bool recoveryStopsBefore(XLogReaderState *record);
 static bool recoveryStopsAfter(XLogReaderState *record);
 static char *getRecoveryStopReason(void);
@@ -903,7 +905,7 @@ static void SetCurrentChunkStartTime(TimestampTz xtime);
 static void CheckRequiredParameterValues(void);
 static void XLogReportParameters(void);
 static void checkTimeLineSwitch(XLogRecPtr lsn, TimeLineID newTLI,
-                                                               TimeLineID prevTLI);
+                                                               TimeLineID prevTLI, TimeLineID replayTLI);
 static void VerifyOverwriteContrecord(xl_overwrite_contrecord *xlrec,
                                                                          XLogReaderState *state);
 static int LocalSetXLogInsertAllowed(void);
@@ -913,9 +915,10 @@ static void CheckPointGuts(XLogRecPtr checkPointRedo, int flags);
 static void KeepLogSeg(XLogRecPtr recptr, XLogSegNo *logSegNo);
 static XLogRecPtr XLogGetReplicationSlotMinimumLSN(void);
 
-static void AdvanceXLInsertBuffer(XLogRecPtr upto, bool opportunistic);
+static void AdvanceXLInsertBuffer(XLogRecPtr upto, TimeLineID tli,
+                                                                 bool opportunistic);
 static bool XLogCheckpointNeeded(XLogSegNo new_segno);
-static void XLogWrite(XLogwrtRqst WriteRqst, bool flexible);
+static void XLogWrite(XLogwrtRqst WriteRqst, TimeLineID tli, bool flexible);
 static bool InstallXLogFileSegment(XLogSegNo *segno, char *tmppath,
                                                                   bool find_free, XLogSegNo max_segno,
                                                                   TimeLineID tli);
@@ -929,11 +932,12 @@ static bool WaitForWALToBecomeAvailable(XLogRecPtr RecPtr, bool randAccess,
 static void XLogShutdownWalRcv(void);
 static int     emode_for_corrupt_record(int emode, XLogRecPtr RecPtr);
 static void XLogFileClose(void);
-static void PreallocXlogFiles(XLogRecPtr endptr);
+static void PreallocXlogFiles(XLogRecPtr endptr, TimeLineID tli);
 static void RemoveTempXlogFiles(void);
-static void RemoveOldXlogFiles(XLogSegNo segno, XLogRecPtr lastredoptr, XLogRecPtr endptr);
+static void RemoveOldXlogFiles(XLogSegNo segno, XLogRecPtr lastredoptr,
+                                                          XLogRecPtr endptr, TimeLineID insertTLI);
 static void RemoveXlogFile(const char *segname, XLogSegNo recycleSegNo,
-                                                  XLogSegNo *endlogSegNo);
+                                                  XLogSegNo *endlogSegNo, TimeLineID insertTLI);
 static void UpdateLastRemovedPtr(char *filename);
 static void ValidateXLOGDirectoryStructure(void);
 static void CleanupBackupHistory(void);
@@ -968,13 +972,14 @@ static int        get_sync_bit(int method);
 
 static void CopyXLogRecordToWAL(int write_len, bool isLogSwitch,
                                                                XLogRecData *rdata,
-                                                               XLogRecPtr StartPos, XLogRecPtr EndPos);
+                                                               XLogRecPtr StartPos, XLogRecPtr EndPos,
+                                                               TimeLineID tli);
 static void ReserveXLogInsertLocation(int size, XLogRecPtr *StartPos,
                                                                          XLogRecPtr *EndPos, XLogRecPtr *PrevPtr);
 static bool ReserveXLogSwitch(XLogRecPtr *StartPos, XLogRecPtr *EndPos,
                                                          XLogRecPtr *PrevPtr);
 static XLogRecPtr WaitXLogInsertionsToFinish(XLogRecPtr upto);
-static char *GetXLogBuffer(XLogRecPtr ptr);
+static char *GetXLogBuffer(XLogRecPtr ptr, TimeLineID tli);
 static XLogRecPtr XLogBytePosToRecPtr(uint64 bytepos);
 static XLogRecPtr XLogBytePosToEndRecPtr(uint64 bytepos);
 static uint64 XLogRecPtrToBytePos(XLogRecPtr ptr);
@@ -1138,7 +1143,7 @@ XLogInsertRecord(XLogRecData *rdata,
                 * inserted. Copy the record in the space reserved.
                 */
                CopyXLogRecordToWAL(rechdr->xl_tot_len, isLogSwitch, rdata,
-                                                       StartPos, EndPos);
+                                                       StartPos, EndPos, ThisTimeLineID);
 
                /*
                 * Unless record is flagged as not important, update LSN of last
@@ -1522,7 +1527,7 @@ checkXLogConsistency(XLogReaderState *record)
  */
 static void
 CopyXLogRecordToWAL(int write_len, bool isLogSwitch, XLogRecData *rdata,
-                                       XLogRecPtr StartPos, XLogRecPtr EndPos)
+                                       XLogRecPtr StartPos, XLogRecPtr EndPos, TimeLineID tli)
 {
        char       *currpos;
        int                     freespace;
@@ -1535,7 +1540,7 @@ CopyXLogRecordToWAL(int write_len, bool isLogSwitch, XLogRecData *rdata,
         * inserting to.
         */
        CurrPos = StartPos;
-       currpos = GetXLogBuffer(CurrPos);
+       currpos = GetXLogBuffer(CurrPos, tli);
        freespace = INSERT_FREESPACE(CurrPos);
 
        /*
@@ -1572,7 +1577,7 @@ CopyXLogRecordToWAL(int write_len, bool isLogSwitch, XLogRecData *rdata,
                         * page was initialized, in AdvanceXLInsertBuffer, and we're the
                         * only backend that needs to set the contrecord flag.
                         */
-                       currpos = GetXLogBuffer(CurrPos);
+                       currpos = GetXLogBuffer(CurrPos, tli);
                        pagehdr = (XLogPageHeader) currpos;
                        pagehdr->xlp_rem_len = write_len - written;
                        pagehdr->xlp_info |= XLP_FIRST_IS_CONTRECORD;
@@ -1645,7 +1650,7 @@ CopyXLogRecordToWAL(int write_len, bool isLogSwitch, XLogRecData *rdata,
                         * (which itself calls the two methods we need) to get the pointer
                         * and zero most of the page.  Then we just zero the page header.
                         */
-                       currpos = GetXLogBuffer(CurrPos);
+                       currpos = GetXLogBuffer(CurrPos, tli);
                        MemSet(currpos, 0, SizeOfXLogShortPHD);
 
                        CurrPos += XLOG_BLCKSZ;
@@ -1897,7 +1902,7 @@ WaitXLogInsertionsToFinish(XLogRecPtr upto)
  * later, because older buffers might be recycled already)
  */
 static char *
-GetXLogBuffer(XLogRecPtr ptr)
+GetXLogBuffer(XLogRecPtr ptr, TimeLineID tli)
 {
        int                     idx;
        XLogRecPtr      endptr;
@@ -1973,7 +1978,7 @@ GetXLogBuffer(XLogRecPtr ptr)
 
                WALInsertLockUpdateInsertingAt(initializedUpto);
 
-               AdvanceXLInsertBuffer(ptr, false);
+               AdvanceXLInsertBuffer(ptr, tli, false);
                endptr = XLogCtl->xlblocks[idx];
 
                if (expectedEndPtr != endptr)
@@ -2135,7 +2140,7 @@ XLogRecPtrToBytePos(XLogRecPtr ptr)
  * initialized properly.
  */
 static void
-AdvanceXLInsertBuffer(XLogRecPtr upto, bool opportunistic)
+AdvanceXLInsertBuffer(XLogRecPtr upto, TimeLineID tli, bool opportunistic)
 {
        XLogCtlInsert *Insert = &XLogCtl->Insert;
        int                     nextidx;
@@ -2208,7 +2213,7 @@ AdvanceXLInsertBuffer(XLogRecPtr upto, bool opportunistic)
                                        TRACE_POSTGRESQL_WAL_BUFFER_WRITE_DIRTY_START();
                                        WriteRqst.Write = OldPageRqstPtr;
                                        WriteRqst.Flush = 0;
-                                       XLogWrite(WriteRqst, false);
+                                       XLogWrite(WriteRqst, tli, false);
                                        LWLockRelease(WALWriteLock);
                                        WalStats.m_wal_buffers_full++;
                                        TRACE_POSTGRESQL_WAL_BUFFER_WRITE_DIRTY_DONE();
@@ -2242,7 +2247,7 @@ AdvanceXLInsertBuffer(XLogRecPtr upto, bool opportunistic)
                NewPage->xlp_magic = XLOG_PAGE_MAGIC;
 
                /* NewPage->xlp_info = 0; */    /* done by memset */
-               NewPage->xlp_tli = ThisTimeLineID;
+               NewPage->xlp_tli = tli;
                NewPage->xlp_pageaddr = NewPageBeginPtr;
 
                /* NewPage->xlp_rem_len = 0; */ /* done by memset */
@@ -2438,7 +2443,7 @@ XLogCheckpointNeeded(XLogSegNo new_segno)
  * write.
  */
 static void
-XLogWrite(XLogwrtRqst WriteRqst, bool flexible)
+XLogWrite(XLogwrtRqst WriteRqst, TimeLineID tli, bool flexible)
 {
        bool            ispartialpage;
        bool            last_iteration;
@@ -2508,7 +2513,7 @@ XLogWrite(XLogwrtRqst WriteRqst, bool flexible)
                                                        wal_segment_size);
 
                        /* create/use new log file */
-                       openLogFile = XLogFileInit(openLogSegNo, ThisTimeLineID);
+                       openLogFile = XLogFileInit(openLogSegNo, tli);
                        ReserveExternalFD();
                }
 
@@ -2517,7 +2522,7 @@ XLogWrite(XLogwrtRqst WriteRqst, bool flexible)
                {
                        XLByteToPrevSeg(LogwrtResult.Write, openLogSegNo,
                                                        wal_segment_size);
-                       openLogFile = XLogFileOpen(openLogSegNo);
+                       openLogFile = XLogFileOpen(openLogSegNo, tli);
                        ReserveExternalFD();
                }
 
@@ -2592,7 +2597,7 @@ XLogWrite(XLogwrtRqst WriteRqst, bool flexible)
                                                continue;
 
                                        save_errno = errno;
-                                       XLogFileName(xlogfname, ThisTimeLineID, openLogSegNo,
+                                       XLogFileName(xlogfname, tli, openLogSegNo,
                                                                 wal_segment_size);
                                        errno = save_errno;
                                        ereport(PANIC,
@@ -2623,7 +2628,7 @@ XLogWrite(XLogwrtRqst WriteRqst, bool flexible)
                         */
                        if (finishing_seg)
                        {
-                               issue_xlog_fsync(openLogFile, openLogSegNo, ThisTimeLineID);
+                               issue_xlog_fsync(openLogFile, openLogSegNo, tli);
 
                                /* signal that we need to wakeup walsenders later */
                                WalSndWakeupRequest();
@@ -2631,7 +2636,7 @@ XLogWrite(XLogwrtRqst WriteRqst, bool flexible)
                                LogwrtResult.Flush = LogwrtResult.Write;        /* end of page */
 
                                if (XLogArchivingActive())
-                                       XLogArchiveNotifySeg(openLogSegNo, ThisTimeLineID);
+                                       XLogArchiveNotifySeg(openLogSegNo, tli);
 
                                XLogCtl->lastSegSwitchTime = (pg_time_t) time(NULL);
                                XLogCtl->lastSegSwitchLSN = LogwrtResult.Flush;
@@ -2690,11 +2695,11 @@ XLogWrite(XLogwrtRqst WriteRqst, bool flexible)
                        {
                                XLByteToPrevSeg(LogwrtResult.Write, openLogSegNo,
                                                                wal_segment_size);
-                               openLogFile = XLogFileOpen(openLogSegNo);
+                               openLogFile = XLogFileOpen(openLogSegNo, tli);
                                ReserveExternalFD();
                        }
 
-                       issue_xlog_fsync(openLogFile, openLogSegNo, ThisTimeLineID);
+                       issue_xlog_fsync(openLogFile, openLogSegNo, tli);
                }
 
                /* signal that we need to wakeup walsenders later */
@@ -3010,7 +3015,7 @@ XLogFlush(XLogRecPtr record)
                WriteRqst.Write = insertpos;
                WriteRqst.Flush = insertpos;
 
-               XLogWrite(WriteRqst, false);
+               XLogWrite(WriteRqst, ThisTimeLineID, false);
 
                LWLockRelease(WALWriteLock);
                /* done */
@@ -3177,7 +3182,7 @@ XLogBackgroundFlush(void)
        if (WriteRqst.Write > LogwrtResult.Write ||
                WriteRqst.Flush > LogwrtResult.Flush)
        {
-               XLogWrite(WriteRqst, flexible);
+               XLogWrite(WriteRqst, ThisTimeLineID, flexible);
        }
        LWLockRelease(WALWriteLock);
 
@@ -3190,7 +3195,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, true);
+       AdvanceXLInsertBuffer(InvalidXLogRecPtr, ThisTimeLineID, true);
 
        /*
         * If we determined that we need to write data, but somebody else
@@ -3512,7 +3517,8 @@ XLogFileInit(XLogSegNo logsegno, TimeLineID logtli)
  * emplacing a bogus file.
  */
 static void
-XLogFileCopy(XLogSegNo destsegno, TimeLineID srcTLI, XLogSegNo srcsegno,
+XLogFileCopy(TimeLineID destTLI, XLogSegNo destsegno,
+                        TimeLineID srcTLI, XLogSegNo srcsegno,
                         int upto)
 {
        char            path[MAXPGPATH];
@@ -3625,7 +3631,7 @@ XLogFileCopy(XLogSegNo destsegno, TimeLineID srcTLI, XLogSegNo srcsegno,
        /*
         * Now move the segment into place with its final name.
         */
-       if (!InstallXLogFileSegment(&destsegno, tmppath, false, 0, ThisTimeLineID))
+       if (!InstallXLogFileSegment(&destsegno, tmppath, false, 0, destTLI))
                elog(ERROR, "InstallXLogFileSegment should not have failed");
 }
 
@@ -3714,12 +3720,12 @@ InstallXLogFileSegment(XLogSegNo *segno, char *tmppath,
  * Open a pre-existing logfile segment for writing.
  */
 int
-XLogFileOpen(XLogSegNo segno)
+XLogFileOpen(XLogSegNo segno, TimeLineID tli)
 {
        char            path[MAXPGPATH];
        int                     fd;
 
-       XLogFilePath(path, ThisTimeLineID, segno, wal_segment_size);
+       XLogFilePath(path, tli, segno, wal_segment_size);
 
        fd = BasicOpenFile(path, O_RDWR | PG_BINARY | get_sync_bit(sync_method));
        if (fd < 0)
@@ -3971,7 +3977,7 @@ XLogFileClose(void)
  * reporting and resource reclamation.)
  */
 static void
-PreallocXlogFiles(XLogRecPtr endptr)
+PreallocXlogFiles(XLogRecPtr endptr, TimeLineID tli)
 {
        XLogSegNo       _logSegNo;
        int                     lf;
@@ -3987,7 +3993,7 @@ PreallocXlogFiles(XLogRecPtr endptr)
        if (offset >= (uint32) (0.75 * wal_segment_size))
        {
                _logSegNo++;
-               lf = XLogFileInitInternal(_logSegNo, ThisTimeLineID, &added, path);
+               lf = XLogFileInitInternal(_logSegNo, tli, &added, path);
                if (lf >= 0)
                        close(lf);
                if (added)
@@ -4104,9 +4110,13 @@ RemoveTempXlogFiles(void)
  * endptr is current (or recent) end of xlog, and lastredoptr is the
  * redo pointer of the last checkpoint. These are used to determine
  * whether we want to recycle rather than delete no-longer-wanted log files.
+ *
+ * insertTLI is the current timeline for XLOG insertion. Any recycled
+ * segments should be reused for this timeline.
  */
 static void
-RemoveOldXlogFiles(XLogSegNo segno, XLogRecPtr lastredoptr, XLogRecPtr endptr)
+RemoveOldXlogFiles(XLogSegNo segno, XLogRecPtr lastredoptr, XLogRecPtr endptr,
+                                  TimeLineID insertTLI)
 {
        DIR                *xldir;
        struct dirent *xlde;
@@ -4155,7 +4165,8 @@ RemoveOldXlogFiles(XLogSegNo segno, XLogRecPtr lastredoptr, XLogRecPtr endptr)
                                /* Update the last removed location in shared memory first */
                                UpdateLastRemovedPtr(xlde->d_name);
 
-                               RemoveXlogFile(xlde->d_name, recycleSegNo, &endlogSegNo);
+                               RemoveXlogFile(xlde->d_name, recycleSegNo, &endlogSegNo,
+                                                          insertTLI);
                        }
                }
        }
@@ -4227,7 +4238,8 @@ RemoveNonParentXlogFiles(XLogRecPtr switchpoint, TimeLineID newTLI)
                         * - but seems safer to let them be archived and removed later.
                         */
                        if (!XLogArchiveIsReady(xlde->d_name))
-                               RemoveXlogFile(xlde->d_name, recycleSegNo, &endLogSegNo);
+                               RemoveXlogFile(xlde->d_name, recycleSegNo, &endLogSegNo,
+                                                          newTLI);
                }
        }
 
@@ -4243,10 +4255,13 @@ RemoveNonParentXlogFiles(XLogRecPtr switchpoint, TimeLineID newTLI)
  *
  * endlogSegNo gets incremented if the segment is recycled so as it is not
  * checked again with future callers of this function.
+ *
+ * insertTLI is the current timeline for XLOG insertion. Any recycled segments
+ * should be used for this timeline.
  */
 static void
 RemoveXlogFile(const char *segname, XLogSegNo recycleSegNo,
-                          XLogSegNo *endlogSegNo)
+                          XLogSegNo *endlogSegNo, TimeLineID insertTLI)
 {
        char            path[MAXPGPATH];
 #ifdef WIN32
@@ -4266,7 +4281,7 @@ RemoveXlogFile(const char *segname, XLogSegNo recycleSegNo,
                XLogCtl->InstallXLogFileSegmentActive &&        /* callee rechecks this */
                lstat(path, &statbuf) == 0 && S_ISREG(statbuf.st_mode) &&
                InstallXLogFileSegment(endlogSegNo, path,
-                                                          true, recycleSegNo, ThisTimeLineID))
+                                                          true, recycleSegNo, insertTLI))
        {
                ereport(DEBUG2,
                                (errmsg_internal("recycled write-ahead log file \"%s\"",
@@ -5645,14 +5660,14 @@ validateRecoveryParameters(void)
  * Exit archive-recovery state
  */
 static void
-exitArchiveRecovery(TimeLineID endTLI, XLogRecPtr endOfLog)
+exitArchiveRecovery(TimeLineID endTLI, XLogRecPtr endOfLog, TimeLineID newTLI)
 {
        char            xlogfname[MAXFNAMELEN];
        XLogSegNo       endLogSegNo;
        XLogSegNo       startLogSegNo;
 
        /* we always switch to a new timeline after archive recovery */
-       Assert(endTLI != ThisTimeLineID);
+       Assert(endTLI != newTLI);
 
        /*
         * We are no longer in archive recovery state.
@@ -5698,7 +5713,7 @@ exitArchiveRecovery(TimeLineID endTLI, XLogRecPtr endOfLog)
                 * considerations. But we should be just as tense as XLogFileInit to
                 * avoid emplacing a bogus file.
                 */
-               XLogFileCopy(endLogSegNo, endTLI, endLogSegNo,
+               XLogFileCopy(newTLI, endLogSegNo, endTLI, endLogSegNo,
                                         XLogSegmentOffset(endOfLog, wal_segment_size));
        }
        else
@@ -5709,15 +5724,14 @@ exitArchiveRecovery(TimeLineID endTLI, XLogRecPtr endOfLog)
                 */
                int                     fd;
 
-               fd = XLogFileInit(startLogSegNo, ThisTimeLineID);
+               fd = XLogFileInit(startLogSegNo, newTLI);
 
                if (close(fd) != 0)
                {
                        char            xlogfname[MAXFNAMELEN];
                        int                     save_errno = errno;
 
-                       XLogFileName(xlogfname, ThisTimeLineID, startLogSegNo,
-                                                wal_segment_size);
+                       XLogFileName(xlogfname, newTLI, startLogSegNo, wal_segment_size);
                        errno = save_errno;
                        ereport(ERROR,
                                        (errcode_for_file_access(),
@@ -5729,7 +5743,7 @@ exitArchiveRecovery(TimeLineID endTLI, XLogRecPtr endOfLog)
         * Let's just make real sure there are not .ready or .done flags posted
         * for the new segment.
         */
-       XLogFileName(xlogfname, ThisTimeLineID, startLogSegNo, wal_segment_size);
+       XLogFileName(xlogfname, newTLI, startLogSegNo, wal_segment_size);
        XLogArchiveCleanup(xlogfname);
 
        /*
@@ -5750,7 +5764,8 @@ exitArchiveRecovery(TimeLineID endTLI, XLogRecPtr endOfLog)
  * Perform cleanup actions at the conclusion of archive recovery.
  */
 static void
-CleanupAfterArchiveRecovery(TimeLineID EndOfLogTLI, XLogRecPtr EndOfLog)
+CleanupAfterArchiveRecovery(TimeLineID EndOfLogTLI, XLogRecPtr EndOfLog,
+                                                       TimeLineID newTLI)
 {
        /*
         * Execute the recovery_end_command, if any.
@@ -5768,7 +5783,7 @@ CleanupAfterArchiveRecovery(TimeLineID EndOfLogTLI, XLogRecPtr EndOfLog)
         * files containing garbage. In any case, they are not part of the new
         * timeline's history so we don't need them.
         */
-       RemoveNonParentXlogFiles(EndOfLog, ThisTimeLineID);
+       RemoveNonParentXlogFiles(EndOfLog, newTLI);
 
        /*
         * If the switch happened in the middle of a segment, what to do with the
@@ -7635,7 +7650,8 @@ StartupXLOG(void)
                                        if (newTLI != ThisTimeLineID)
                                        {
                                                /* Check that it's OK to switch to this TLI */
-                                               checkTimeLineSwitch(EndRecPtr, newTLI, prevTLI);
+                                               checkTimeLineSwitch(EndRecPtr, newTLI, prevTLI,
+                                                                                       ThisTimeLineID);
 
                                                /* Following WAL records should be run with new TLI */
                                                ThisTimeLineID = newTLI;
@@ -7948,7 +7964,7 @@ StartupXLOG(void)
                 * (Note that we also have a copy of the last block of the old WAL in
                 * readBuf; we will use that below.)
                 */
-               exitArchiveRecovery(EndOfLogTLI, EndOfLog);
+               exitArchiveRecovery(EndOfLogTLI, EndOfLog, ThisTimeLineID);
 
                /*
                 * Write the timeline history file, and have it archived. After this
@@ -8046,7 +8062,7 @@ StartupXLOG(void)
        /*
         * Preallocate additional log files, if wanted.
         */
-       PreallocXlogFiles(EndOfLog);
+       PreallocXlogFiles(EndOfLog, ThisTimeLineID);
 
        /*
         * Okay, we're officially UP.
@@ -8127,7 +8143,7 @@ StartupXLOG(void)
 
        /* If this is archive recovery, perform post-recovery cleanup actions. */
        if (ArchiveRecoveryRequested)
-               CleanupAfterArchiveRecovery(EndOfLogTLI, EndOfLog);
+               CleanupAfterArchiveRecovery(EndOfLogTLI, EndOfLog, ThisTimeLineID);
 
        /*
         * Local WAL inserts enabled, so it's time to finish initialization of
@@ -9440,14 +9456,14 @@ CreateCheckPoint(int flags)
                KeepLogSeg(recptr, &_logSegNo);
        }
        _logSegNo--;
-       RemoveOldXlogFiles(_logSegNo, RedoRecPtr, recptr);
+       RemoveOldXlogFiles(_logSegNo, RedoRecPtr, recptr, 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);
+               PreallocXlogFiles(recptr, ThisTimeLineID);
 
        /*
         * Truncate pg_subtrans if possible.  We can throw away all data before
@@ -9848,13 +9864,13 @@ CreateRestartPoint(int flags)
        if (RecoveryInProgress())
                ThisTimeLineID = replayTLI;
 
-       RemoveOldXlogFiles(_logSegNo, RedoRecPtr, endptr);
+       RemoveOldXlogFiles(_logSegNo, RedoRecPtr, endptr, ThisTimeLineID);
 
        /*
         * Make more log segments if needed.  (Do this after recycling old log
         * segments, since that may supply some of the needed files.)
         */
-       PreallocXlogFiles(endptr);
+       PreallocXlogFiles(endptr, ThisTimeLineID);
 
        /*
         * ThisTimeLineID is normally not set when we're still in recovery.
@@ -10271,22 +10287,23 @@ UpdateFullPageWrites(void)
  * replay. (Currently, timeline can only change at a shutdown checkpoint).
  */
 static void
-checkTimeLineSwitch(XLogRecPtr lsn, TimeLineID newTLI, TimeLineID prevTLI)
+checkTimeLineSwitch(XLogRecPtr lsn, TimeLineID newTLI, TimeLineID prevTLI,
+                                       TimeLineID replayTLI)
 {
        /* Check that the record agrees on what the current (old) timeline is */
-       if (prevTLI != ThisTimeLineID)
+       if (prevTLI != replayTLI)
                ereport(PANIC,
                                (errmsg("unexpected previous timeline ID %u (current timeline ID %u) in checkpoint record",
-                                               prevTLI, ThisTimeLineID)));
+                                               prevTLI, replayTLI)));
 
        /*
         * The new timeline better be in the list of timelines we expect to see,
         * according to the timeline history. It should also not decrease.
         */
-       if (newTLI < ThisTimeLineID || !tliInHistory(newTLI, expectedTLEs))
+       if (newTLI < replayTLI || !tliInHistory(newTLI, expectedTLEs))
                ereport(PANIC,
                                (errmsg("unexpected timeline ID %u (after %u) in checkpoint record",
-                                               newTLI, ThisTimeLineID)));
+                                               newTLI, replayTLI)));
 
        /*
         * If we have not yet reached min recovery point, and we're about to
index 51a672b703f6d698a07fd2277b1c54210823fda5..2b42082ffeb1e67f94b445acf8f8080460c2b55d 100644 (file)
@@ -261,7 +261,7 @@ extern void XLogFlush(XLogRecPtr RecPtr);
 extern bool XLogBackgroundFlush(void);
 extern bool XLogNeedsFlush(XLogRecPtr RecPtr);
 extern int     XLogFileInit(XLogSegNo segno, TimeLineID tli);
-extern int     XLogFileOpen(XLogSegNo segno);
+extern int     XLogFileOpen(XLogSegNo segno, TimeLineID tli);
 
 extern void CheckXLogRemoved(XLogSegNo segno, TimeLineID tli);
 extern XLogSegNo XLogGetLastRemovedSegno(void);