From abfa974be88a5b3fb10144873aeca2679e4e95ff Mon Sep 17 00:00:00 2001 From: Bharath Rupireddy Date: Fri, 28 Jan 2022 08:17:27 +0000 Subject: [PATCH v3] add last checkpoint kind to pg_control file Bump catalog version --- doc/src/sgml/func.sgml | 5 +++++ src/backend/access/transam/xlog.c | 2 ++ src/backend/utils/misc/pg_controldata.c | 28 ++++++++++++++++++++++--- src/bin/pg_controldata/pg_controldata.c | 19 +++++++++++++++++ src/include/catalog/pg_control.h | 5 +++-- src/include/catalog/pg_proc.dat | 6 +++--- 6 files changed, 57 insertions(+), 8 deletions(-) diff --git a/doc/src/sgml/func.sgml b/doc/src/sgml/func.sgml index 0ee6974f1c..4357ca838e 100644 --- a/doc/src/sgml/func.sgml +++ b/doc/src/sgml/func.sgml @@ -25093,6 +25093,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 dfe2a0bcce..72255f6b8a 100644 --- a/src/backend/access/transam/xlog.c +++ b/src/backend/access/transam/xlog.c @@ -9375,6 +9375,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 */ @@ -9761,6 +9762,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 781f8b8758..0640a450e1 100644 --- a/src/backend/utils/misc/pg_controldata.c +++ b/src/backend/utils/misc/pg_controldata.c @@ -79,20 +79,23 @@ pg_control_system(PG_FUNCTION_ARGS) Datum pg_control_checkpoint(PG_FUNCTION_ARGS) { - Datum values[18]; - bool nulls[18]; + Datum values[19]; + bool nulls[19]; TupleDesc tupdesc; HeapTuple htup; ControlFileData *ControlFile; XLogSegNo segno; char xlogfilename[MAXFNAMELEN]; bool crc_ok; + uint16 flags; +#define CHECKPOINT_KIND_TEXT_LENGTH 128 + char ckpt_kind[CHECKPOINT_KIND_TEXT_LENGTH]; /* * 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 +132,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,9 +207,26 @@ pg_control_checkpoint(PG_FUNCTION_ARGS) values[17] = TimestampTzGetDatum(time_t_to_timestamptz(ControlFile->checkPointCopy.time)); nulls[17] = false; + MemSet(ckpt_kind, 0, CHECKPOINT_KIND_TEXT_LENGTH); + flags = ControlFile->checkPointKind; + + snprintf(ckpt_kind, CHECKPOINT_KIND_TEXT_LENGTH, "%s%s%s%s%s%s%s%s", + (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)); +#undef CHECKPOINT_KIND_TEXT_LENGTH } Datum diff --git a/src/bin/pg_controldata/pg_controldata.c b/src/bin/pg_controldata/pg_controldata.c index f911f98d94..37c1ebf8ad 100644 --- a/src/bin/pg_controldata/pg_controldata.c +++ b/src/bin/pg_controldata/pg_controldata.c @@ -106,6 +106,9 @@ main(int argc, char *argv[]) int c; int i; int WalSegSz; + uint16 flags; +#define CHECKPOINT_KIND_TEXT_LENGTH 128 + char ckpt_kind[CHECKPOINT_KIND_TEXT_LENGTH]; pg_logging_init(argv[0]); set_pglocale_pgservice(argv[0], PG_TEXTDOMAIN("pg_controldata")); @@ -225,6 +228,19 @@ 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, CHECKPOINT_KIND_TEXT_LENGTH); + flags = ControlFile->checkPointKind; + + snprintf(ckpt_kind, CHECKPOINT_KIND_TEXT_LENGTH, "%s%s%s%s%s%s%s%s", + (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"), @@ -329,4 +347,5 @@ main(int argc, char *argv[]) printf(_("Mock authentication nonce: %s\n"), mock_auth_nonce_str); return 0; +#undef CHECKPOINT_KIND_TEXT_LENGTH } diff --git a/src/include/catalog/pg_control.h b/src/include/catalog/pg_control.h index 1f3dc24ac1..4ec24ff518 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 0859dc81ca..5c0e20fe5c 100644 --- a/src/include/catalog/pg_proc.dat +++ b/src/include/catalog/pg_proc.dat @@ -11565,9 +11565,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