From 77fe03bc10454ed3a00e71d1e0eeb711a3e95b9f Mon Sep 17 00:00:00 2001 From: Robert Haas Date: Mon, 18 Apr 2022 16:01:13 -0400 Subject: [PATCH] Remove previous timeline ID from checkpoint. 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 | 5 -- src/backend/access/rmgrdesc/xlogdesc.c | 3 +- src/backend/access/transam/xlog.c | 2 - src/backend/access/transam/xlogrecovery.c | 32 +++++------- src/backend/utils/misc/pg_controldata.c | 61 +++++++++++------------ src/bin/pg_controldata/pg_controldata.c | 2 - src/bin/pg_resetwal/pg_resetwal.c | 4 -- src/include/catalog/pg_control.h | 4 +- src/include/catalog/pg_proc.dat | 6 +-- 9 files changed, 45 insertions(+), 74 deletions(-) diff --git a/doc/src/sgml/func.sgml b/doc/src/sgml/func.sgml index 489184a4f0..f8516b5475 100644 --- a/doc/src/sgml/func.sgml +++ b/doc/src/sgml/func.sgml @@ -27626,11 +27626,6 @@ SELECT collation for ('foo' COLLATE "de_DE"); integer - - prev_timeline_id - integer - - full_page_writes boolean diff --git a/src/backend/access/rmgrdesc/xlogdesc.c b/src/backend/access/rmgrdesc/xlogdesc.c index c0dfea40c7..a3e29b043f 100644 --- a/src/backend/access/rmgrdesc/xlogdesc.c +++ b/src/backend/access/rmgrdesc/xlogdesc.c @@ -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), diff --git a/src/backend/access/transam/xlog.c b/src/backend/access/transam/xlog.c index 420e93bed3..912a913b64 100644 --- a/src/backend/access/transam/xlog.c +++ b/src/backend/access/transam/xlog.c @@ -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; diff --git a/src/backend/access/transam/xlogrecovery.c b/src/backend/access/transam/xlogrecovery.c index 39ef865ed9..14a3ee96a3 100644 --- a/src/backend/access/transam/xlogrecovery.c +++ b/src/backend/access/transam/xlogrecovery.c @@ -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; + } } } diff --git a/src/backend/utils/misc/pg_controldata.c b/src/backend/utils/misc/pg_controldata.c index 781f8b8758..c30f380d07 100644 --- a/src/backend/utils/misc/pg_controldata.c +++ b/src/backend/utils/misc/pg_controldata.c @@ -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)); diff --git a/src/bin/pg_controldata/pg_controldata.c b/src/bin/pg_controldata/pg_controldata.c index c390ec51ce..56dc8d0031 100644 --- a/src/bin/pg_controldata/pg_controldata.c +++ b/src/bin/pg_controldata/pg_controldata.c @@ -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"), diff --git a/src/bin/pg_resetwal/pg_resetwal.c b/src/bin/pg_resetwal/pg_resetwal.c index d4772a2965..2e2f35bf5c 100644 --- a/src/bin/pg_resetwal/pg_resetwal.c +++ b/src/bin/pg_resetwal/pg_resetwal.c @@ -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); diff --git a/src/include/catalog/pg_control.h b/src/include/catalog/pg_control.h index 06368e2366..b0da5cb1b5 100644 --- a/src/include/catalog/pg_control.h +++ b/src/include/catalog/pg_control.h @@ -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 */ diff --git a/src/include/catalog/pg_proc.dat b/src/include/catalog/pg_proc.dat index 6d378ff785..c2bd6f0801 100644 --- a/src/include/catalog/pg_proc.dat +++ b/src/include/catalog/pg_proc.dat @@ -11711,9 +11711,9 @@ 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', -- 2.30.2