From f5076d265b8d3048a530d44cd0b754479c679866 Mon Sep 17 00:00:00 2001 From: Bharath Rupireddy Date: Wed, 8 Dec 2021 11:24:49 +0000 Subject: [PATCH v1] add last checkpoint kind to pg_control file Bump catalog version --- doc/src/sgml/func.sgml | 5 +++++ src/backend/access/transam/xlog.c | 3 +++ src/backend/utils/misc/pg_controldata.c | 23 ++++++++++++++++++++++- src/bin/pg_controldata/pg_controldata.c | 18 ++++++++++++++++++ src/include/catalog/pg_control.h | 5 +++-- src/include/catalog/pg_proc.dat | 6 +++--- 6 files changed, 54 insertions(+), 6 deletions(-) diff --git a/doc/src/sgml/func.sgml b/doc/src/sgml/func.sgml index 0a725a6711..445dfaaac0 100644 --- a/doc/src/sgml/func.sgml +++ b/doc/src/sgml/func.sgml @@ -25029,6 +25029,11 @@ SELECT collation for ('foo' COLLATE "de_DE"); timestamp with time zone + + checkpoint_kind + text + + diff --git a/src/backend/access/transam/xlog.c b/src/backend/access/transam/xlog.c index d894af310a..b457051941 100644 --- a/src/backend/access/transam/xlog.c +++ b/src/backend/access/transam/xlog.c @@ -5476,6 +5476,7 @@ BootStrapXLOG(void) /* Now create pg_control */ InitControlFile(sysidentifier); + ControlFile->checkPointKind = 0; ControlFile->time = checkPoint.time; ControlFile->checkPoint = checkPoint.redo; ControlFile->checkPointCopy = checkPoint; @@ -9408,6 +9409,7 @@ CreateCheckPoint(int flags) LWLockAcquire(ControlFileLock, LW_EXCLUSIVE); if (shutdown) ControlFile->state = DB_SHUTDOWNED; + ControlFile->checkPointKind = flags; ControlFile->checkPoint = ProcLastRecPtr; ControlFile->checkPointCopy = checkPoint; /* crash recovery should always recover to the end of WAL */ @@ -9794,6 +9796,7 @@ CreateRestartPoint(int flags) if (ControlFile->state == DB_IN_ARCHIVE_RECOVERY && ControlFile->checkPointCopy.redo < lastCheckPoint.redo) { + ControlFile->checkPointKind = flags; ControlFile->checkPoint = lastCheckPointRecPtr; ControlFile->checkPointCopy = lastCheckPoint; diff --git a/src/backend/utils/misc/pg_controldata.c b/src/backend/utils/misc/pg_controldata.c index 209a20a882..e94965d51f 100644 --- a/src/backend/utils/misc/pg_controldata.c +++ b/src/backend/utils/misc/pg_controldata.c @@ -87,12 +87,14 @@ pg_control_checkpoint(PG_FUNCTION_ARGS) XLogSegNo segno; char xlogfilename[MAXFNAMELEN]; bool crc_ok; + uint16 flags; + char ckpt_kind[2 * MAXPGPATH]; /* * Construct a tuple descriptor for the result row. This must match this * function's pg_proc entry! */ - tupdesc = CreateTemplateTupleDesc(18); + tupdesc = CreateTemplateTupleDesc(19); TupleDescInitEntry(tupdesc, (AttrNumber) 1, "checkpoint_lsn", PG_LSNOID, -1, 0); TupleDescInitEntry(tupdesc, (AttrNumber) 2, "redo_lsn", @@ -129,6 +131,8 @@ pg_control_checkpoint(PG_FUNCTION_ARGS) XIDOID, -1, 0); TupleDescInitEntry(tupdesc, (AttrNumber) 18, "checkpoint_time", TIMESTAMPTZOID, -1, 0); + TupleDescInitEntry(tupdesc, (AttrNumber) 19, "checkpoint_kind", + TEXTOID, -1, 0); tupdesc = BlessTupleDesc(tupdesc); /* Read the control file. */ @@ -202,6 +206,23 @@ pg_control_checkpoint(PG_FUNCTION_ARGS) values[17] = TimestampTzGetDatum(time_t_to_timestamptz(ControlFile->checkPointCopy.time)); nulls[17] = false; + MemSet(ckpt_kind, 0, 2 * MAXPGPATH); + flags = ControlFile->checkPointKind; + + snprintf(ckpt_kind, 2 * MAXPGPATH, "%s%s%s%s%s%s%s%s%s", + (flags == 0) ? "unknown" : "", + (flags & CHECKPOINT_IS_SHUTDOWN) ? "shutdown " : "", + (flags & CHECKPOINT_END_OF_RECOVERY) ? "end-of-recovery " : "", + (flags & CHECKPOINT_IMMEDIATE) ? "immediate " : "", + (flags & CHECKPOINT_FORCE) ? "force " : "", + (flags & CHECKPOINT_WAIT) ? "wait " : "", + (flags & CHECKPOINT_CAUSE_XLOG) ? "wal " : "", + (flags & CHECKPOINT_CAUSE_TIME) ? "time " : "", + (flags & CHECKPOINT_FLUSH_ALL) ? "flush-all" : ""); + + values[18] = CStringGetTextDatum(ckpt_kind); + nulls[18] = 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 f911f98d94..dfff0928e5 100644 --- a/src/bin/pg_controldata/pg_controldata.c +++ b/src/bin/pg_controldata/pg_controldata.c @@ -106,6 +106,8 @@ main(int argc, char *argv[]) int c; int i; int WalSegSz; + uint16 flags; + char ckpt_kind[2 * MAXPGPATH]; pg_logging_init(argv[0]); set_pglocale_pgservice(argv[0], PG_TEXTDOMAIN("pg_controldata")); @@ -225,6 +227,20 @@ main(int argc, char *argv[]) snprintf(&mock_auth_nonce_str[i * 2], 3, "%02x", (unsigned char) ControlFile->mock_authentication_nonce[i]); + MemSet(ckpt_kind, 0, 2 * MAXPGPATH); + flags = ControlFile->checkPointKind; + + snprintf(ckpt_kind, 2 * MAXPGPATH, "%s%s%s%s%s%s%s%s%s", + (flags == 0) ? "unknown" : "", + (flags & CHECKPOINT_IS_SHUTDOWN) ? "shutdown " : "", + (flags & CHECKPOINT_END_OF_RECOVERY) ? "end-of-recovery " : "", + (flags & CHECKPOINT_IMMEDIATE) ? "immediate " : "", + (flags & CHECKPOINT_FORCE) ? "force " : "", + (flags & CHECKPOINT_WAIT) ? "wait " : "", + (flags & CHECKPOINT_CAUSE_XLOG) ? "wal " : "", + (flags & CHECKPOINT_CAUSE_TIME) ? "time " : "", + (flags & CHECKPOINT_FLUSH_ALL) ? "flush-all" : ""); + printf(_("pg_control version number: %u\n"), ControlFile->pg_control_version); printf(_("Catalog version number: %u\n"), @@ -235,6 +251,8 @@ main(int argc, char *argv[]) dbState(ControlFile->state)); printf(_("pg_control last modified: %s\n"), pgctime_str); + printf(_("Latest checkpoint kind: %s\n"), + ckpt_kind); printf(_("Latest checkpoint location: %X/%X\n"), LSN_FORMAT_ARGS(ControlFile->checkPoint)); printf(_("Latest checkpoint's REDO location: %X/%X\n"), diff --git a/src/include/catalog/pg_control.h b/src/include/catalog/pg_control.h index 749bce0cc6..3155857b67 100644 --- a/src/include/catalog/pg_control.h +++ b/src/include/catalog/pg_control.h @@ -128,9 +128,10 @@ typedef struct ControlFileData */ DBState state; /* see enum above */ pg_time_t time; /* time stamp of last pg_control update */ - XLogRecPtr checkPoint; /* last check point record ptr */ + uint16 checkPointKind; /* last checkpoint kind */ + XLogRecPtr checkPoint; /* last checkpoint record ptr */ - CheckPoint checkPointCopy; /* copy of last check point record */ + CheckPoint checkPointCopy; /* copy of last checkpoint record */ XLogRecPtr unloggedLSN; /* current fake LSN value, for unlogged rels */ diff --git a/src/include/catalog/pg_proc.dat b/src/include/catalog/pg_proc.dat index 79d787cd26..1abf466c63 100644 --- a/src/include/catalog/pg_proc.dat +++ b/src/include/catalog/pg_proc.dat @@ -11567,9 +11567,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,int4,bool,text,oid,xid,xid,xid,oid,xid,xid,oid,xid,xid,timestamptz,text}', + proargmodes => '{o,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,checkpoint_kind}', prosrc => 'pg_control_checkpoint' }, { oid => '3443', -- 2.25.1