backend-private struct xlogacceptwrites
authorRobert Haas <[email protected]>
Mon, 18 Apr 2022 15:30:33 +0000 (11:30 -0400)
committerRobert Haas <[email protected]>
Tue, 19 Apr 2022 17:13:40 +0000 (13:13 -0400)
src/backend/access/transam/xlog.c
src/include/access/xlog.h

index 912a913b64731b522f62870123149f2fe3ab60ab..3c6eafaf92d89485f2ac8dc900d26ed2d3c1b8f8 100644 (file)
@@ -665,6 +665,7 @@ static void UpdateLastRemovedPtr(char *filename);
 static void ValidateXLOGDirectoryStructure(void);
 static void CleanupBackupHistory(void);
 static void UpdateMinRecoveryPoint(XLogRecPtr lsn, bool force);
+static void XLogAcceptWrites(XLogAcceptWritesInfo *awi);
 static void InitControlFile(uint64 sysidentifier);
 static void WriteControlFile(void);
 static void ReadControlFile(void);
@@ -4887,13 +4888,8 @@ StartupXLOG(void)
        bool            didCrash;
        bool            haveTblspcMap;
        bool            haveBackupLabel;
-       XLogRecPtr      EndOfLog;
-       TimeLineID      EndOfLogTLI;
-       TimeLineID      newTLI;
-       bool            performedWalRecovery;
        EndOfWalRecoveryInfo *endOfRecoveryInfo;
-       XLogRecPtr      abortedRecPtr;
-       XLogRecPtr      missingContrecPtr;
+       XLogAcceptWritesInfo    awi;
        TransactionId oldestActiveXID;
 
        /*
@@ -5293,19 +5289,19 @@ StartupXLOG(void)
                 * We're all set for replaying the WAL now. Do it.
                 */
                PerformWalRecovery();
-               performedWalRecovery = true;
+               awi.performedWalRecovery = true;
        }
        else
-               performedWalRecovery = false;
+               awi.performedWalRecovery = false;
 
        /*
         * Finish WAL recovery.
         */
        endOfRecoveryInfo = FinishWalRecovery();
