1
0
mirror of https://github.com/postgres/postgres.git synced 2025-04-22 23:02:54 +03:00

Add num_done counter to the pg_stat_checkpointer view.

Checkpoints can be skipped when the server is idle. The existing num_timed and
num_requested counters in pg_stat_checkpointer track both completed and
skipped checkpoints, but there was no way to count only the completed ones.

This commit introduces the num_done counter, which tracks only completed
checkpoints, making it easier to see how many were actually performed.

Bump catalog version.

Author: Anton A. Melnikov
Reviewed-by: Fujii Masao
Discussion: https://postgr.es/m/9ea77f40-818d-4841-9dee-158ac8f6e690@oss.nttdata.com
This commit is contained in:
Fujii Masao 2024-09-30 11:56:05 +09:00
parent 20cfec896c
commit 559efce1d6
11 changed files with 60 additions and 19 deletions

View File

@ -3063,7 +3063,16 @@ description | Waiting for a newly initialized WAL file to reach durable storage
<structfield>num_requested</structfield> <type>bigint</type> <structfield>num_requested</structfield> <type>bigint</type>
</para> </para>
<para> <para>
Number of requested checkpoints that have been performed Number of backend requested checkpoints
</para></entry>
</row>
<row>
<entry role="catalog_table_entry"><para role="column_definition">
<structfield>num_done</structfield> <type>bigint</type>
</para>
<para>
Number of checkpoints that have been performed
</para></entry> </para></entry>
</row> </row>

View File

@ -6878,8 +6878,11 @@ update_checkpoint_display(int flags, bool restartpoint, bool reset)
* In this case, we only insert an XLOG_CHECKPOINT_SHUTDOWN record, and it's * In this case, we only insert an XLOG_CHECKPOINT_SHUTDOWN record, and it's
* both the record marking the completion of the checkpoint and the location * both the record marking the completion of the checkpoint and the location
* from which WAL replay would begin if needed. * from which WAL replay would begin if needed.
*
* Returns true if a new checkpoint was performed, or false if it was skipped
* because the system was idle.
*/ */
void bool
CreateCheckPoint(int flags) CreateCheckPoint(int flags)
{ {
bool shutdown; bool shutdown;
@ -6971,7 +6974,7 @@ CreateCheckPoint(int flags)
END_CRIT_SECTION(); END_CRIT_SECTION();
ereport(DEBUG1, ereport(DEBUG1,
(errmsg_internal("checkpoint skipped because system is idle"))); (errmsg_internal("checkpoint skipped because system is idle")));
return; return false;
} }
} }
@ -7353,6 +7356,8 @@ CreateCheckPoint(int flags)
CheckpointStats.ckpt_segs_added, CheckpointStats.ckpt_segs_added,
CheckpointStats.ckpt_segs_removed, CheckpointStats.ckpt_segs_removed,
CheckpointStats.ckpt_segs_recycled); CheckpointStats.ckpt_segs_recycled);
return true;
} }
/* /*

View File

@ -1138,6 +1138,7 @@ CREATE VIEW pg_stat_checkpointer AS
SELECT SELECT
pg_stat_get_checkpointer_num_timed() AS num_timed, pg_stat_get_checkpointer_num_timed() AS num_timed,
pg_stat_get_checkpointer_num_requested() AS num_requested, pg_stat_get_checkpointer_num_requested() AS num_requested,
pg_stat_get_checkpointer_num_performed() AS num_done,
pg_stat_get_checkpointer_restartpoints_timed() AS restartpoints_timed, pg_stat_get_checkpointer_restartpoints_timed() AS restartpoints_timed,
pg_stat_get_checkpointer_restartpoints_requested() AS restartpoints_req, pg_stat_get_checkpointer_restartpoints_requested() AS restartpoints_req,
pg_stat_get_checkpointer_restartpoints_performed() AS restartpoints_done, pg_stat_get_checkpointer_restartpoints_performed() AS restartpoints_done,

View File

@ -460,10 +460,7 @@ CheckpointerMain(char *startup_data, size_t startup_data_len)
* Do the checkpoint. * Do the checkpoint.
*/ */
if (!do_restartpoint) if (!do_restartpoint)
{ ckpt_performed = CreateCheckPoint(flags);
CreateCheckPoint(flags);
ckpt_performed = true;
}
else else
ckpt_performed = CreateRestartPoint(flags); ckpt_performed = CreateRestartPoint(flags);
@ -484,7 +481,7 @@ CheckpointerMain(char *startup_data, size_t startup_data_len)
ConditionVariableBroadcast(&CheckpointerShmem->done_cv); ConditionVariableBroadcast(&CheckpointerShmem->done_cv);
if (ckpt_performed) if (!do_restartpoint)
{ {
/* /*
* Note we record the checkpoint start time not end time as * Note we record the checkpoint start time not end time as
@ -493,18 +490,32 @@ CheckpointerMain(char *startup_data, size_t startup_data_len)
*/ */
last_checkpoint_time = now; last_checkpoint_time = now;
if (do_restartpoint) if (ckpt_performed)
PendingCheckpointerStats.restartpoints_performed++; PendingCheckpointerStats.num_performed++;
} }
else else
{ {
/* if (ckpt_performed)
* We were not able to perform the restartpoint (checkpoints {
* throw an ERROR in case of error). Most likely because we /*
* have not received any new checkpoint WAL records since the * The same as for checkpoint. Please see the
* last restartpoint. Try again in 15 s. * corresponding comment.
*/ */
last_checkpoint_time = now - CheckPointTimeout + 15; last_checkpoint_time = now;
PendingCheckpointerStats.restartpoints_performed++;
}
else
{
/*
* We were not able to perform the restartpoint
* (checkpoints throw an ERROR in case of error). Most
* likely because we have not received any new checkpoint
* WAL records since the last restartpoint. Try again in
* 15 s.
*/
last_checkpoint_time = now - CheckPointTimeout + 15;
}
} }
ckpt_active = false; ckpt_active = false;

