Remove InitXLOGAccess().
authorRobert Haas <rhaas@postgresql.org>
Mon, 13 Dec 2021 14:58:36 +0000 (09:58 -0500)
committerRobert Haas <rhaas@postgresql.org>
Mon, 13 Dec 2021 14:58:36 +0000 (09:58 -0500)
It's not great that RecoveryInProgress() calls InitXLOGAccess(),
because a status inquiry function typically shouldn't have the side
effect of performing initializations. We could fix that by calling
InitXLOGAccess() from some other place, but instead, let's remove it
altogether.

One thing InitXLogAccess() did is initialize wal_segment_size, but it
doesn't need to do that. In the postmaster, PostmasterMain() calls
LocalProcessControlFile(), and all child processes will inherit that
value -- except in EXEC_BACKEND bulds, but then each backend runs
SubPostmasterMain() which also calls LocalProcessControlFile().

The other thing InitXLOGAccess() did is update RedoRecPtr and
doPageWrites, but that's not critical, because all code that uses
them will just retry if it turns out that they've changed. The
only difference is that most code will now see an initial value that
is definitely invalid instead of one that might have just been way
out of date, but that will only happen once per backend lifetime,
so it shouldn't be a big deal.

Patch by me, reviewed by Nathan Bossart, Michael Paquier, Andres
Freund, Heikki Linnakangas, and Álvaro Herrera.

Discussion: http://postgr.es/m/CA+TgmoY7b65qRjzHN_tWUk8B4sJqk1vj1d31uepVzmgPnZKeLg@mail.gmail.com

src/backend/access/transam/xlog.c
src/backend/postmaster/auxprocess.c
src/backend/utils/init/postinit.c
src/include/access/xlog.h

index 69cd5e9d426b6e833705ae29c12f29672aa3d78e..72aeb42961f1171e67ae7173caefb8769848f5ea 100644 (file)
@@ -350,8 +350,14 @@ XLogRecPtr XactLastCommitEnd = InvalidXLogRecPtr;
  * XLogCtl->Insert.RedoRecPtr, whenever we can safely do so (ie, when we
  * hold an insertion lock).  See XLogInsertRecord for details.  We are also
  * allowed to update from XLogCtl->RedoRecPtr if we hold the info_lck;
- * see GetRedoRecPtr.  A freshly spawned backend obtains the value during
- * InitXLOGAccess.
+ * see GetRedoRecPtr.
+ *
+ * NB: Code that uses this variable must be prepared not only for the
+ * possibility that it may be arbitrarily out of date, but also for the
+ * possibility that it might be set to InvalidXLogRecPtr. We used to
+ * initialize it as a side effect of the first call to RecoveryInProgress(),
+ * which meant that most code that might use it could assume that it had a
+ * real if perhaps stale value. That's no longer the case.
  */
 static XLogRecPtr RedoRecPtr;
 
@@ -359,6 +365,12 @@ static XLogRecPtr RedoRecPtr;
  * doPageWrites is this backend's local copy of (forcePageWrites ||
  * fullPageWrites).  It is used together with RedoRecPtr to decide whether
  * a full-page image of a page need to be taken.
+ *
+ * NB: Initially this is false, and there's no guarantee that it will be
+ * initialized to any other value before it is first used. Any code that
+ * makes use of it must recheck the value after obtaining a WALInsertLock,
+ * and respond appropriately if it turns out that the previous value wasn't
+ * accurate.
  */
 static bool doPageWrites;
 
@@ -8390,9 +8402,6 @@ PerformRecoveryXLogAction(void)
  *
  * Unlike testing InRecovery, this works in any process that's connected to
  * shared memory.
- *
- * As a side-effect, we initialize the local RedoRecPtr variable the first
- * time we see that recovery is finished.
  */
 bool
 RecoveryInProgress(void)
@@ -8414,23 +8423,6 @@ RecoveryInProgress(void)
 
                LocalRecoveryInProgress = (xlogctl->SharedRecoveryState != RECOVERY_STATE_DONE);
 
