Remove previous timeline ID from checkpoint.
authorRobert Haas <[email protected]>
Mon, 18 Apr 2022 20:01:13 +0000 (16:01 -0400)
committerRobert Haas <[email protected]>
Tue, 19 Apr 2022 12:26:12 +0000 (08:26 -0400)
Since recovery now always ends with an end-of-recovery record rather
than a checkpoint, a checkpoint never causes a timeline switch.
Therefore, it doesn't need to store a previous timeline ID and a
current timeline ID any more.

Note that this affects the signature of the SQL-callable function
pg_control_checkpoint().

doc/src/sgml/func.sgml
src/backend/access/rmgrdesc/xlogdesc.c
src/backend/access/transam/xlog.c
src/backend/access/transam/xlogrecovery.c
src/backend/utils/misc/pg_controldata.c
src/bin/pg_controldata/pg_controldata.c
src/bin/pg_resetwal/pg_resetwal.c
src/include/catalog/pg_control.h
src/include/catalog/pg_proc.dat

index 489184a4f043810a4fa385cdf320944f21578b47..f8516b5475414371b60e51e1a70958e7421dbc83 100644 (file)
@@ -27626,11 +27626,6 @@ SELECT collation for ('foo' COLLATE "de_DE");
        <entry><type>integer</type></entry>
       </row>
 
-      <row>
-       <entry><structfield>prev_timeline_id</structfield></entry>
-       <entry><type>integer</type></entry>
-      </row>
-
       <row>
        <entry><structfield>full_page_writes</structfield></entry>
        <entry><type>boolean</type></entry>
index c0dfea40c70f3b209760f0ca0d95518b93c65179..a3e29b043fb6c064286dff921cdb704aeae0e743 100644 (file)
@@ -45,13 +45,12 @@ xlog_desc(StringInfo buf, XLogReaderState *record)
                CheckPoint *checkpoint = (CheckPoint *) rec;
 
                appendStringInfo(buf, "redo %X/%X; "
-                                                "tli %u; prev tli %u; fpw %s; xid %u:%u; oid %u; multi %u; offset %u; "
+                                                "tli %u; fpw %s; xid %u:%u; oid %u; multi %u; offset %u; "
                                                 "oldest xid %u in DB %u; oldest multi %u in DB %u; "
                                                 "oldest/newest commit timestamp xid: %u/%u; "
                                                 "oldest running xid %u; %s",
                                                 LSN_FORMAT_ARGS(checkpoint->redo),
                                                 checkpoint->ThisTimeLineID,
-                                                checkpoint->PrevTimeLineID,
                                                 checkpoint->fullPageWrites ? "true" : "false",
                                                 EpochFromFullTransactionId(checkpoint->nextXid),
                                                 XidFromFullTransactionId(checkpoint->nextXid),
index 420e93bed3ac24dc1eaa765a41641ce08f1fbcbf..912a913b64731b522f62870123149f2fe3ab60ab 100644 (file)
@@ -4539,7 +4539,6 @@ BootStrapXLOG(void)
         */
        checkPoint.redo = wal_segment_size + SizeOfXLogLongPHD;
        checkPoint.ThisTimeLineID = BootstrapTimeLineID;
-       checkPoint.PrevTimeLineID = BootstrapTimeLineID;
        checkPoint.fullPageWrites = fullPageWrites;
        checkPoint.nextXid = starting_fxid;
        checkPoint.nextOid = FirstGenbkiObjectId;
@@ -6307,7 +6306,6 @@ CreateCheckPoint(int flags)
        }
 
        checkPoint.ThisTimeLineID = XLogCtl->InsertTimeLineID;
-       checkPoint.PrevTimeLineID = checkPoint.ThisTimeLineID;
 
        checkPoint.fullPageWrites = Insert->fullPageWrites;
 