-       EndOfLog = endOfRecoveryInfo->endOfLog;
-       EndOfLogTLI = endOfRecoveryInfo->endOfLogTLI;
-       abortedRecPtr = endOfRecoveryInfo->abortedRecPtr;
-       missingContrecPtr = endOfRecoveryInfo->missingContrecPtr;
+       awi.EndOfLog = endOfRecoveryInfo->endOfLog;
+       awi.EndOfLogTLI = endOfRecoveryInfo->endOfLogTLI;
+       awi.abortedRecPtr = endOfRecoveryInfo->abortedRecPtr;
+       awi.missingContrecPtr = endOfRecoveryInfo->missingContrecPtr;
 
        /*
         * When recovering from a backup (we are in recovery, and archive recovery
@@ -5326,7 +5322,7 @@ StartupXLOG(void)
         * been advanced beyond the WAL we processed.
         */
        if (InRecovery &&
-               (EndOfLog < LocalMinRecoveryPoint ||
+               (awi.EndOfLog < LocalMinRecoveryPoint ||
                 !XLogRecPtrIsInvalid(ControlFile->backupStartPoint)))
        {
                /*
@@ -5386,19 +5382,19 @@ StartupXLOG(void)
         *
         * In a normal crash recovery, we can just extend the timeline we were in.
         */
-       newTLI = endOfRecoveryInfo->lastRecTLI;
+       awi.newTLI = endOfRecoveryInfo->lastRecTLI;
        if (ArchiveRecoveryRequested)
        {
-               newTLI = findNewestTimeLine(recoveryTargetTLI) + 1;
+               awi.newTLI = findNewestTimeLine(recoveryTargetTLI) + 1;
                ereport(LOG,
-                               (errmsg("selected new timeline ID: %u", newTLI)));
+                               (errmsg("selected new timeline ID: %u", awi.newTLI)));
 
                /*
                 * Make a writable copy of the last WAL segment.  (Note that we also
                 * have a copy of the last block of the old WAL in
                 * endOfRecovery->lastPage; we will use that below.)
                 */
-               XLogInitNewTimeline(EndOfLogTLI, EndOfLog, newTLI);
+               XLogInitNewTimeline(awi.EndOfLogTLI, awi.EndOfLog, awi.newTLI);
 
                /*
                 * Remove the signal files out of the way, so that we don't
@@ -5420,15 +5416,16 @@ StartupXLOG(void)
                 * To minimize the window for that, try to do as little as possible
                 * between here and writing the end-of-recovery record.
                 */
-               writeTimeLineHistory(newTLI, recoveryTargetTLI,
-                                                        EndOfLog, endOfRecoveryInfo->recoveryStopReason);
+               writeTimeLineHistory(awi.newTLI, recoveryTargetTLI,
+                                                        awi.EndOfLog,
+                                                        endOfRecoveryInfo->recoveryStopReason);
 
                ereport(LOG,
                                (errmsg("archive recovery complete")));
        }
 
        /* Save the selected TimeLineID in shared memory, too */
-       XLogCtl->InsertTimeLineID = newTLI;
+       XLogCtl->InsertTimeLineID = awi.newTLI;
        XLogCtl->PrevTimeLineID = endOfRecoveryInfo->lastRecTLI;
 
        /*
@@ -5437,10 +5434,10 @@ StartupXLOG(void)
         * (It's critical to first write an OVERWRITE_CONTRECORD message, which
         * we'll do as soon as we're open for writing new WAL.)
         */
-       if (!XLogRecPtrIsInvalid(missingContrecPtr))
+       if (!XLogRecPtrIsInvalid(awi.missingContrecPtr))
        {
-               Assert(!XLogRecPtrIsInvalid(abortedRecPtr));
-               EndOfLog = missingContrecPtr;
+               Assert(!XLogRecPtrIsInvalid(awi.abortedRecPtr));
+               awi.EndOfLog = awi.missingContrecPtr;
        }
 
        /*
@@ -5450,21 +5447,21 @@ StartupXLOG(void)
         */
        Insert = &XLogCtl->Insert;
        Insert->PrevBytePos = XLogRecPtrToBytePos(endOfRecoveryInfo->lastRec);
-       Insert->CurrBytePos = XLogRecPtrToBytePos(EndOfLog);
+       Insert->CurrBytePos = XLogRecPtrToBytePos(awi.EndOfLog);
 
        /*
         * Tricky point here: lastPage contains the *last* block that the LastRec
         * record spans, not the one it starts in.  The last block is indeed the
         * one we want to use.
         */
-       if (EndOfLog % XLOG_BLCKSZ != 0)
+       if (awi.EndOfLog % XLOG_BLCKSZ != 0)
        {
                char       *page;
                int                     len;
                int                     firstIdx;
 
-               firstIdx = XLogRecPtrToBufIdx(EndOfLog);
-               len = EndOfLog - endOfRecoveryInfo->lastPageBeginPtr;
+               firstIdx = XLogRecPtrToBufIdx(awi.EndOfLog);
+               len = awi.EndOfLog - endOfRecoveryInfo->lastPageBeginPtr;
                Assert(len < XLOG_BLCKSZ);
 
                /* Copy the valid part of the last block, and zero the rest */
@@ -5482,20 +5479,20 @@ StartupXLOG(void)
                 * let the first attempt to insert a log record to initialize the next
                 * buffer.
                 */
-               XLogCtl->InitializedUpTo = EndOfLog;
+               XLogCtl->InitializedUpTo = awi.EndOfLog;
        }
 
-       LogwrtResult.Write = LogwrtResult.Flush = EndOfLog;
+       LogwrtResult.Write = LogwrtResult.Flush = awi.EndOfLog;
 
        XLogCtl->LogwrtResult = LogwrtResult;
 
-       XLogCtl->LogwrtRqst.Write = EndOfLog;
-       XLogCtl->LogwrtRqst.Flush = EndOfLog;
+       XLogCtl->LogwrtRqst.Write = awi.EndOfLog;
+       XLogCtl->LogwrtRqst.Flush = awi.EndOfLog;
 
        /*
         * Preallocate additional log files, if wanted.
         */
-       PreallocXlogFiles(EndOfLog, newTLI);
+       PreallocXlogFiles(awi.EndOfLog, awi.newTLI);
 
        /*
         * Okay, we're officially UP.
@@ -5504,7 +5501,7 @@ StartupXLOG(void)
 
        /* start the archive_timeout timer and LSN running */
        XLogCtl->lastSegSwitchTime = (pg_time_t) time(NULL);
-       XLogCtl->lastSegSwitchLSN = EndOfLog;
+       XLogCtl->lastSegSwitchLSN = awi.EndOfLog;
 
        /* also initialize latestCompletedXid, to nextXid - 1 */
        LWLockAcquire(ProcArrayLock, LW_EXCLUSIVE);
@@ -5531,45 +5528,8 @@ StartupXLOG(void)
        /* Shut down xlogreader */
        ShutdownWalRecovery();
 
-       /* Enable WAL writes for this backend only. */
-       LocalSetXLogInsertAllowed();
-
-       /* If necessary, write overwrite-contrecord before doing anything else */
-       if (!XLogRecPtrIsInvalid(abortedRecPtr))
-       {
-               Assert(!XLogRecPtrIsInvalid(missingContrecPtr));
-               CreateOverwriteContrecordRecord(abortedRecPtr, missingContrecPtr, newTLI);
-       }
-
-       /*
-        * Update full_page_writes in shared memory and write an XLOG_FPW_CHANGE
-        * record before resource manager writes cleanup WAL records or checkpoint
-        * record is written.
-        */
-       Insert->fullPageWrites = lastFullPageWrites;
-       UpdateFullPageWrites();
-
-       /*
-        * Emit end-of-recovery record in XLOG, if required.
-        */
-       if (performedWalRecovery)
-               CreateEndOfRecoveryRecord();
-
-       /*
-        * If any of the critical GUCs have changed, log them before we allow
-        * backends to write WAL.
-        */
-       XLogReportParameters();
-
-       /* If this is archive recovery, perform post-recovery cleanup actions. */
-       if (ArchiveRecoveryRequested)
-               CleanupAfterArchiveRecovery(EndOfLogTLI, EndOfLog, newTLI);
-
-       /*
-        * Local WAL inserts enabled, so it's time to finish initialization of
-        * commit timestamp.
-        */
-       CompleteCommitTsInitialization();
+       /* WRITE A BETTER COMMENT */
+       XLogAcceptWrites(&awi);
 
        /*
         * All done with end-of-recovery actions.
@@ -5620,10 +5580,59 @@ StartupXLOG(void)
         * back, and in case of a crash, recovering from it might take a longer
         * than is appropriate now that we're not in standby mode anymore.
         */
-       if (performedWalRecovery)
+       if (awi.performedWalRecovery)
                RequestCheckpoint(CHECKPOINT_FORCE);
 }
 
