From 18e0913a420349d373cfd8e45b91b4777501fb74 Mon Sep 17 00:00:00 2001 From: Robert Haas Date: Mon, 25 Oct 2021 10:16:28 -0400 Subject: [PATCH] StartupXLOG: Don't repeatedly disable/enable local xlog insertion. All the code that runs in the startup process to write WAL records before that's allowed generally is now consecutive, so there's no reason to shut the facility to write WAL locally off and then turn it on again three times in a row. Unfortunately, this requires a slight kludge in the checkpointer, which needs to separately enable writing WAL in order to write the checkpoint record. Because that code might run in the same process as StartupXLOG() if we are in single-user mode, we must save/restore the state of the LocalXLogInsertAllowed flag. Hopefully, we'll be able to eliminate this wart in further refactoring, but it's not too bad anyway. Amul Sul, with modifications by me. Discussion: http://postgr.es/m/CAAJ_b97fysj6sRSQEfOHj-y8Jfd5uPqOgO74qast89B4WfD+TA@mail.gmail.com --- src/backend/access/transam/xlog.c | 23 ++++++++++++----------- 1 file changed, 12 insertions(+), 11 deletions(-) diff --git a/src/backend/access/transam/xlog.c b/src/backend/access/transam/xlog.c index 1215776672..142506834c 100644 --- a/src/backend/access/transam/xlog.c +++ b/src/backend/access/transam/xlog.c @@ -905,7 +905,7 @@ static void checkTimeLineSwitch(XLogRecPtr lsn, TimeLineID newTLI, TimeLineID prevTLI); static void VerifyOverwriteContrecord(xl_overwrite_contrecord *xlrec, XLogReaderState *state); -static void LocalSetXLogInsertAllowed(void); +static int LocalSetXLogInsertAllowed(void); static void CreateEndOfRecoveryRecord(void); static XLogRecPtr CreateOverwriteContrecordRecord(XLogRecPtr aborted_lsn); static void CheckPointGuts(XLogRecPtr checkPointRedo, int flags); @@ -8062,6 +8062,7 @@ StartupXLOG(void) } XLogReaderFree(xlogreader); + /* Enable WAL writes for this backend only. */ LocalSetXLogInsertAllowed(); /* If necessary, write overwrite-contrecord before doing anything else */ @@ -8080,7 +8081,6 @@ StartupXLOG(void) */ Insert->fullPageWrites = lastFullPageWrites; UpdateFullPageWrites(); - LocalXLogInsertAllowed = -1; /* * Emit checkpoint or end-of-recovery record in XLOG, if required. @@ -8098,7 +8098,6 @@ StartupXLOG(void) * If any of the critical GUCs have changed, log them before we allow * backends to write WAL. */ - LocalSetXLogInsertAllowed(); XLogReportParameters(); /* If this is archive recovery, perform post-recovery cleanup actions. */ @@ -8467,15 +8466,20 @@ XLogInsertAllowed(void) * * Note: it is allowed to switch LocalXLogInsertAllowed back to -1 later, * and even call LocalSetXLogInsertAllowed() again after that. + * + * Returns the previous value of LocalXLogInsertAllowed. */ -static void +static int LocalSetXLogInsertAllowed(void) { - Assert(LocalXLogInsertAllowed == -1); + int oldXLogAllowed = LocalXLogInsertAllowed; + LocalXLogInsertAllowed = 1; /* Initialize as RecoveryInProgress() would do when switching state */ InitXLOGAccess(); + + return oldXLogAllowed; } /* @@ -9020,6 +9024,7 @@ CreateCheckPoint(int flags) XLogRecPtr last_important_lsn; VirtualTransactionId *vxids; int nvxids; + int oldXLogAllowed; /* * An end-of-recovery checkpoint is really a shutdown checkpoint, just @@ -9127,7 +9132,7 @@ CreateCheckPoint(int flags) * initialized, which we need here and in AdvanceXLInsertBuffer.) */ if (flags & CHECKPOINT_END_OF_RECOVERY) - LocalSetXLogInsertAllowed(); + oldXLogAllowed = LocalSetXLogInsertAllowed(); checkPoint.ThisTimeLineID = ThisTimeLineID; if (flags & CHECKPOINT_END_OF_RECOVERY) @@ -9307,7 +9312,7 @@ CreateCheckPoint(int flags) if (shutdown) { if (flags & CHECKPOINT_END_OF_RECOVERY) - LocalXLogInsertAllowed = -1; /* return to "check" state */ + LocalXLogInsertAllowed = oldXLogAllowed; else LocalXLogInsertAllowed = 0; /* never again write WAL */ } @@ -9447,8 +9452,6 @@ CreateEndOfRecoveryRecord(void) xlrec.PrevTimeLineID = XLogCtl->PrevTimeLineID; WALInsertLockRelease(); - LocalSetXLogInsertAllowed(); - START_CRIT_SECTION(); XLogBeginInsert(); @@ -9469,8 +9472,6 @@ CreateEndOfRecoveryRecord(void) LWLockRelease(ControlFileLock); END_CRIT_SECTION(); - - LocalXLogInsertAllowed = -1; /* return to "check" state */ } /*