index 39ef865ed92997d5b37ac9b4a6f5c3ad2863a16f..14a3ee96a3387c5993f3fa67f0fc95dbfeaf0796 100644 (file)
@@ -1833,36 +1833,28 @@ ApplyWalRecord(XLogReaderState *xlogreader, XLogRecord *record, TimeLineID *repl
         */
        if (record->xl_rmid == RM_XLOG_ID)
        {
-               TimeLineID      newReplayTLI = *replayTLI;
-               TimeLineID      prevReplayTLI = *replayTLI;
                uint8           info = record->xl_info & ~XLR_INFO_MASK;
 
-               if (info == XLOG_CHECKPOINT_SHUTDOWN)
-               {
-                       CheckPoint      checkPoint;
-
-                       memcpy(&checkPoint, XLogRecGetData(xlogreader), sizeof(CheckPoint));
-                       newReplayTLI = checkPoint.ThisTimeLineID;
-                       prevReplayTLI = checkPoint.PrevTimeLineID;
-               }
-               else if (info == XLOG_END_OF_RECOVERY)
+               if (info == XLOG_END_OF_RECOVERY)
                {
                        xl_end_of_recovery xlrec;
+                       TimeLineID      newReplayTLI;
+                       TimeLineID      prevReplayTLI;
 
                        memcpy(&xlrec, XLogRecGetData(xlogreader), sizeof(xl_end_of_recovery));
                        newReplayTLI = xlrec.ThisTimeLineID;
                        prevReplayTLI = xlrec.PrevTimeLineID;
-               }
 
-               if (newReplayTLI != *replayTLI)
-               {
-                       /* Check that it's OK to switch to this TLI */
-                       checkTimeLineSwitch(xlogreader->EndRecPtr,
-                                                               newReplayTLI, prevReplayTLI, *replayTLI);
+                       if (newReplayTLI != *replayTLI)
+                       {
+                               /* Check that it's OK to switch to this TLI */
+                               checkTimeLineSwitch(xlogreader->EndRecPtr,
+                                                                       newReplayTLI, prevReplayTLI, *replayTLI);
 
-                       /* Following WAL records should be run with new TLI */
-                       *replayTLI = newReplayTLI;
-                       switchedTLI = true;
+                               /* Following WAL records should be run with new TLI */
+                               *replayTLI = newReplayTLI;
+                               switchedTLI = true;
+                       }
                }
        }
 
index 781f8b8758097da122d5c4d3689c113fb8406d8e..c30f380d0795da6f1a9a9e2f76cdc553f4126aef 100644 (file)
@@ -101,33 +101,31 @@ pg_control_checkpoint(PG_FUNCTION_ARGS)
                                           TEXTOID, -1, 0);
        TupleDescInitEntry(tupdesc, (AttrNumber) 4, "timeline_id",
                                           INT4OID, -1, 0);