View File

@ -49,6 +49,7 @@ pgstat_report_checkpointer(void)
#define CHECKPOINTER_ACC(fld) stats_shmem->stats.fld += PendingCheckpointerStats.fld #define CHECKPOINTER_ACC(fld) stats_shmem->stats.fld += PendingCheckpointerStats.fld
CHECKPOINTER_ACC(num_timed); CHECKPOINTER_ACC(num_timed);
CHECKPOINTER_ACC(num_requested); CHECKPOINTER_ACC(num_requested);
CHECKPOINTER_ACC(num_performed);
CHECKPOINTER_ACC(restartpoints_timed); CHECKPOINTER_ACC(restartpoints_timed);
CHECKPOINTER_ACC(restartpoints_requested); CHECKPOINTER_ACC(restartpoints_requested);
CHECKPOINTER_ACC(restartpoints_performed); CHECKPOINTER_ACC(restartpoints_performed);
@ -127,6 +128,7 @@ pgstat_checkpointer_snapshot_cb(void)
#define CHECKPOINTER_COMP(fld) pgStatLocal.snapshot.checkpointer.fld -= reset.fld; #define CHECKPOINTER_COMP(fld) pgStatLocal.snapshot.checkpointer.fld -= reset.fld;
CHECKPOINTER_COMP(num_timed); CHECKPOINTER_COMP(num_timed);
CHECKPOINTER_COMP(num_requested); CHECKPOINTER_COMP(num_requested);
CHECKPOINTER_COMP(num_performed);
CHECKPOINTER_COMP(restartpoints_timed); CHECKPOINTER_COMP(restartpoints_timed);
CHECKPOINTER_COMP(restartpoints_requested); CHECKPOINTER_COMP(restartpoints_requested);
CHECKPOINTER_COMP(restartpoints_performed); CHECKPOINTER_COMP(restartpoints_performed);

View File

