From b0d1790e5aa95a02217efb4e635398d3086a7493 Mon Sep 17 00:00:00 2001 From: Robert Haas Date: Fri, 23 Jul 2021 14:27:51 -0400 Subject: [PATCH v38 2/4] Postpone some end-of-recovery operations relating to allowing WAL. Previously, moved the code that performs whether to write a checkpoint or an end-of-recovery record into PerformRecoveryXlogAction(), and code performs post-archive-recovery into CleanupAfterArchiveRecovery(), but called both the functions from the same place. Now postpone that stuff until after we clear InRecovery and shut down the XLogReader. We do find out of InRecovery value afterward by looking XLogCtl->lastReplayedEndRecPtr, that will be only get set inside the REDO loop. 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. The steps that themselves write WAL clearly shouldn't happen before we're ready to accept WAL writes, and it seems best for now to keep the steps performed by CleanupAfterArchiveRecovery() at the same point relative to the surrounding steps. We assume (hopefully correctly) that the user doesn't want recovery_end_command to run until we're committed to writing WAL on the new timeline. Until then, the machine is still usable as a standby on the old timeline. Aside from the value of this patch as preparatory work, this order of operations actually seems more logical, since it means we don't actually write any WAL until after exiting recovery. Robert Haas, with modifications by Amul Sul. --- src/backend/access/transam/xlog.c | 62 +++++++++++++++++-------------- 1 file changed, 34 insertions(+), 28 deletions(-) diff --git a/src/backend/access/transam/xlog.c b/src/backend/access/transam/xlog.c index 44e5a0610ef..6612b81e4b9 100644 --- a/src/backend/access/transam/xlog.c +++ b/src/backend/access/transam/xlog.c @@ -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,40 @@ 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 the server has been + * through the archive or the crash recovery. + * + * If the recovery is performed lastReplayedEndRecPtr will always be a valid + * record pointer that never changes after REDO loop. + */ + 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. -- 2.18.0