-               /*
-                * Initialize TimeLineID and RedoRecPtr when we discover that recovery
-                * is finished. InitPostgres() relies upon this behaviour to ensure
-                * that InitXLOGAccess() is called at backend startup.  (If you change
-                * this, see also LocalSetXLogInsertAllowed.)
-                */
-               if (!LocalRecoveryInProgress)
-               {
-                       /*
-                        * If we just exited recovery, make sure we read TimeLineID and
-                        * RedoRecPtr after SharedRecoveryState (for machines with weak
-                        * memory ordering).
-                        */
-                       pg_memory_barrier();
-                       InitXLOGAccess();
-               }
-
                /*
                 * Note: We don't need a memory barrier when we're still in recovery.
                 * We might exit recovery immediately after return, so the caller
@@ -8547,9 +8539,6 @@ LocalSetXLogInsertAllowed(void)
 
        LocalXLogInsertAllowed = 1;
 
-       /* Initialize as RecoveryInProgress() would do when switching state */
-       InitXLOGAccess();
-
        return oldXLogAllowed;
 }
 
@@ -8656,25 +8645,6 @@ ReadCheckpointRecord(XLogReaderState *xlogreader, XLogRecPtr RecPtr,
        return record;
 }
 
-/*
- * This must be called in a backend process before creating WAL records
- * (except in a standalone backend, which does StartupXLOG instead).  We need
- * to initialize the local copy of RedoRecPtr.
- */
-void
-InitXLOGAccess(void)
-{
-       XLogCtlInsert *Insert = &XLogCtl->Insert;
-
-       /* set wal_segment_size */
-       wal_segment_size = ControlFile->xlog_seg_size;
-
-       /* Use GetRedoRecPtr to copy the RedoRecPtr safely */
-       (void) GetRedoRecPtr();
-       /* Also update our copy of doPageWrites. */
-       doPageWrites = (Insert->fullPageWrites || Insert->forcePageWrites);
-}
-
 /*
  * Return the current Redo pointer from shared memory.
  *
@@ -8706,8 +8676,9 @@ GetRedoRecPtr(void)
  * full-page image to be included in the WAL record.
  *
  * The returned values are cached copies from backend-private memory, and
- * possibly out-of-date.  XLogInsertRecord will re-check them against
- * up-to-date values, while holding the WAL insert lock.
+ * possibly out-of-date or, indeed, uninitalized, in which case they will
+ * be InvalidXLogRecPtr and false, respectively.  XLogInsertRecord will
+ * re-check them against up-to-date values, while holding the WAL insert lock.
  */
 void
 GetFullPageWriteInfo(XLogRecPtr *RedoRecPtr_p, bool *doPageWrites_p)
index 7452f908b234e234a908ff4767b90a4511191d1c..43497676ab1e6a31ba22c1edbb505cb97737ea0e 100644 (file)
@@ -154,7 +154,6 @@ AuxiliaryProcessMain(AuxProcType auxtype)
                        proc_exit(1);
 
                case WalWriterProcess:
-                       InitXLOGAccess();
                        WalWriterMain();
                        proc_exit(1);
 
index 646126edee57d240451502711d60c07a4528133c..7292e51f7de902187b5f1643e2b96c951c791a8d 100644 (file)
@@ -624,25 +624,14 @@ InitPostgres(const char *in_dbname, Oid dboid, const char *username,
        }
 
        /*
-        * Initialize local process's access to XLOG.
+        * If this is either a bootstrap process nor a standalone backend, start
+        * up the XLOG machinery, and register to have it closed down at exit.
+        * In other cases, the startup process is responsible for starting up
+        * the XLOG machinery, and the checkpointer for closing it down.
         */
-       if (IsUnderPostmaster)
-       {
-               /*
-                * The postmaster already started the XLOG machinery, but we need to
-                * call InitXLOGAccess(), if the system isn't in hot-standby mode.
-                * This is handled by calling RecoveryInProgress and ignoring the
-                * result.
-                */
-               (void) RecoveryInProgress();
-       }
-       else
+       if (!IsUnderPostmaster)
        {
                /*
-                * We are either a bootstrap process or a standalone backend. Either
-                * way, start up the XLOG machinery, and register to have it closed
-                * down at exit.
-                *
                 * We don't yet have an aux-process resource owner, but StartupXLOG
                 * and ShutdownXLOG will need one.  Hence, create said resource owner
                 * (and register a callback to clean it up after ShutdownXLOG runs).
index 898df2ee034307c86c77d7a7a59145e972ce2319..34f6c89f0671774aa1b4fe5f061a285a8495b07d 100644 (file)
@@ -299,7 +299,6 @@ extern void BootStrapXLOG(void);
 extern void LocalProcessControlFile(bool reset);
 extern void StartupXLOG(void);
 extern void ShutdownXLOG(int code, Datum arg);
-extern void InitXLOGAccess(void);
 extern void CreateCheckPoint(int flags);
 extern bool CreateRestartPoint(int flags);
 extern WALAvailability GetWALAvailability(XLogRecPtr targetLSN);