@ -1191,6 +1191,12 @@ pg_stat_get_checkpointer_num_requested(PG_FUNCTION_ARGS)
PG_RETURN_INT64(pgstat_fetch_stat_checkpointer()->num_requested); PG_RETURN_INT64(pgstat_fetch_stat_checkpointer()->num_requested);
} }
Datum
pg_stat_get_checkpointer_num_performed(PG_FUNCTION_ARGS)
{
PG_RETURN_INT64(pgstat_fetch_stat_checkpointer()->num_performed);
}
Datum Datum
pg_stat_get_checkpointer_restartpoints_timed(PG_FUNCTION_ARGS) pg_stat_get_checkpointer_restartpoints_timed(PG_FUNCTION_ARGS)
{ {

View File

@ -239,7 +239,7 @@ extern void LocalProcessControlFile(bool reset);
extern WalLevel GetActiveWalLevelOnStandby(void); extern WalLevel GetActiveWalLevelOnStandby(void);
extern void StartupXLOG(void); extern void StartupXLOG(void);
extern void ShutdownXLOG(int code, Datum arg); extern void ShutdownXLOG(int code, Datum arg);
extern void CreateCheckPoint(int flags); extern bool CreateCheckPoint(int flags);
extern bool CreateRestartPoint(int flags); extern bool CreateRestartPoint(int flags);
extern WALAvailability GetWALAvailability(XLogRecPtr targetLSN); extern WALAvailability GetWALAvailability(XLogRecPtr targetLSN);
extern void XLogPutNextOid(Oid nextOid); extern void XLogPutNextOid(Oid nextOid);

View File

@ -57,6 +57,6 @@
*/ */
/* yyyymmddN */ /* yyyymmddN */
#define CATALOG_VERSION_NO 202409271 #define CATALOG_VERSION_NO 202409301
#endif #endif

View File

@ -5820,6 +5820,11 @@
proname => 'pg_stat_get_checkpointer_num_requested', provolatile => 's', proname => 'pg_stat_get_checkpointer_num_requested', provolatile => 's',
proparallel => 'r', prorettype => 'int8', proargtypes => '', proparallel => 'r', prorettype => 'int8', proargtypes => '',
prosrc => 'pg_stat_get_checkpointer_num_requested' }, prosrc => 'pg_stat_get_checkpointer_num_requested' },
{ oid => '8599',
descr => 'statistics: number of checkpoints performed by the checkpointer',
proname => 'pg_stat_get_checkpointer_num_performed', provolatile => 's',
proparallel => 'r', prorettype => 'int8', proargtypes => '',
prosrc => 'pg_stat_get_checkpointer_num_performed' },
{ oid => '6327', { oid => '6327',
descr => 'statistics: number of timed restartpoints started by the checkpointer', descr => 'statistics: number of timed restartpoints started by the checkpointer',
proname => 'pg_stat_get_checkpointer_restartpoints_timed', provolatile => 's', proname => 'pg_stat_get_checkpointer_restartpoints_timed', provolatile => 's',

View File

@ -294,6 +294,7 @@ typedef struct PgStat_CheckpointerStats
{ {
PgStat_Counter num_timed; PgStat_Counter num_timed;
PgStat_Counter num_requested; PgStat_Counter num_requested;
PgStat_Counter num_performed;
PgStat_Counter restartpoints_timed; PgStat_Counter restartpoints_timed;
PgStat_Counter restartpoints_requested; PgStat_Counter restartpoints_requested;
PgStat_Counter restartpoints_performed; PgStat_Counter restartpoints_performed;

View File

@ -1824,6 +1824,7 @@ pg_stat_bgwriter| SELECT pg_stat_get_bgwriter_buf_written_clean() AS buffers_cle
pg_stat_get_bgwriter_stat_reset_time() AS stats_reset; pg_stat_get_bgwriter_stat_reset_time() AS stats_reset;
pg_stat_checkpointer| SELECT pg_stat_get_checkpointer_num_timed() AS num_timed, pg_stat_checkpointer| SELECT pg_stat_get_checkpointer_num_timed() AS num_timed,
pg_stat_get_checkpointer_num_requested() AS num_requested, pg_stat_get_checkpointer_num_requested() AS num_requested,
pg_stat_get_checkpointer_num_performed() AS num_done,
pg_stat_get_checkpointer_restartpoints_timed() AS restartpoints_timed, pg_stat_get_checkpointer_restartpoints_timed() AS restartpoints_timed,
pg_stat_get_checkpointer_restartpoints_requested() AS restartpoints_req, pg_stat_get_checkpointer_restartpoints_requested() AS restartpoints_req,
pg_stat_get_checkpointer_restartpoints_performed() AS restartpoints_done, pg_stat_get_checkpointer_restartpoints_performed() AS restartpoints_done,