Postpone some end-of-recovery operations related to allowing WAL.

CreateOverwriteContrecordRecord(), UpdateFullPageWrites(),
PerformRecoveryXLogAction(), and CleanupAfterArchiveRecovery()
are moved somewhat later in StartupXLOG(). This is preparatory
work for a future patch that wants to allow recovery to end at one
time and only later start to allow WAL writes. To do that, it's
necessary to separate code that has to do with allowing WAL writes
from other things that need to happen simply because recovery is
ending, such as initializing shared memory data structures that
depend on information that might not be accurate before redo is
complete.

This commit does not achieve that goal, but it is a step in that
direction.  For example, there are a few different bits of code that
write things into WAL once we have finished recovery, and with this
change, those bits of code are closer to each other than previously,
with fewer unrelated bits of code interspersed.

Robert Haas and Amul Sul

Discussion: http://postgr.es/m/CAAJ_b97abMuq=470Wahun=aS1PHTSbStHtrjjPaD-C0YQ1AqVw@mail.gmail.com
This commit is contained in:
Robert Haas 2021-10-14 11:55:50 -04:00
parent 010e523373
commit 811051c2e7
1 changed files with 36 additions and 28 deletions

View File

@ -8018,34 +8018,6 @@ StartupXLOG(void)
XLogCtl->LogwrtRqst.Write = EndOfLog;
XLogCtl->LogwrtRqst.Flush = EndOfLog;
LocalSetXLogInsertAllowed();
/* If necessary, write overwrite-contrecord before doing anything else */
if (!XLogRecPtrIsInvalid(abortedRecPtr))
{
Assert(!XLogRecPtrIsInvalid(missingContrecPtr));
CreateOverwriteContrecordRecord(abortedRecPtr);
abortedRecPtr = InvalidXLogRecPtr;
missingContrecPtr = InvalidXLogRecPtr;
}
/*
* 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();
LocalXLogInsertAllowed = -1;
/* Emit checkpoint or end-of-recovery record in XLOG, if required. */
if (InRecovery)
promoted = PerformRecoveryXLogAction();
/* If this is archive recovery, perform post-recovery cleanup actions. */
if (ArchiveRecoveryRequested)
CleanupAfterArchiveRecovery(EndOfLogTLI, EndOfLog);
/*
* Preallocate additional log files, if wanted.
*/
@ -8090,6 +8062,42 @@ StartupXLOG(void)
}
XLogReaderFree(xlogreader);
LocalSetXLogInsertAllowed();
/* If necessary, write overwrite-contrecord before doing anything else */
if (!XLogRecPtrIsInvalid(abortedRecPtr))
{
Assert(!XLogRecPtrIsInvalid(missingContrecPtr));
CreateOverwriteContrecordRecord(abortedRecPtr);
abortedRecPtr = InvalidXLogRecPtr;
missingContrecPtr = InvalidXLogRecPtr;
}
/*
* 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();
LocalXLogInsertAllowed = -1;
/*
* Emit checkpoint or end-of-recovery record in XLOG, if required.
*
* XLogCtl->lastReplayedEndRecPtr will be a valid LSN if and only if we
* entered recovery. Even if we ultimately replayed no WAL records, it will
* have been initialized based on where replay was due to start. We don't
* need a lock to access this, since this can't change any more by the time
* we reach this code.
*/
if (!XLogRecPtrIsInvalid(XLogCtl->lastReplayedEndRecPtr))
promoted = PerformRecoveryXLogAction();
/* If this is archive recovery, perform post-recovery cleanup actions. */
if (ArchiveRecoveryRequested)
CleanupAfterArchiveRecovery(EndOfLogTLI, EndOfLog);
/*
* If any of the critical GUCs have changed, log them before we allow
* backends to write WAL.