Add GetWALInsertionTimeLine(); also return it via GetFlushRecPtr().
authorRobert Haas <[email protected]>
Fri, 29 Oct 2021 20:03:16 +0000 (16:03 -0400)
committerRobert Haas <[email protected]>
Fri, 29 Oct 2021 21:05:21 +0000 (17:05 -0400)
Having lots of code that relies on the ThisTimeLineID global variable
is problematic, but to have any chance of fixing that, we must provide
another way for code outside xlog.c to get the relevant value. This
commit adds infrastructure for doing that on a system that is in
normal running, but doesn't do anything about the case where the
system is in recovery.

Here, we provide two different methods for getting the timeline of
a system in normal running. First, a number of the places where we
call GetFlushRecPtr() need the timeline as well, so provide it via
an out parameter. Second, for other places that just need the
timeline and not any LSN, add a GetWALInsertionTimeLine() function.

Future commits will take care of actually removing references to
ThisTimeLineID; this commit is just infrastructure.

src/backend/access/transam/xlog.c
src/backend/access/transam/xlogfuncs.c
src/backend/access/transam/xlogutils.c
src/backend/replication/logical/logicalfuncs.c
src/backend/replication/logical/worker.c
src/backend/replication/slotfuncs.c
src/backend/replication/walsender.c
src/include/access/xlog.h

index f547efd2944172ea7c2258006dfa5436d0088e7d..6070e0f3b3fb17e9be3e7db178d2406d1ad599e8 100644 (file)
@@ -8695,15 +8695,35 @@ GetInsertRecPtr(void)
  * position known to be fsync'd to disk.
  */
 XLogRecPtr
-GetFlushRecPtr(void)
+GetFlushRecPtr(TimeLineID *insertTLI)
 {
        SpinLockAcquire(&XLogCtl->info_lck);
        LogwrtResult = XLogCtl->LogwrtResult;
        SpinLockRelease(&XLogCtl->info_lck);
 
+       /*
+        * If we're writing and flushing WAL, the time line can't be changing,
+        * so no lock is required.
+        */
+       if (insertTLI)
+               *insertTLI = XLogCtl->ThisTimeLineID;
+
        return LogwrtResult.Flush;
 }
 
+/*
+ * GetWALInsertionTimeLine -- Returns the current timeline of a system that
+ * is not in recovery.
+ */
+TimeLineID
+GetWALInsertionTimeLine(void)
+{
+       Assert(XLogCtl->SharedRecoveryState == RECOVERY_STATE_DONE);
+
+       /* Since the value can't be changing, no lock is required. */
+       return XLogCtl->ThisTimeLineID;
+}
+
 /*
  * GetLastImportantRecPtr -- Returns the LSN of the last important record
  * inserted. All records not explicitly marked as unimportant are considered
index b98deb72ec69dee4d61f0e894a3af3b0c1b9d12d..5bebcc50dde3b63f1e0cc663fb1bede56b78f87a 100644 (file)
@@ -382,7 +382,7 @@ pg_current_wal_flush_lsn(PG_FUNCTION_ARGS)
                                 errmsg("recovery is in progress"),
                                 errhint("WAL control functions cannot be executed during recovery.")));
 
-       current_recptr = GetFlushRecPtr();
+       current_recptr = GetFlushRecPtr(NULL);
 
        PG_RETURN_LSN(current_recptr);
 }
index 88a1bfd9394aaa0513b69b98a662c5e834184788..c40500a6f2bad0f0b96fbc98a128169dfd829a5c 100644 (file)
@@ -862,13 +862,9 @@ read_local_xlog_page(XLogReaderState *state, XLogRecPtr targetPagePtr,
                /*
                 * Determine the limit of xlog we can currently read to, and what the
                 * most recent timeline is.
-                *
-                * RecoveryInProgress() will update ThisTimeLineID when it first
-                * notices recovery finishes, so we only have to maintain it for the
-                * local process until recovery ends.
                 */
                if (!RecoveryInProgress())
-                       read_upto = GetFlushRecPtr();
+                       read_upto = GetFlushRecPtr(&ThisTimeLineID);
                else
                        read_upto = GetXLogReplayRecPtr(&ThisTimeLineID);
                tli = ThisTimeLineID;
