From 1b79e74d404a97aaef62717d6b33fcf54801719e Mon Sep 17 00:00:00 2001
From: Nitin Jadhav <nitinjadhav@microsoft.com>
Date: Wed, 21 Dec 2022 10:13:58 +0000
Subject: [PATCH 1/2] Fix inconsistency in checkpointer stats

The buffers written information exposed using pg_stat_bgwriter view is having
inconsistent data compared to the checkpoint complete log message. Introduced
a new column slru_buffers_checkpoint in pg_stat_bgwriter view to show the SLRU
buffers written during checkpoints. The existing column buffers_checkpoint
remains as-is to represent the main buffers written during checkpoints.
---
 doc/src/sgml/monitoring.sgml                     | 9 +++++++++
 src/backend/access/transam/slru.c                | 3 +++
 src/backend/catalog/system_views.sql             | 1 +
 src/backend/utils/activity/pgstat_checkpointer.c | 1 +
 src/backend/utils/adt/pgstatfuncs.c              | 6 ++++++
 src/include/catalog/pg_proc.dat                  | 5 +++++
 src/include/pgstat.h                             | 1 +
 7 files changed, 26 insertions(+)

diff --git a/doc/src/sgml/monitoring.sgml b/doc/src/sgml/monitoring.sgml
index 363b183e5f..5c15a40981 100644
--- a/doc/src/sgml/monitoring.sgml
+++ b/doc/src/sgml/monitoring.sgml
@@ -3699,6 +3699,15 @@ SELECT pid, wait_event_type, wait_event FROM pg_stat_activity WHERE wait_event i
       </para></entry>
      </row>
 
+     <row>
+      <entry role="catalog_table_entry"><para role="column_definition">
+       <structfield>slru_buffers_checkpoint</structfield> <type>bigint</type>
+      </para>
+      <para>
+       Number of SLRU buffers written during checkpoints
+      </para></entry>
+     </row>
+
      <row>
       <entry role="catalog_table_entry"><para role="column_definition">
        <structfield>buffers_clean</structfield> <type>bigint</type>
diff --git a/src/backend/access/transam/slru.c b/src/backend/access/transam/slru.c
index 6feda87f57..3379e20f30 100644
--- a/src/backend/access/transam/slru.c
+++ b/src/backend/access/transam/slru.c
@@ -604,7 +604,10 @@ SlruInternalWritePage(SlruCtl ctl, int slotno, SlruWriteAll fdata)
 
 	/* If part of a checkpoint, count this as a buffer written. */
 	if (fdata)
+	{
 		CheckpointStats.ckpt_bufs_written++;
+		PendingCheckpointerStats.slru_written_checkpoints++;
+	}
 }
 
 /*
diff --git a/src/backend/catalog/system_views.sql b/src/backend/catalog/system_views.sql
index 2d8104b090..6954ad39fc 100644
--- a/src/backend/catalog/system_views.sql
+++ b/src/backend/catalog/system_views.sql
@@ -1110,6 +1110,7 @@ CREATE VIEW pg_stat_bgwriter AS
         pg_stat_get_checkpoint_write_time() AS checkpoint_write_time,
         pg_stat_get_checkpoint_sync_time() AS checkpoint_sync_time,
         pg_stat_get_bgwriter_buf_written_checkpoints() AS buffers_checkpoint,
+        pg_stat_get_bgwriter_slru_written_checkpoints() AS slru_buffers_checkpoint,
         pg_stat_get_bgwriter_buf_written_clean() AS buffers_clean,
         pg_stat_get_bgwriter_maxwritten_clean() AS maxwritten_clean,
         pg_stat_get_buf_written_backend() AS buffers_backend,
diff --git a/src/backend/utils/activity/pgstat_checkpointer.c b/src/backend/utils/activity/pgstat_checkpointer.c
index af8d513e7b..5a9245296d 100644
--- a/src/backend/utils/activity/pgstat_checkpointer.c
+++ b/src/backend/utils/activity/pgstat_checkpointer.c
@@ -52,6 +52,7 @@ pgstat_report_checkpointer(void)
 	CHECKPOINTER_ACC(checkpoint_write_time);
 	CHECKPOINTER_ACC(checkpoint_sync_time);
 	CHECKPOINTER_ACC(buf_written_checkpoints);
+	CHECKPOINTER_ACC(slru_written_checkpoints);
 	CHECKPOINTER_ACC(buf_written_backend);
 	CHECKPOINTER_ACC(buf_fsync_backend);
 #undef CHECKPOINTER_ACC
diff --git a/src/backend/utils/adt/pgstatfuncs.c b/src/backend/utils/adt/pgstatfuncs.c
index 46f98fd67f..29e7165c3f 100644
--- a/src/backend/utils/adt/pgstatfuncs.c
+++ b/src/backend/utils/adt/pgstatfuncs.c
@@ -1182,6 +1182,12 @@ pg_stat_get_bgwriter_buf_written_checkpoints(PG_FUNCTION_ARGS)
 	PG_RETURN_INT64(pgstat_fetch_stat_checkpointer()->buf_written_checkpoints);
 }
 
+Datum
+pg_stat_get_bgwriter_slru_written_checkpoints(PG_FUNCTION_ARGS)
+{
+	PG_RETURN_INT64(pgstat_fetch_stat_checkpointer()->slru_written_checkpoints);
+}
+
 Datum
 pg_stat_get_bgwriter_buf_written_clean(PG_FUNCTION_ARGS)
 {
diff --git a/src/include/catalog/pg_proc.dat b/src/include/catalog/pg_proc.dat
index 98d90d9338..8bd5425e71 100644
--- a/src/include/catalog/pg_proc.dat
+++ b/src/include/catalog/pg_proc.dat
@@ -5649,6 +5649,11 @@
   proname => 'pg_stat_get_bgwriter_buf_written_checkpoints', provolatile => 's',
   proparallel => 'r', prorettype => 'int8', proargtypes => '',
   prosrc => 'pg_stat_get_bgwriter_buf_written_checkpoints' },
+{ oid => '3813',
+  descr => 'statistics: number of SLRU buffers written by the bgwriter during checkpoints',
+  proname => 'pg_stat_get_bgwriter_slru_written_checkpoints', provolatile => 's',
+  proparallel => 'r', prorettype => 'int8', proargtypes => '',
+  prosrc => 'pg_stat_get_bgwriter_slru_written_checkpoints' },
 { oid => '2772',
   descr => 'statistics: number of buffers written by the bgwriter for cleaning dirty buffers',
   proname => 'pg_stat_get_bgwriter_buf_written_clean', provolatile => 's',
diff --git a/src/include/pgstat.h b/src/include/pgstat.h
index a3df8d27c3..3a11d23d94 100644
--- a/src/include/pgstat.h
+++ b/src/include/pgstat.h
@@ -272,6 +272,7 @@ typedef struct PgStat_CheckpointerStats
 	PgStat_Counter checkpoint_write_time;	/* times in milliseconds */
 	PgStat_Counter checkpoint_sync_time;
 	PgStat_Counter buf_written_checkpoints;
+	PgStat_Counter slru_written_checkpoints;
 	PgStat_Counter buf_written_backend;
 	PgStat_Counter buf_fsync_backend;
 } PgStat_CheckpointerStats;
-- 
2.25.1