+static void
+XLogAcceptWrites(XLogAcceptWritesInfo *awi)
+{
+       XLogCtlInsert *Insert = &XLogCtl->Insert;
+
+       /* Enable WAL writes for this backend only. */
+       LocalSetXLogInsertAllowed();
+
+       /* If necessary, write overwrite-contrecord before doing anything else */
+       if (!XLogRecPtrIsInvalid(awi->abortedRecPtr))
+       {
+               Assert(!XLogRecPtrIsInvalid(awi->missingContrecPtr));
+               CreateOverwriteContrecordRecord(awi->abortedRecPtr,
+                                                                               awi->missingContrecPtr,
+                                                                               awi->newTLI);
+       }
+
+       /*
+        * Update full_page_writes in shared memory and write an XLOG_FPW_CHANGE
+        * record before resource manager writes cleanup WAL records or checkpoint
+        * record is written.
+        */
+       Insert->fullPageWrites = lastFullPageWrites;
+       UpdateFullPageWrites();
+
+       /*
+        * Emit end-of-recovery record in XLOG, if required.
+        */
+       if (awi->performedWalRecovery)
+               CreateEndOfRecoveryRecord();
+
+       /*
+        * If any of the critical GUCs have changed, log them before we allow
+        * backends to write WAL.
+        */
+       XLogReportParameters();
+
+       /* If this is archive recovery, perform post-recovery cleanup actions. */
+       if (ArchiveRecoveryRequested)
+               CleanupAfterArchiveRecovery(awi->EndOfLogTLI, awi->EndOfLog,
+                                                                       awi->newTLI);
+
+       /*
+        * Local WAL inserts enabled, so it's time to finish initialization of
+        * commit timestamp.
+        */
+       CompleteCommitTsInitialization();
+}
+
 /*
  * Callback from PerformWalRecovery(), called when we switch from crash
  * recovery to archive recovery mode.  Updates the control file accordingly.
index 04091d85760f8ba200aa073e881dbe86928979e0..ab557637c8763b6c8dc185e7d3508657638308aa 100644 (file)
@@ -174,6 +174,16 @@ typedef struct CheckpointStatsData
                                                                         * entire sync phase. */
 } CheckpointStatsData;
 
+typedef struct XLogAcceptWritesInfo
+{
+       bool            performedWalRecovery;
+       XLogRecPtr      abortedRecPtr;
+       XLogRecPtr      missingContrecPtr;
+       XLogRecPtr      EndOfLog;
+       TimeLineID      EndOfLogTLI;
+       TimeLineID      newTLI;
+} XLogAcceptWritesInfo;
+
 extern PGDLLIMPORT CheckpointStatsData CheckpointStats;
 
 /*