index 5a7fae4a87d3a954a231d1320b2cd0469b9a856e..2609a0a71048bcea357100baa9df32eabafb1ab5 100644 (file)
@@ -211,7 +211,7 @@ pg_logical_slot_get_changes_guts(FunctionCallInfo fcinfo, bool confirm, bool bin
         * Compute the current end-of-wal.
         */
        if (!RecoveryInProgress())
-               end_of_wal = GetFlushRecPtr();
+               end_of_wal = GetFlushRecPtr(NULL);
        else
                end_of_wal = GetXLogReplayRecPtr(NULL);
 
index 8d96c926b4f2e35ba5fed9fd30422f7712569487..0bd5d0ee5e08bf80ec86121817f3d1c23846f375 100644 (file)
@@ -2435,7 +2435,7 @@ get_flush_position(XLogRecPtr *write, XLogRecPtr *flush,
                                   bool *have_pending_txes)
 {
        dlist_mutable_iter iter;
-       XLogRecPtr      local_flush = GetFlushRecPtr();
+       XLogRecPtr      local_flush = GetFlushRecPtr(NULL);
 
        *write = InvalidXLogRecPtr;
        *flush = InvalidXLogRecPtr;
index 877a006d50332bb8b4e4e7375864dcfe04b7e495..a80298ba53dea2966c6c17a57733611e365c4e23 100644 (file)
@@ -625,7 +625,7 @@ pg_replication_slot_advance(PG_FUNCTION_ARGS)
         * target position accordingly.
         */
        if (!RecoveryInProgress())
-               moveto = Min(moveto, GetFlushRecPtr());
+               moveto = Min(moveto, GetFlushRecPtr(NULL));
        else
                moveto = Min(moveto, GetXLogReplayRecPtr(NULL));
 
index d9ab6d6de241a930ee3af79e28e1884b0e816c7b..d09bffaa9dc03ca401296e20922589be6f78d262 100644 (file)
@@ -402,7 +402,7 @@ IdentifySystem(void)
                logptr = GetStandbyFlushRecPtr();
        }
        else
-               logptr = GetFlushRecPtr();
+               logptr = GetFlushRecPtr(&ThisTimeLineID);
 
        snprintf(xloc, sizeof(xloc), "%X/%X", LSN_FORMAT_ARGS(logptr));
 
@@ -720,7 +720,7 @@ StartReplication(StartReplicationCmd *cmd)
                FlushPtr = GetStandbyFlushRecPtr();
        }
        else
-               FlushPtr = GetFlushRecPtr();
+               FlushPtr = GetFlushRecPtr(&ThisTimeLineID);
 
        if (cmd->timeline != 0)
        {
@@ -1487,7 +1487,7 @@ WalSndWaitForWal(XLogRecPtr loc)
 
        /* Get a more recent flush pointer. */
        if (!RecoveryInProgress())
-               RecentFlushPtr = GetFlushRecPtr();
+               RecentFlushPtr = GetFlushRecPtr(NULL);
        else
                RecentFlushPtr = GetXLogReplayRecPtr(NULL);
 
@@ -1521,7 +1521,7 @@ WalSndWaitForWal(XLogRecPtr loc)
 
                /* Update our idea of the currently flushed position. */
                if (!RecoveryInProgress())
-                       RecentFlushPtr = GetFlushRecPtr();
+                       RecentFlushPtr = GetFlushRecPtr(NULL);
                else
                        RecentFlushPtr = GetXLogReplayRecPtr(NULL);
 
@@ -2756,7 +2756,7 @@ XLogSendPhysical(void)
                 * primary: if the primary subsequently crashes and restarts, standbys
                 * must not have applied any WAL that got lost on the primary.
                 */
-               SendRqstPtr = GetFlushRecPtr();
+               SendRqstPtr = GetFlushRecPtr(NULL);
        }
 
        /*
@@ -2997,9 +2997,9 @@ XLogSendLogical(void)
         * we only need to update flushPtr if EndRecPtr is past it.
         */
        if (flushPtr == InvalidXLogRecPtr)
-               flushPtr = GetFlushRecPtr();
+               flushPtr = GetFlushRecPtr(NULL);
        else if (logical_decoding_ctx->reader->EndRecPtr >= flushPtr)
-               flushPtr = GetFlushRecPtr();
+               flushPtr = GetFlushRecPtr(NULL);
 
        /* If EndRecPtr is still past our flushPtr, it means we caught up. */
        if (logical_decoding_ctx->reader->EndRecPtr >= flushPtr)
index 5e2c94a05ff15d73917cc5cc322a7c87e250be97..72417f44b660659929755459ef441ff16e987603 100644 (file)
@@ -312,7 +312,8 @@ extern void UpdateFullPageWrites(void);
 extern void GetFullPageWriteInfo(XLogRecPtr *RedoRecPtr_p, bool *doPageWrites_p);
 extern XLogRecPtr GetRedoRecPtr(void);
 extern XLogRecPtr GetInsertRecPtr(void);
-extern XLogRecPtr GetFlushRecPtr(void);
+extern XLogRecPtr GetFlushRecPtr(TimeLineID *insertTLI);
+extern TimeLineID GetWALInsertionTimeLine(void);
 extern XLogRecPtr GetLastImportantRecPtr(void);
 extern void RemovePromoteSignalFiles(void);