-       TupleDescInitEntry(tupdesc, (AttrNumber) 5, "prev_timeline_id",
-                                          INT4OID, -1, 0);
-       TupleDescInitEntry(tupdesc, (AttrNumber) 6, "full_page_writes",
+       TupleDescInitEntry(tupdesc, (AttrNumber) 5, "full_page_writes",
                                           BOOLOID, -1, 0);
-       TupleDescInitEntry(tupdesc, (AttrNumber) 7, "next_xid",
+       TupleDescInitEntry(tupdesc, (AttrNumber) 6, "next_xid",
                                           TEXTOID, -1, 0);
-       TupleDescInitEntry(tupdesc, (AttrNumber) 8, "next_oid",
+       TupleDescInitEntry(tupdesc, (AttrNumber) 7, "next_oid",
                                           OIDOID, -1, 0);
-       TupleDescInitEntry(tupdesc, (AttrNumber) 9, "next_multixact_id",
+       TupleDescInitEntry(tupdesc, (AttrNumber) 8, "next_multixact_id",
                                           XIDOID, -1, 0);
-       TupleDescInitEntry(tupdesc, (AttrNumber) 10, "next_multi_offset",
+       TupleDescInitEntry(tupdesc, (AttrNumber) 9, "next_multi_offset",
                                           XIDOID, -1, 0);
-       TupleDescInitEntry(tupdesc, (AttrNumber) 11, "oldest_xid",
+       TupleDescInitEntry(tupdesc, (AttrNumber) 10, "oldest_xid",
                                           XIDOID, -1, 0);
-       TupleDescInitEntry(tupdesc, (AttrNumber) 12, "oldest_xid_dbid",
+       TupleDescInitEntry(tupdesc, (AttrNumber) 11, "oldest_xid_dbid",
                                           OIDOID, -1, 0);
-       TupleDescInitEntry(tupdesc, (AttrNumber) 13, "oldest_active_xid",
+       TupleDescInitEntry(tupdesc, (AttrNumber) 12, "oldest_active_xid",
                                           XIDOID, -1, 0);
-       TupleDescInitEntry(tupdesc, (AttrNumber) 14, "oldest_multi_xid",
+       TupleDescInitEntry(tupdesc, (AttrNumber) 13, "oldest_multi_xid",
                                           XIDOID, -1, 0);
-       TupleDescInitEntry(tupdesc, (AttrNumber) 15, "oldest_multi_dbid",
+       TupleDescInitEntry(tupdesc, (AttrNumber) 14, "oldest_multi_dbid",
                                           OIDOID, -1, 0);
-       TupleDescInitEntry(tupdesc, (AttrNumber) 16, "oldest_commit_ts_xid",
+       TupleDescInitEntry(tupdesc, (AttrNumber) 15, "oldest_commit_ts_xid",
                                           XIDOID, -1, 0);
-       TupleDescInitEntry(tupdesc, (AttrNumber) 17, "newest_commit_ts_xid",
+       TupleDescInitEntry(tupdesc, (AttrNumber) 16, "newest_commit_ts_xid",
                                           XIDOID, -1, 0);
-       TupleDescInitEntry(tupdesc, (AttrNumber) 18, "checkpoint_time",
+       TupleDescInitEntry(tupdesc, (AttrNumber) 17, "checkpoint_time",
                                           TIMESTAMPTZOID, -1, 0);
        tupdesc = BlessTupleDesc(tupdesc);
 
@@ -158,50 +156,47 @@ pg_control_checkpoint(PG_FUNCTION_ARGS)
        values[3] = Int32GetDatum(ControlFile->checkPointCopy.ThisTimeLineID);
        nulls[3] = false;
 
-       values[4] = Int32GetDatum(ControlFile->checkPointCopy.PrevTimeLineID);
+       values[4] = BoolGetDatum(ControlFile->checkPointCopy.fullPageWrites);
        nulls[4] = false;
 
-       values[5] = BoolGetDatum(ControlFile->checkPointCopy.fullPageWrites);
-       nulls[5] = false;
-
-       values[6] = CStringGetTextDatum(psprintf("%u:%u",
+       values[5] = CStringGetTextDatum(psprintf("%u:%u",
                                                                                         EpochFromFullTransactionId(ControlFile->checkPointCopy.nextXid),
                                                                                         XidFromFullTransactionId(ControlFile->checkPointCopy.nextXid)));
+       nulls[5] = false;
+
+       values[6] = ObjectIdGetDatum(ControlFile->checkPointCopy.nextOid);
        nulls[6] = false;
 
-       values[7] = ObjectIdGetDatum(ControlFile->checkPointCopy.nextOid);
+       values[7] = TransactionIdGetDatum(ControlFile->checkPointCopy.nextMulti);
        nulls[7] = false;
 
-       values[8] = TransactionIdGetDatum(ControlFile->checkPointCopy.nextMulti);
+       values[8] = TransactionIdGetDatum(ControlFile->checkPointCopy.nextMultiOffset);
        nulls[8] = false;
 
-       values[9] = TransactionIdGetDatum(ControlFile->checkPointCopy.nextMultiOffset);
+       values[9] = TransactionIdGetDatum(ControlFile->checkPointCopy.oldestXid);
        nulls[9] = false;
 
-       values[10] = TransactionIdGetDatum(ControlFile->checkPointCopy.oldestXid);
+       values[10] = ObjectIdGetDatum(ControlFile->checkPointCopy.oldestXidDB);
        nulls[10] = false;
 
-       values[11] = ObjectIdGetDatum(ControlFile->checkPointCopy.oldestXidDB);
+       values[11] = TransactionIdGetDatum(ControlFile->checkPointCopy.oldestActiveXid);
        nulls[11] = false;
 
-       values[12] = TransactionIdGetDatum(ControlFile->checkPointCopy.oldestActiveXid);
+       values[12] = TransactionIdGetDatum(ControlFile->checkPointCopy.oldestMulti);
        nulls[12] = false;
 
-       values[13] = TransactionIdGetDatum(ControlFile->checkPointCopy.oldestMulti);
+       values[13] = ObjectIdGetDatum(ControlFile->checkPointCopy.oldestMultiDB);
        nulls[13] = false;
 
-       values[14] = ObjectIdGetDatum(ControlFile->checkPointCopy.oldestMultiDB);
+       values[14] = TransactionIdGetDatum(ControlFile->checkPointCopy.oldestCommitTsXid);
        nulls[14] = false;
 
-       values[15] = TransactionIdGetDatum(ControlFile->checkPointCopy.oldestCommitTsXid);
+       values[15] = TransactionIdGetDatum(ControlFile->checkPointCopy.newestCommitTsXid);
        nulls[15] = false;
 
-       values[16] = TransactionIdGetDatum(ControlFile->checkPointCopy.newestCommitTsXid);
+       values[16] = TimestampTzGetDatum(time_t_to_timestamptz(ControlFile->checkPointCopy.time));
        nulls[16] = false;
 
-       values[17] = TimestampTzGetDatum(time_t_to_timestamptz(ControlFile->checkPointCopy.time));
-       nulls[17] = false;
-
        htup = heap_form_tuple(tupdesc, values, nulls);
 
        PG_RETURN_DATUM(HeapTupleGetDatum(htup));
index c390ec51ce9b427da2d17328a4944b65e9018897..56dc8d0031887c282e339bf5f1810542a1a6a53b 100644 (file)
@@ -243,8 +243,6 @@ main(int argc, char *argv[])
                   xlogfilename);
        printf(_("Latest checkpoint's TimeLineID:       %u\n"),
                   ControlFile->checkPointCopy.ThisTimeLineID);
-       printf(_("Latest checkpoint's PrevTimeLineID:   %u\n"),
-                  ControlFile->checkPointCopy.PrevTimeLineID);
        printf(_("Latest checkpoint's full_page_writes: %s\n"),
                   ControlFile->checkPointCopy.fullPageWrites ? _("on") : _("off"));
        printf(_("Latest checkpoint's NextXID:          %u:%u\n"),
index d4772a2965047a4677dcd50f2cdb3d62b973f3b9..2e2f35bf5cd283154bf6a67e43cc47d2e4536f8e 100644 (file)
@@ -444,10 +444,7 @@ main(int argc, char *argv[])
                ControlFile.checkPointCopy.nextMultiOffset = set_mxoff;
 
        if (minXlogTli > ControlFile.checkPointCopy.ThisTimeLineID)
-       {
                ControlFile.checkPointCopy.ThisTimeLineID = minXlogTli;
-               ControlFile.checkPointCopy.PrevTimeLineID = minXlogTli;
-       }
 
        if (set_wal_segsize != 0)
                ControlFile.xlog_seg_size = WalSegSz;
@@ -650,7 +647,6 @@ GuessControlValues(void)
 
        ControlFile.checkPointCopy.redo = SizeOfXLogLongPHD;
        ControlFile.checkPointCopy.ThisTimeLineID = 1;
-       ControlFile.checkPointCopy.PrevTimeLineID = 1;
        ControlFile.checkPointCopy.fullPageWrites = false;
        ControlFile.checkPointCopy.nextXid =
                FullTransactionIdFromEpochAndXid(0, FirstNormalTransactionId);
index 06368e236678690464fcdebf4ed5d22c9a7e3c9b..b0da5cb1b543a1b39a9545d531107882b1f11e73 100644 (file)
@@ -22,7 +22,7 @@
 
 
 /* Version identifier for this pg_control format */
-#define PG_CONTROL_VERSION     1300
+#define PG_CONTROL_VERSION     1600
 
 /* Nonce key length, see below */
 #define MOCK_AUTH_NONCE_LEN            32
@@ -37,8 +37,6 @@ typedef struct CheckPoint
        XLogRecPtr      redo;                   /* next RecPtr available when we began to
                                                                 * create CheckPoint (i.e. REDO start point) */
        TimeLineID      ThisTimeLineID; /* current TLI */
-       TimeLineID      PrevTimeLineID; /* previous TLI, if this record begins a new
-                                                                * timeline (equals ThisTimeLineID otherwise) */
        bool            fullPageWrites; /* current full_page_writes */
        FullTransactionId nextXid;      /* next free transaction ID */
        Oid                     nextOid;                /* next free OID */
index 6d378ff7859485e5bcf86c68c86647056c51813e..c2bd6f0801aae8d8fd675abf78c654062b8664fe 100644 (file)
   descr => 'pg_controldata checkpoint state information as a function',
   proname => 'pg_control_checkpoint', provolatile => 'v',
   prorettype => 'record', proargtypes => '',
-  proallargtypes => '{pg_lsn,pg_lsn,text,int4,int4,bool,text,oid,xid,xid,xid,oid,xid,xid,oid,xid,xid,timestamptz}',
-  proargmodes => '{o,o,o,o,o,o,o,o,o,o,o,o,o,o,o,o,o,o}',
-  proargnames => '{checkpoint_lsn,redo_lsn,redo_wal_file,timeline_id,prev_timeline_id,full_page_writes,next_xid,next_oid,next_multixact_id,next_multi_offset,oldest_xid,oldest_xid_dbid,oldest_active_xid,oldest_multi_xid,oldest_multi_dbid,oldest_commit_ts_xid,newest_commit_ts_xid,checkpoint_time}',
+  proallargtypes => '{pg_lsn,pg_lsn,text,int4,bool,text,oid,xid,xid,xid,oid,xid,xid,oid,xid,xid,timestamptz}',
+  proargmodes => '{o,o,o,o,o,o,o,o,o,o,o,o,o,o,o,o,o}',
+  proargnames => '{checkpoint_lsn,redo_lsn,redo_wal_file,timeline_id,full_page_writes,next_xid,next_oid,next_multixact_id,next_multi_offset,oldest_xid,oldest_xid_dbid,oldest_active_xid,oldest_multi_xid,oldest_multi_dbid,oldest_commit_ts_xid,newest_commit_ts_xid,checkpoint_time}',
   prosrc => 'pg_control_checkpoint' },
 
 { oid => '3443',