commit 5198f5010be0febd019b1888817e2d78b8e42b21 Author: bdrouvot Date: Thu Nov 3 12:59:10 2022 +0000 v7-0001-pg_stat_progress_checkpoint-view.patch diff --git a/doc/src/sgml/monitoring.sgml b/doc/src/sgml/monitoring.sgml index e5d622d514..ceb7d60ffa 100644 --- a/doc/src/sgml/monitoring.sgml +++ b/doc/src/sgml/monitoring.sgml @@ -414,6 +414,13 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser See . + + + pg_stat_progress_checkpointpg_stat_progress_checkpoint + One row only, showing the progress of the checkpoint. + See . + + @@ -5784,7 +5791,7 @@ FROM pg_stat_get_backend_idset() AS backendid; which support progress reporting are ANALYZE, CLUSTER, CREATE INDEX, VACUUM, - COPY, + COPY, CHECKPOINT and (i.e., replication command that issues to take a base backup). @@ -7072,6 +7079,402 @@ FROM pg_stat_get_backend_idset() AS backendid; + + Checkpoint Progress Reporting + + + pg_stat_progress_checkpoint + + + + Whenever the checkpoint operation is running, the + pg_stat_progress_checkpoint view will contain a + single row indicating the progress of the checkpoint. The tables below + describe the information that will be reported and provide information about + how to interpret it. + + + + <structname>pg_stat_progress_checkpoint</structname> View + + + + + Column Type + + + Description + + + + + + + + pid integer + + + Process ID of the checkpointer process. + + + + + + type text + + + Type of the checkpoint. See . + + + + + + flags text + + + Flags of the checkpoint. See . + + + + + + start_lsn text + + + The checkpoint start location. + + + + + + start_time timestamp with time zone + + + Start time of the checkpoint. + + + + + + phase text + + + Current processing phase. See . + + + + + + buffers_total bigint + + + Total number of buffers to be written. This is estimated and reported + as of the beginning of buffer write operation. + + + + + + buffers_processed bigint + + + Number of buffers processed. This counter increases when the targeted + buffer is processed. This number will eventually become equal to + buffers_total when the checkpoint is + complete. + + + + + + buffers_written bigint + + + Number of buffers written. This counter only advances when the targeted + buffers is written. Note that some of the buffers are processed but may + not required to be written. So this count will always be less than or + equal to buffers_total. + + + + + + files_total bigint + + + Total number of files to be synced. This is estimated and reported as of + the beginning of sync operation. + + + + + + files_synced bigint + + + Number of files synced. This counter advances when the targeted file is + synced. This number will eventually become equal to + files_total when the checkpoint is complete. + + + + + + new_requests text + + + True if any of the backend is requested for a checkpoint while the + current checkpoint is in progress, False otherwise. + + + + +
+ + + Checkpoint Types + + + + + + Types + Description + + + + + checkpoint + + The current operation is checkpoint. + + + + restartpoint + + The current operation is restartpoint. + + + + +
+ + + Checkpoint Flags + + + + + + Flags + Description + + + + + shutdown + + The checkpoint is for shutdown. + + + + end-of-recovery + + The checkpoint is for end-of-recovery. + + + + immediate + + The checkpoint happens without delays. + + + + force + + The checkpoint is started because some operation (for which the + checkpoint is necessary) forced a checkpoint. + + + + flush all + + The checkpoint flushes all pages, including those belonging to unlogged + tables. + + + + wait + + The operations which requested the checkpoint waits for completion + before returning. + + + + requested + + The checkpoint request has been made. + + + + wal + + The checkpoint is started because max_wal_size is + reached. + + + + time + + The checkpoint is started because checkpoint_timeout + expired. + + + + +
+ + + Checkpoint Phases + + + + + + Phase + Description + + + + + initializing + + The checkpointer process is preparing to begin the checkpoint operation. + This phase is expected to be very brief. + + + + getting virtual transaction IDs + + The checkpointer process is getting the virtual transaction IDs that + are delaying the checkpoint. + + + + checkpointing replication slots + + The checkpointer process is currently flushing all the replication slots + to disk. + + + + checkpointing logical replication snapshot files + + The checkpointer process is currently removing all the serialized + snapshot files that are not required anymore. + + + + checkpointing logical rewrite mapping files + + The checkpointer process is currently removing unwanted or flushing + required logical rewrite mapping files. + + + + checkpointing replication origin + + The checkpointer process is currently performing a checkpoint of each + replication origin's progress with respect to the replayed remote LSN. + + + + checkpointing commit log pages + + The checkpointer process is currently writing commit log pages to disk. + + + + checkpointing commit time stamp pages + + The checkpointer process is currently writing commit time stamp pages to + disk. + + + + checkpointing subtransaction pages + + The checkpointer process is currently writing subtransaction pages to disk. + + + + checkpointing multixact pages + + The checkpointer process is currently writing multixact pages to disk. + + + + checkpointing predicate lock pages + + The checkpointer process is currently writing predicate lock pages to disk. + + + + checkpointing buffers + + The checkpointer process is currently writing buffers to disk. + + + + processing file sync requests + + The checkpointer process is currently processing file sync requests. + + + + performing two phase checkpoint + + The checkpointer process is currently performing two phase checkpoint. + + + + performing post checkpoint cleanup + + The checkpointer process is currently performing post checkpoint cleanup. + It removes any lingering files that can be safely removed. + + + + invalidating replication slots + + The checkpointer process is currently invalidating replication slots. + + + + recycling old WAL files + + The checkpointer process is currently recycling old WAL files. + + + + truncating subtransactions + + The checkpointer process is currently removing the subtransaction + segments. + + + + finalizing + + The checkpointer process is finalizing the checkpoint operation. + + + + +
+ +
+ diff --git a/doc/src/sgml/ref/checkpoint.sgml b/doc/src/sgml/ref/checkpoint.sgml index 28a1d717b8..906883336d 100644 --- a/doc/src/sgml/ref/checkpoint.sgml +++ b/doc/src/sgml/ref/checkpoint.sgml @@ -55,6 +55,14 @@ CHECKPOINT Only superusers or users with the privileges of the pg_checkpoint role can call CHECKPOINT. + + + The checkpointer process running the checkpoint will report its progress + in the pg_stat_progress_checkpoint view except for + the shutdown and end-of-recovery cases. See + for details. + + diff --git a/doc/src/sgml/wal.sgml b/doc/src/sgml/wal.sgml index 6a38b53744..733a8d2837 100644 --- a/doc/src/sgml/wal.sgml +++ b/doc/src/sgml/wal.sgml @@ -531,7 +531,11 @@ adjust the parameter rather than the checkpoint parameters.) It is also possible to force a checkpoint by using the SQL - command CHECKPOINT. + command CHECKPOINT. The checkpointer process running the + checkpoint will report its progress in the + pg_stat_progress_checkpoint view except for the + shutdown and end-of-recovery cases. See + for details. diff --git a/src/backend/access/transam/xlog.c b/src/backend/access/transam/xlog.c index be54c23187..f2cebe0973 100644 --- a/src/backend/access/transam/xlog.c +++ b/src/backend/access/transam/xlog.c @@ -67,6 +67,7 @@ #include "catalog/catversion.h" #include "catalog/pg_control.h" #include "catalog/pg_database.h" +#include "commands/progress.h" #include "common/controldata_utils.h" #include "common/file_utils.h" #include "executor/instrument.h" @@ -698,6 +699,8 @@ static void WALInsertLockAcquireExclusive(void); static void WALInsertLockRelease(void); static void WALInsertLockUpdateInsertingAt(XLogRecPtr insertingAt); +static void checkpoint_progress_start(int flags, int type); + /* * Insert an XLOG record represented by an already-constructed chain of data * chunks. This is a low-level routine; to construct the WAL record header @@ -6622,6 +6625,9 @@ CreateCheckPoint(int flags) XLogCtl->RedoRecPtr = checkPoint.redo; SpinLockRelease(&XLogCtl->info_lck); + /* Prepare to report progress of the checkpoint. */ + checkpoint_progress_start(flags, PROGRESS_CHECKPOINT_TYPE_CHECKPOINT); + /* * If enabled, log checkpoint start. We postpone this until now so as not * to log anything if we decided to skip the checkpoint. @@ -6704,6 +6710,8 @@ CreateCheckPoint(int flags) * clog and we will correctly flush the update below. So we cannot miss * any xacts we need to wait for. */ + pgstat_progress_update_param(PROGRESS_CHECKPOINT_PHASE, + PROGRESS_CHECKPOINT_PHASE_GET_VIRTUAL_TRANSACTION_IDS); vxids = GetVirtualXIDsDelayingChkpt(&nvxids, DELAY_CHKPT_START); if (nvxids > 0) { @@ -6819,6 +6827,8 @@ CreateCheckPoint(int flags) /* * Let smgr do post-checkpoint cleanup (eg, deleting old files). */ + pgstat_progress_update_param(PROGRESS_CHECKPOINT_PHASE, + PROGRESS_CHECKPOINT_PHASE_POST_CHECKPOINT_CLEANUP); SyncPostCheckpoint(); /* @@ -6834,6 +6844,9 @@ CreateCheckPoint(int flags) */ XLByteToSeg(RedoRecPtr, _logSegNo, wal_segment_size); KeepLogSeg(recptr, &_logSegNo); + pgstat_progress_update_param(PROGRESS_CHECKPOINT_PHASE, + PROGRESS_CHECKPOINT_PHASE_INVALIDATE_REPLI_SLOTS); + if (InvalidateObsoleteReplicationSlots(_logSegNo)) { /* @@ -6844,6 +6857,8 @@ CreateCheckPoint(int flags) KeepLogSeg(recptr, &_logSegNo); } _logSegNo--; + pgstat_progress_update_param(PROGRESS_CHECKPOINT_PHASE, + PROGRESS_CHECKPOINT_PHASE_RECYCLE_OLD_XLOG); RemoveOldXlogFiles(_logSegNo, RedoRecPtr, recptr, checkPoint.ThisTimeLineID); @@ -6862,11 +6877,21 @@ CreateCheckPoint(int flags) * StartupSUBTRANS hasn't been called yet. */ if (!RecoveryInProgress()) + { + pgstat_progress_update_param(PROGRESS_CHECKPOINT_PHASE, + PROGRESS_CHECKPOINT_PHASE_TRUNCATE_SUBTRANS); TruncateSUBTRANS(GetOldestTransactionIdConsideredRunning()); + } + + pgstat_progress_update_param(PROGRESS_CHECKPOINT_PHASE, + PROGRESS_CHECKPOINT_PHASE_FINALIZE); /* Real work is done; log and update stats. */ LogCheckpointEnd(false); + /* Stop reporting progress of the checkpoint. */ + pgstat_progress_end_command(); + /* Reset the process title */ update_checkpoint_display(flags, false, true); @@ -7023,29 +7048,63 @@ static void CheckPointGuts(XLogRecPtr checkPointRedo, int flags) { CheckPointRelationMap(); + + pgstat_progress_update_param(PROGRESS_CHECKPOINT_PHASE, + PROGRESS_CHECKPOINT_PHASE_REPLI_SLOTS); CheckPointReplicationSlots(); + + pgstat_progress_update_param(PROGRESS_CHECKPOINT_PHASE, + PROGRESS_CHECKPOINT_PHASE_SNAPSHOTS); CheckPointSnapBuild(); + + pgstat_progress_update_param(PROGRESS_CHECKPOINT_PHASE, + PROGRESS_CHECKPOINT_PHASE_LOGICAL_REWRITE_MAPPINGS); CheckPointLogicalRewriteHeap(); + + pgstat_progress_update_param(PROGRESS_CHECKPOINT_PHASE, + PROGRESS_CHECKPOINT_PHASE_REPLI_ORIGIN); CheckPointReplicationOrigin(); /* Write out all dirty data in SLRUs and the main buffer pool */ TRACE_POSTGRESQL_BUFFER_CHECKPOINT_START(flags); CheckpointStats.ckpt_write_t = GetCurrentTimestamp(); + + pgstat_progress_update_param(PROGRESS_CHECKPOINT_PHASE, + PROGRESS_CHECKPOINT_PHASE_CLOG_PAGES); CheckPointCLOG(); + + pgstat_progress_update_param(PROGRESS_CHECKPOINT_PHASE, + PROGRESS_CHECKPOINT_PHASE_COMMITTS_PAGES); CheckPointCommitTs(); + + pgstat_progress_update_param(PROGRESS_CHECKPOINT_PHASE, + PROGRESS_CHECKPOINT_PHASE_SUBTRANS_PAGES); CheckPointSUBTRANS(); + + pgstat_progress_update_param(PROGRESS_CHECKPOINT_PHASE, + PROGRESS_CHECKPOINT_PHASE_MULTIXACT_PAGES); CheckPointMultiXact(); + + pgstat_progress_update_param(PROGRESS_CHECKPOINT_PHASE, + PROGRESS_CHECKPOINT_PHASE_PREDICATE_LOCK_PAGES); CheckPointPredicate(); + + pgstat_progress_update_param(PROGRESS_CHECKPOINT_PHASE, + PROGRESS_CHECKPOINT_PHASE_BUFFERS); CheckPointBuffers(flags); /* Perform all queued up fsyncs */ TRACE_POSTGRESQL_BUFFER_CHECKPOINT_SYNC_START(); CheckpointStats.ckpt_sync_t = GetCurrentTimestamp(); + pgstat_progress_update_param(PROGRESS_CHECKPOINT_PHASE, + PROGRESS_CHECKPOINT_PHASE_SYNC_FILES); ProcessSyncRequests(); CheckpointStats.ckpt_sync_end_t = GetCurrentTimestamp(); TRACE_POSTGRESQL_BUFFER_CHECKPOINT_DONE(); /* We deliberately delay 2PC checkpointing as long as possible */ + pgstat_progress_update_param(PROGRESS_CHECKPOINT_PHASE, + PROGRESS_CHECKPOINT_PHASE_TWO_PHASE); CheckPointTwoPhase(checkPointRedo); } @@ -7195,6 +7254,9 @@ CreateRestartPoint(int flags) MemSet(&CheckpointStats, 0, sizeof(CheckpointStats)); CheckpointStats.ckpt_start_t = GetCurrentTimestamp(); + /* Prepare to report progress of the restartpoint. */ + checkpoint_progress_start(flags, PROGRESS_CHECKPOINT_TYPE_RESTARTPOINT); + if (log_checkpoints) LogCheckpointStart(flags, true); @@ -7278,6 +7340,9 @@ CreateRestartPoint(int flags) replayPtr = GetXLogReplayRecPtr(&replayTLI); endptr = (receivePtr < replayPtr) ? replayPtr : receivePtr; KeepLogSeg(endptr, &_logSegNo); + pgstat_progress_update_param(PROGRESS_CHECKPOINT_PHASE, + PROGRESS_CHECKPOINT_PHASE_INVALIDATE_REPLI_SLOTS); + if (InvalidateObsoleteReplicationSlots(_logSegNo)) { /* @@ -7304,6 +7369,8 @@ CreateRestartPoint(int flags) if (!RecoveryInProgress()) replayTLI = XLogCtl->InsertTimeLineID; + pgstat_progress_update_param(PROGRESS_CHECKPOINT_PHASE, + PROGRESS_CHECKPOINT_PHASE_RECYCLE_OLD_XLOG); RemoveOldXlogFiles(_logSegNo, RedoRecPtr, endptr, replayTLI); /* @@ -7320,11 +7387,20 @@ CreateRestartPoint(int flags) * this because StartupSUBTRANS hasn't been called yet. */ if (EnableHotStandby) + { + pgstat_progress_update_param(PROGRESS_CHECKPOINT_PHASE, + PROGRESS_CHECKPOINT_PHASE_TRUNCATE_SUBTRANS); TruncateSUBTRANS(GetOldestTransactionIdConsideredRunning()); + } + pgstat_progress_update_param(PROGRESS_CHECKPOINT_PHASE, + PROGRESS_CHECKPOINT_PHASE_FINALIZE); /* Real work is done; log and update stats. */ LogCheckpointEnd(true); + /* Stop reporting progress of the restartpoint. */ + pgstat_progress_end_command(); + /* Reset the process title */ update_checkpoint_display(flags, true, true); @@ -8958,3 +9034,29 @@ SetWalWriterSleeping(bool sleeping) XLogCtl->WalWriterSleeping = sleeping; SpinLockRelease(&XLogCtl->info_lck); } + +/* + * Start reporting progress of the checkpoint. + */ +static void +checkpoint_progress_start(int flags, int type) +{ + const int index[] = { + PROGRESS_CHECKPOINT_TYPE, + PROGRESS_CHECKPOINT_FLAGS, + PROGRESS_CHECKPOINT_LSN, + PROGRESS_CHECKPOINT_START_TIMESTAMP, + PROGRESS_CHECKPOINT_PHASE + }; + int64 val[5]; + + pgstat_progress_start_command(PROGRESS_COMMAND_CHECKPOINT, InvalidOid); + + val[0] = type; + val[1] = flags; + val[2] = RedoRecPtr; + val[3] = CheckpointStats.ckpt_start_t; + val[4] = PROGRESS_CHECKPOINT_PHASE_INIT; + + pgstat_progress_update_multi_param(5, index, val); +} \ No newline at end of file diff --git a/src/backend/catalog/system_views.sql b/src/backend/catalog/system_views.sql index 2d8104b090..384ca35833 100644 --- a/src/backend/catalog/system_views.sql +++ b/src/backend/catalog/system_views.sql @@ -1267,6 +1267,57 @@ CREATE VIEW pg_stat_progress_copy AS FROM pg_stat_get_progress_info('COPY') AS S LEFT JOIN pg_database D ON S.datid = D.oid; +CREATE VIEW pg_stat_progress_checkpoint AS + SELECT + S.pid AS pid, + CASE S.param1 WHEN 1 THEN 'checkpoint' + WHEN 2 THEN 'restartpoint' + END AS type, + ( CASE WHEN (S.param2 & 4) > 0 THEN 'immediate ' ELSE '' END || + CASE WHEN (S.param2 & 8) > 0 THEN 'force ' ELSE '' END || + CASE WHEN (S.param2 & 16) > 0 THEN 'flush-all ' ELSE '' END || + CASE WHEN (S.param2 & 32) > 0 THEN 'wait ' ELSE '' END || + CASE WHEN (S.param2 & 128) > 0 THEN 'wal ' ELSE '' END || + CASE WHEN (S.param2 & 256) > 0 THEN 'time ' ELSE '' END + ) AS flags, + ( '0/0'::pg_lsn + + ((CASE + WHEN S.param3 < 0 THEN pow(2::numeric, 64::numeric)::numeric + ELSE 0::numeric + END) + + S.param3::numeric) + ) AS start_lsn, + to_timestamp(946684800 + (S.param4::float8 / 1000000)) AS start_time, + CASE S.param5 WHEN 1 THEN 'initializing' + WHEN 2 THEN 'getting virtual transaction IDs' + WHEN 3 THEN 'checkpointing replication slots' + WHEN 4 THEN 'checkpointing logical replication snapshot files' + WHEN 5 THEN 'checkpointing logical rewrite mapping files' + WHEN 6 THEN 'checkpointing replication origin' + WHEN 7 THEN 'checkpointing commit log pages' + WHEN 8 THEN 'checkpointing commit time stamp pages' + WHEN 9 THEN 'checkpointing subtransaction pages' + WHEN 10 THEN 'checkpointing multixact pages' + WHEN 11 THEN 'checkpointing predicate lock pages' + WHEN 12 THEN 'checkpointing buffers' + WHEN 13 THEN 'processing file sync requests' + WHEN 14 THEN 'performing two phase checkpoint' + WHEN 15 THEN 'performing post checkpoint cleanup' + WHEN 16 THEN 'invalidating replication slots' + WHEN 17 THEN 'recycling old WAL files' + WHEN 18 THEN 'truncating subtransactions' + WHEN 19 THEN 'finalizing' + END AS phase, + S.param6 AS buffers_total, + S.param7 AS buffers_processed, + S.param8 AS buffers_written, + S.param9 AS files_total, + S.param10 AS files_synced, + CASE S.param11 WHEN 0 THEN 'false' + WHEN 1 THEN 'true' + END AS new_requests + FROM pg_stat_get_progress_info('CHECKPOINT') AS S; + CREATE VIEW pg_user_mappings AS SELECT U.oid AS umid, diff --git a/src/backend/postmaster/checkpointer.c b/src/backend/postmaster/checkpointer.c index 5fc076fc14..21bf75b058 100644 --- a/src/backend/postmaster/checkpointer.c +++ b/src/backend/postmaster/checkpointer.c @@ -39,6 +39,7 @@ #include "access/xlog.h" #include "access/xlog_internal.h" #include "access/xlogrecovery.h" +#include "commands/progress.h" #include "libpq/pqsignal.h" #include "miscadmin.h" #include "pgstat.h" @@ -163,7 +164,7 @@ static pg_time_t last_xlog_switch_time; static void HandleCheckpointerInterrupts(void); static void CheckArchiveTimeout(void); static bool IsCheckpointOnSchedule(double progress); -static bool ImmediateCheckpointRequested(void); +static bool ImmediateCheckpointRequested(int flags); static bool CompactCheckpointerRequestQueue(void); static void UpdateSharedMemoryConfig(void); @@ -667,16 +668,24 @@ CheckArchiveTimeout(void) * there is one pending behind it.) */ static bool -ImmediateCheckpointRequested(void) +ImmediateCheckpointRequested(int flags) { volatile CheckpointerShmemStruct *cps = CheckpointerShmem; + if (cps->ckpt_flags & CHECKPOINT_REQUESTED) + pgstat_progress_update_param(PROGRESS_CHECKPOINT_NEW_REQUESTS, true); + /* * We don't need to acquire the ckpt_lck in this case because we're only * looking at a single flag bit. */ if (cps->ckpt_flags & CHECKPOINT_IMMEDIATE) + { + pgstat_progress_update_param(PROGRESS_CHECKPOINT_FLAGS, + (flags | CHECKPOINT_IMMEDIATE)); return true; + } + return false; } @@ -708,7 +717,7 @@ CheckpointWriteDelay(int flags, double progress) */ if (!(flags & CHECKPOINT_IMMEDIATE) && !ShutdownRequestPending && - !ImmediateCheckpointRequested() && + !ImmediateCheckpointRequested(flags) && IsCheckpointOnSchedule(progress)) { if (ConfigReloadPending) diff --git a/src/backend/storage/buffer/bufmgr.c b/src/backend/storage/buffer/bufmgr.c index 73d30bf619..6d69255667 100644 --- a/src/backend/storage/buffer/bufmgr.c +++ b/src/backend/storage/buffer/bufmgr.c @@ -39,6 +39,7 @@ #include "catalog/catalog.h" #include "catalog/storage.h" #include "catalog/storage_xlog.h" +#include "commands/progress.h" #include "executor/instrument.h" #include "lib/binaryheap.h" #include "miscadmin.h" @@ -2026,6 +2027,8 @@ BufferSync(int flags) WritebackContextInit(&wb_context, &checkpoint_flush_after); TRACE_POSTGRESQL_BUFFER_SYNC_START(NBuffers, num_to_scan); + pgstat_progress_update_param(PROGRESS_CHECKPOINT_BUFFERS_TOTAL, + num_to_scan); /* * Sort buffers that need to be written to reduce the likelihood of random @@ -2143,6 +2146,8 @@ BufferSync(int flags) bufHdr = GetBufferDescriptor(buf_id); num_processed++; + pgstat_progress_update_param(PROGRESS_CHECKPOINT_BUFFERS_PROCESSED, + num_processed); /* * We don't need to acquire the lock here, because we're only looking @@ -2163,6 +2168,8 @@ BufferSync(int flags) TRACE_POSTGRESQL_BUFFER_SYNC_WRITTEN(buf_id); PendingCheckpointerStats.buf_written_checkpoints++; num_written++; + pgstat_progress_update_param(PROGRESS_CHECKPOINT_BUFFERS_WRITTEN, + num_written); } } diff --git a/src/backend/storage/sync/sync.c b/src/backend/storage/sync/sync.c index 9d6a9e9109..aa25215910 100644 --- a/src/backend/storage/sync/sync.c +++ b/src/backend/storage/sync/sync.c @@ -23,6 +23,7 @@ #include "access/multixact.h" #include "access/xlog.h" #include "access/xlogutils.h" +#include "commands/progress.h" #include "commands/tablespace.h" #include "miscadmin.h" #include "pgstat.h" @@ -368,6 +369,9 @@ ProcessSyncRequests(void) /* Now scan the hashtable for fsync requests to process */ absorb_counter = FSYNCS_PER_ABSORB; hash_seq_init(&hstat, pendingOps); + pgstat_progress_update_param(PROGRESS_CHECKPOINT_FILES_TOTAL, + hash_get_num_entries(pendingOps)); + while ((entry = (PendingFsyncEntry *) hash_seq_search(&hstat)) != NULL) { int failures; @@ -431,6 +435,8 @@ ProcessSyncRequests(void) longest = elapsed; total_elapsed += elapsed; processed++; + pgstat_progress_update_param(PROGRESS_CHECKPOINT_FILES_SYNCED, + processed); if (log_checkpoints) elog(DEBUG1, "checkpoint sync: number=%d file=%s time=%.3f ms", diff --git a/src/backend/utils/adt/pgstatfuncs.c b/src/backend/utils/adt/pgstatfuncs.c index 96bffc0f2a..8281d961bf 100644 --- a/src/backend/utils/adt/pgstatfuncs.c +++ b/src/backend/utils/adt/pgstatfuncs.c @@ -497,6 +497,8 @@ pg_stat_get_progress_info(PG_FUNCTION_ARGS) cmdtype = PROGRESS_COMMAND_BASEBACKUP; else if (pg_strcasecmp(cmd, "COPY") == 0) cmdtype = PROGRESS_COMMAND_COPY; + else if (pg_strcasecmp(cmd, "CHECKPOINT") == 0) + cmdtype = PROGRESS_COMMAND_CHECKPOINT; else ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE), diff --git a/src/include/commands/progress.h b/src/include/commands/progress.h index a28938caf4..33a64d2f0b 100644 --- a/src/include/commands/progress.h +++ b/src/include/commands/progress.h @@ -151,4 +151,42 @@ #define PROGRESS_COPY_TYPE_PIPE 3 #define PROGRESS_COPY_TYPE_CALLBACK 4 +/* Progress parameters for checkpoint */ +#define PROGRESS_CHECKPOINT_TYPE 0 +#define PROGRESS_CHECKPOINT_FLAGS 1 +#define PROGRESS_CHECKPOINT_LSN 2 +#define PROGRESS_CHECKPOINT_START_TIMESTAMP 3 +#define PROGRESS_CHECKPOINT_PHASE 4 +#define PROGRESS_CHECKPOINT_BUFFERS_TOTAL 5 +#define PROGRESS_CHECKPOINT_BUFFERS_PROCESSED 6 +#define PROGRESS_CHECKPOINT_BUFFERS_WRITTEN 7 +#define PROGRESS_CHECKPOINT_FILES_TOTAL 8 +#define PROGRESS_CHECKPOINT_FILES_SYNCED 9 +#define PROGRESS_CHECKPOINT_NEW_REQUESTS 10 + +/* Types of checkpoint (as advertised via PROGRESS_CHECKPOINT_TYPE) */ +#define PROGRESS_CHECKPOINT_TYPE_CHECKPOINT 1 +#define PROGRESS_CHECKPOINT_TYPE_RESTARTPOINT 2 + +/* Phases of checkpoint (as advertised via PROGRESS_CHECKPOINT_PHASE) */ +#define PROGRESS_CHECKPOINT_PHASE_INIT 1 +#define PROGRESS_CHECKPOINT_PHASE_GET_VIRTUAL_TRANSACTION_IDS 2 +#define PROGRESS_CHECKPOINT_PHASE_REPLI_SLOTS 3 +#define PROGRESS_CHECKPOINT_PHASE_SNAPSHOTS 4 +#define PROGRESS_CHECKPOINT_PHASE_LOGICAL_REWRITE_MAPPINGS 5 +#define PROGRESS_CHECKPOINT_PHASE_REPLI_ORIGIN 6 +#define PROGRESS_CHECKPOINT_PHASE_CLOG_PAGES 7 +#define PROGRESS_CHECKPOINT_PHASE_COMMITTS_PAGES 8 +#define PROGRESS_CHECKPOINT_PHASE_SUBTRANS_PAGES 9 +#define PROGRESS_CHECKPOINT_PHASE_MULTIXACT_PAGES 10 +#define PROGRESS_CHECKPOINT_PHASE_PREDICATE_LOCK_PAGES 11 +#define PROGRESS_CHECKPOINT_PHASE_BUFFERS 12 +#define PROGRESS_CHECKPOINT_PHASE_SYNC_FILES 13 +#define PROGRESS_CHECKPOINT_PHASE_TWO_PHASE 14 +#define PROGRESS_CHECKPOINT_PHASE_POST_CHECKPOINT_CLEANUP 15 +#define PROGRESS_CHECKPOINT_PHASE_INVALIDATE_REPLI_SLOTS 16 +#define PROGRESS_CHECKPOINT_PHASE_RECYCLE_OLD_XLOG 17 +#define PROGRESS_CHECKPOINT_PHASE_TRUNCATE_SUBTRANS 18 +#define PROGRESS_CHECKPOINT_PHASE_FINALIZE 19 + #endif diff --git a/src/include/utils/backend_progress.h b/src/include/utils/backend_progress.h index 47bf8029b0..02d51fb948 100644 --- a/src/include/utils/backend_progress.h +++ b/src/include/utils/backend_progress.h @@ -27,7 +27,8 @@ typedef enum ProgressCommandType PROGRESS_COMMAND_CLUSTER, PROGRESS_COMMAND_CREATE_INDEX, PROGRESS_COMMAND_BASEBACKUP, - PROGRESS_COMMAND_COPY + PROGRESS_COMMAND_COPY, + PROGRESS_COMMAND_CHECKPOINT } ProgressCommandType; #define PGSTAT_NUM_PROGRESS_PARAM 20 diff --git a/src/test/regress/expected/rules.out b/src/test/regress/expected/rules.out index 624d0e5aae..eab68d7f14 100644 --- a/src/test/regress/expected/rules.out +++ b/src/test/regress/expected/rules.out @@ -1913,6 +1913,76 @@ pg_stat_progress_basebackup| SELECT s.pid, s.param4 AS tablespaces_total, s.param5 AS tablespaces_streamed FROM pg_stat_get_progress_info('BASEBACKUP'::text) s(pid, datid, relid, param1, param2, param3, param4, param5, param6, param7, param8, param9, param10, param11, param12, param13, param14, param15, param16, param17, param18, param19, param20); +pg_stat_progress_checkpoint| SELECT s.pid, + CASE s.param1 + WHEN 1 THEN 'checkpoint'::text + WHEN 2 THEN 'restartpoint'::text + ELSE NULL::text + END AS type, + ((((( + CASE + WHEN ((s.param2 & (4)::bigint) > 0) THEN 'immediate '::text + ELSE ''::text + END || + CASE + WHEN ((s.param2 & (8)::bigint) > 0) THEN 'force '::text + ELSE ''::text + END) || + CASE + WHEN ((s.param2 & (16)::bigint) > 0) THEN 'flush-all '::text + ELSE ''::text + END) || + CASE + WHEN ((s.param2 & (32)::bigint) > 0) THEN 'wait '::text + ELSE ''::text + END) || + CASE + WHEN ((s.param2 & (128)::bigint) > 0) THEN 'wal '::text + ELSE ''::text + END) || + CASE + WHEN ((s.param2 & (256)::bigint) > 0) THEN 'time '::text + ELSE ''::text + END) AS flags, + ('0/0'::pg_lsn + ( + CASE + WHEN (s.param3 < 0) THEN pow((2)::numeric, (64)::numeric) + ELSE (0)::numeric + END + (s.param3)::numeric)) AS start_lsn, + to_timestamp(((946684800)::double precision + ((s.param4)::double precision / (1000000)::double precision))) AS start_time, + CASE s.param5 + WHEN 1 THEN 'initializing'::text + WHEN 2 THEN 'getting virtual transaction IDs'::text + WHEN 3 THEN 'checkpointing replication slots'::text + WHEN 4 THEN 'checkpointing logical replication snapshot files'::text + WHEN 5 THEN 'checkpointing logical rewrite mapping files'::text + WHEN 6 THEN 'checkpointing replication origin'::text + WHEN 7 THEN 'checkpointing commit log pages'::text + WHEN 8 THEN 'checkpointing commit time stamp pages'::text + WHEN 9 THEN 'checkpointing subtransaction pages'::text + WHEN 10 THEN 'checkpointing multixact pages'::text + WHEN 11 THEN 'checkpointing predicate lock pages'::text + WHEN 12 THEN 'checkpointing buffers'::text + WHEN 13 THEN 'processing file sync requests'::text + WHEN 14 THEN 'performing two phase checkpoint'::text + WHEN 15 THEN 'performing post checkpoint cleanup'::text + WHEN 16 THEN 'invalidating replication slots'::text + WHEN 17 THEN 'recycling old WAL files'::text + WHEN 18 THEN 'truncating subtransactions'::text + WHEN 19 THEN 'finalizing'::text + ELSE NULL::text + END AS phase, + s.param6 AS buffers_total, + s.param7 AS buffers_processed, + s.param8 AS buffers_written, + s.param9 AS files_total, + s.param10 AS files_synced, + CASE s.param11 + WHEN 0 THEN 'false'::text + WHEN 1 THEN 'true'::text + ELSE NULL::text + END AS new_requests + FROM pg_stat_get_progress_info('CHECKPOINT'::text) s(pid, datid, relid, param1, param2, param3, param4, param5, param6, param7, param8, param9, param10, param11, param12, param13, param14, param15, param16, param17, param18, param19, param20); pg_stat_progress_cluster| SELECT s.pid, s.datid, d.datname,