Inconsistency in reporting checkpointer stats
Hi,
While working on checkpoint related stuff, I have encountered that
there is some inconsistency while reporting checkpointer stats. When a
checkpoint gets completed, a checkpoint complete message gets logged.
This message has a lot of information including the buffers written
(CheckpointStats.ckpt_bufs_written). This variable gets incremented in
2 cases. First is in BufferSync() and the second is in
SlruInternalWritePage(). On the other hand the checkpointer stats
exposed using pg_stat_bgwriter contains a lot of information including
buffers written (PendingCheckpointerStats.buf_written_checkpoints).
This variable gets incremented in only one place and that is in
BufferSync(). So there is inconsistent behaviour between these two
data. Please refer to the sample output below.
postgres=# select * from pg_stat_bgwriter;
checkpoints_timed | checkpoints_req | checkpoint_write_time |
checkpoint_sync_time | buffers_checkpoint | buffers_clean |
maxwritten_clean | buffers_backend | buffers_backend_fsync |
buffers_alloc | stats_reset
-------------------+-----------------+-----------------------+----------------------+--------------------+---------------+------------------+-----------------+-----------------------+---------------+-------------------------------
0 | 1 | 75 |
176 | 4702 | 0 | 0 |
4656 | 0 | 5023 | 2022-12-14
07:01:01.494672+00
2022-12-14 07:03:18.052 UTC [6087] LOG: checkpoint starting:
immediate force wait
2022-12-14 07:03:18.370 UTC [6087] LOG: checkpoint complete: wrote
4705 buffers (28.7%); 0 WAL file(s) added, 0 removed, 4 recycled;
write=0.075 s, sync=0.176 s, total=0.318 s; sync files=34,
longest=0.159 s, average=0.006 s; distance=66180 kB, estimate=66180
kB; lsn=0/5565E38, redo lsn=0/5565E00
In order to fix this, the
PendingCheckpointerStats.buf_written_checkpoints should be incremented
in SlruInternalWritePage() similar to
CheckpointStats.ckpt_bufs_written. I have attached the patch for the
same. Please share your thoughts.
Thanks & Regards,
Nitin Jadhav
Attachments:
v1-0001-Fix-inconsistency-in-checkpointer-stats.patchapplication/octet-stream; name=v1-0001-Fix-inconsistency-in-checkpointer-stats.patchDownload
From d57655ca788b266f6ffab5fdf27aaf007803b415 Mon Sep 17 00:00:00 2001
From: Nitin Jadhav <nitinjadhav@microsoft.com>
Date: Wed, 14 Dec 2022 07:22:46 +0000
Subject: [PATCH] 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. So
incremented the counter in SlruInternalWritePage() to fix the inconsistency.
---
src/backend/access/transam/slru.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/src/backend/access/transam/slru.c b/src/backend/access/transam/slru.c
index 6feda87f57..bddc32c82f 100644
--- a/src/backend/access/transam/slru.c
+++ b/src/backend/access/transam/slru.c
@@ -605,6 +605,7 @@ 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.buf_written_checkpoints++;
}
/*
--
2.25.1
On Wed, Dec 14, 2022 at 1:02 PM Nitin Jadhav
<nitinjadhavpostgres@gmail.com> wrote:
Hi,
While working on checkpoint related stuff, I have encountered that
there is some inconsistency while reporting checkpointer stats. When a
checkpoint gets completed, a checkpoint complete message gets logged.
This message has a lot of information including the buffers written
(CheckpointStats.ckpt_bufs_written). This variable gets incremented in
2 cases. First is in BufferSync() and the second is in
SlruInternalWritePage(). On the other hand the checkpointer stats
exposed using pg_stat_bgwriter contains a lot of information including
buffers written (PendingCheckpointerStats.buf_written_checkpoints).
This variable gets incremented in only one place and that is in
BufferSync(). So there is inconsistent behaviour between these two
data. Please refer to the sample output below.In order to fix this, the
PendingCheckpointerStats.buf_written_checkpoints should be incremented
in SlruInternalWritePage() similar to
CheckpointStats.ckpt_bufs_written. I have attached the patch for the
same. Please share your thoughts.
Indeed PendingCheckpointerStats.buf_written_checkpoints needs to count
buffer writes in SlruInternalWritePage(). However, does it need to be
done immediately there? The stats will not be visible to the users
until the next pgstat_report_checkpointer(). Incrementing
buf_written_checkpoints in BufferSync() makes sense as the
pgstat_report_checkpointer() gets called in there via
CheckpointWriteDelay() and it becomes visible to the user immediately.
Have you checked if pgstat_report_checkpointer() gets called while the
checkpoint calls SlruInternalWritePage()? If not, then you can just
assign ckpt_bufs_written to buf_written_checkpoints in
LogCheckpointEnd() like its other friends
checkpoint_write_time and checkpoint_sync_time.
--
Bharath Rupireddy
PostgreSQL Contributors Team
RDS Open Source Databases
Amazon Web Services: https://aws.amazon.com
On Wed, Dec 14, 2022 at 04:54:53PM +0530, Bharath Rupireddy wrote:
Indeed PendingCheckpointerStats.buf_written_checkpoints needs to count
buffer writes in SlruInternalWritePage(). However, does it need to be
done immediately there? The stats will not be visible to the users
until the next pgstat_report_checkpointer(). Incrementing
buf_written_checkpoints in BufferSync() makes sense as the
pgstat_report_checkpointer() gets called in there via
CheckpointWriteDelay() and it becomes visible to the user immediately.
Have you checked if pgstat_report_checkpointer() gets called while the
checkpoint calls SlruInternalWritePage()? If not, then you can just
assign ckpt_bufs_written to buf_written_checkpoints in
LogCheckpointEnd() like its other friends
checkpoint_write_time and checkpoint_sync_time.
/* If part of a checkpoint, count this as a buffer written. */
if (fdata)
CheckpointStats.ckpt_bufs_written++;
+ PendingCheckpointerStats.buf_written_checkpoints++;
Also, the proposed patch would touch PendingCheckpointerStats even
when there is no fdata, aka outside the context of a checkpoint or
shutdown sequence..
--
Michael
Indeed PendingCheckpointerStats.buf_written_checkpoints needs to count
buffer writes in SlruInternalWritePage(). However, does it need to be
done immediately there? The stats will not be visible to the users
until the next pgstat_report_checkpointer(). Incrementing
buf_written_checkpoints in BufferSync() makes sense as the
pgstat_report_checkpointer() gets called in there via
CheckpointWriteDelay() and it becomes visible to the user immediately.
Have you checked if pgstat_report_checkpointer() gets called while the
checkpoint calls SlruInternalWritePage()? If not, then you can just
assign ckpt_bufs_written to buf_written_checkpoints in
LogCheckpointEnd() like its other friends
checkpoint_write_time and checkpoint_sync_time.
In case of an immediate checkpoint, the CheckpointWriteDelay() never
gets called until the checkpoint is completed. So no issues in this
case. CheckpointWriteDelay() comes into picture in case of non
immediate checkpoints (i.e. checkpoint timeout is reached or max wal
size is reached). If we remove the increment in BufferSync() and
SlruInternalWritePage() and then just assign ckpt_bufs_written to
buf_written_checkpoints in LogCheckpointEnd() then the update will be
available after the end of each checkpoint which is not better than
the existing behaviour (without patch). If we keep the increment in
BufferSync() then we have to calculate the remaining buffer
incremented in SlruInternalWritePage() and then increment
buf_written_checkpoints with this number in LogCheckpointEnd(). This
just makes it complicated and again the buffer incremented in
SlruInternalWritePage() will get updated at the end of the checkpoint.
In the case of checkpoint_write_time and checkpoint_sync_time, it
makes sense because this information is based on the entire checkpoint
operation and it should be done at the end. So I feel the patch
handles it in a better way even though the
pgstat_report_checkpointer() does not get called immediately but it
will be called during the next increment in BufferSync() which is
before the end of the checkpoint. Please share if you have any other
ideas.
On Wed, Dec 14, 2022 at 4:55 PM Bharath Rupireddy
<bharath.rupireddyforpostgres@gmail.com> wrote:
Show quoted text
On Wed, Dec 14, 2022 at 1:02 PM Nitin Jadhav
<nitinjadhavpostgres@gmail.com> wrote:Hi,
While working on checkpoint related stuff, I have encountered that
there is some inconsistency while reporting checkpointer stats. When a
checkpoint gets completed, a checkpoint complete message gets logged.
This message has a lot of information including the buffers written
(CheckpointStats.ckpt_bufs_written). This variable gets incremented in
2 cases. First is in BufferSync() and the second is in
SlruInternalWritePage(). On the other hand the checkpointer stats
exposed using pg_stat_bgwriter contains a lot of information including
buffers written (PendingCheckpointerStats.buf_written_checkpoints).
This variable gets incremented in only one place and that is in
BufferSync(). So there is inconsistent behaviour between these two
data. Please refer to the sample output below.In order to fix this, the
PendingCheckpointerStats.buf_written_checkpoints should be incremented
in SlruInternalWritePage() similar to
CheckpointStats.ckpt_bufs_written. I have attached the patch for the
same. Please share your thoughts.Indeed PendingCheckpointerStats.buf_written_checkpoints needs to count
buffer writes in SlruInternalWritePage(). However, does it need to be
done immediately there? The stats will not be visible to the users
until the next pgstat_report_checkpointer(). Incrementing
buf_written_checkpoints in BufferSync() makes sense as the
pgstat_report_checkpointer() gets called in there via
CheckpointWriteDelay() and it becomes visible to the user immediately.
Have you checked if pgstat_report_checkpointer() gets called while the
checkpoint calls SlruInternalWritePage()? If not, then you can just
assign ckpt_bufs_written to buf_written_checkpoints in
LogCheckpointEnd() like its other friends
checkpoint_write_time and checkpoint_sync_time.--
Bharath Rupireddy
PostgreSQL Contributors Team
RDS Open Source Databases
Amazon Web Services: https://aws.amazon.com
/* If part of a checkpoint, count this as a buffer written. */
if (fdata)
CheckpointStats.ckpt_bufs_written++;
+ PendingCheckpointerStats.buf_written_checkpoints++;
Also, the proposed patch would touch PendingCheckpointerStats even
when there is no fdata, aka outside the context of a checkpoint or
shutdown sequence.
Sorry. I missed adding braces. Fixed in the v2 patch attached.
Thanks & Regards,
Nitin Jadhav
Show quoted text
On Thu, Dec 15, 2022 at 3:16 AM Michael Paquier <michael@paquier.xyz> wrote:
On Wed, Dec 14, 2022 at 04:54:53PM +0530, Bharath Rupireddy wrote:
Indeed PendingCheckpointerStats.buf_written_checkpoints needs to count
buffer writes in SlruInternalWritePage(). However, does it need to be
done immediately there? The stats will not be visible to the users
until the next pgstat_report_checkpointer(). Incrementing
buf_written_checkpoints in BufferSync() makes sense as the
pgstat_report_checkpointer() gets called in there via
CheckpointWriteDelay() and it becomes visible to the user immediately.
Have you checked if pgstat_report_checkpointer() gets called while the
checkpoint calls SlruInternalWritePage()? If not, then you can just
assign ckpt_bufs_written to buf_written_checkpoints in
LogCheckpointEnd() like its other friends
checkpoint_write_time and checkpoint_sync_time./* If part of a checkpoint, count this as a buffer written. */ if (fdata) CheckpointStats.ckpt_bufs_written++; + PendingCheckpointerStats.buf_written_checkpoints++; Also, the proposed patch would touch PendingCheckpointerStats even when there is no fdata, aka outside the context of a checkpoint or shutdown sequence.. -- Michael
Attachments:
v2-0001-Fix-inconsistency-in-checkpointer-stats.patchapplication/octet-stream; name=v2-0001-Fix-inconsistency-in-checkpointer-stats.patchDownload
From 555f280f36c8c8fc0927596610672b5a6898c3e7 Mon Sep 17 00:00:00 2001
From: Nitin Jadhav <nitinjadhav@microsoft.com>
Date: Thu, 15 Dec 2022 10:03:48 +0000
Subject: [PATCH] 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. So
incremented the counter in SlruInternalWritePage() to fix the inconsistency.
---
src/backend/access/transam/slru.c | 3 +++
1 file changed, 3 insertions(+)
diff --git a/src/backend/access/transam/slru.c b/src/backend/access/transam/slru.c
index 6feda87f57..de23f1d673 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.buf_written_checkpoints++;
+ }
}
/*
--
2.25.1
At Wed, 14 Dec 2022 16:54:53 +0530, Bharath Rupireddy <bharath.rupireddyforpostgres@gmail.com> wrote in
Indeed PendingCheckpointerStats.buf_written_checkpoints needs to count
buffer writes in SlruInternalWritePage(). However, does it need to be
done immediately there? The stats will not be visible to the users
until the next pgstat_report_checkpointer(). Incrementing
buf_written_checkpoints in BufferSync() makes sense as the
pgstat_report_checkpointer() gets called in there via
CheckpointWriteDelay() and it becomes visible to the user immediately.
Have you checked if pgstat_report_checkpointer() gets called while the
checkpoint calls SlruInternalWritePage()? If not, then you can just
assign ckpt_bufs_written to buf_written_checkpoints in
LogCheckpointEnd() like its other friends
checkpoint_write_time and checkpoint_sync_time.
If I'm getting Bharath correctly, it results in double counting of
BufferSync. If we want to keep the realtime-reporting nature of
BufferSync, BufferSync should give up to increment CheckPointerStats'
counter. Such separation seems to be a kind of stupid and quite
bug-prone.
In the first place I don't like that we count the same things twice.
Couldn't we count the number only by any one of them?
If we remove CheckPointerStats.ckpt_bufs_written, CreateCheckPoint can
get the final number as the difference between the start-end values of
*the shared stats*. As long as a checkpoint runs on a single process,
trace info in BufferSync will work fine. Assuming single process
checkpointing there must be no problem to do that. (Anyway the current
shared stats update for checkpointer is assuming single-process).
Otherwise, in exchange with giving up the realtime nature, we can
count the number only by CheckPointerStats.ckpt_bufs_written.
regards.
--
Kyotaro Horiguchi
NTT Open Source Software Center
On Fri, Dec 16, 2022 at 2:14 PM Kyotaro Horiguchi
<horikyota.ntt@gmail.com> wrote:
In the first place I don't like that we count the same things twice.
Couldn't we count the number only by any one of them?If we remove CheckPointerStats.ckpt_bufs_written, CreateCheckPoint can
get the final number as the difference between the start-end values of
*the shared stats*. As long as a checkpoint runs on a single process,
trace info in BufferSync will work fine. Assuming single process
checkpointing there must be no problem to do that. (Anyway the current
shared stats update for checkpointer is assuming single-process).
What if someone resets checkpointer shared stats with
pg_stat_reset_shared()? In such a case, the checkpoint complete
message will not have the stats, no?
--
Bharath Rupireddy
PostgreSQL Contributors Team
RDS Open Source Databases
Amazon Web Services: https://aws.amazon.com
On Wed, Dec 14, 2022 at 2:32 AM Nitin Jadhav
<nitinjadhavpostgres@gmail.com> wrote:
In order to fix this, the
PendingCheckpointerStats.buf_written_checkpoints should be incremented
in SlruInternalWritePage() similar to
CheckpointStats.ckpt_bufs_written. I have attached the patch for the
same. Please share your thoughts.
Presumably we could make this consistent either by counting SLRU
writes in both places, or by counting them in neither place. This
proposal would count them in both places. But why is that the right
thing to do?
I'm somewhat inclined to think that we should use "buffers" to mean
regular data buffers, and if SLRU buffers also need to be counted, we
ought to make that a separate counter. Or just leave it out
altogether.
This is arguable, though, for sure....
--
Robert Haas
EDB: http://www.enterprisedb.com
Presumably we could make this consistent either by counting SLRU
writes in both places, or by counting them in neither place. This
proposal would count them in both places. But why is that the right
thing to do?I'm somewhat inclined to think that we should use "buffers" to mean
regular data buffers, and if SLRU buffers also need to be counted, we
ought to make that a separate counter. Or just leave it out
altogether.This is arguable, though, for sure....
Thanks Robert for sharing your thoughts.
My first thought was to just remove counting SLRU buffers, then after
some more analysis, I found that the checkpointer is responsible for
including both regular data buffers and SLRU buffers. Please refer to
dee663f7843902535a15ae366cede8b4089f1144 commit for more information.
The part of the commit message is included here [1]Hoist ProcessSyncRequests() up into CheckPointGuts() to make it clearer that it applies to all the SLRU mini-buffer-pools as well as the main buffer pool. Rearrange things so that data collected in CheckpointStats includes SLRU activity. for quick
reference. Hence I concluded to keep the information and added an
increment to count SLRU buffers. I am not in favour of making this as
a separate counter as this can be treated as little low level
information and it just adds up in the stats. Please share your
thoughts.
[1]: Hoist ProcessSyncRequests() up into CheckPointGuts() to make it clearer that it applies to all the SLRU mini-buffer-pools as well as the main buffer pool. Rearrange things so that data collected in CheckpointStats includes SLRU activity.
Hoist ProcessSyncRequests() up into CheckPointGuts() to make it clearer
that it applies to all the SLRU mini-buffer-pools as well as the main
buffer pool. Rearrange things so that data collected in CheckpointStats
includes SLRU activity.
Thanks & Regards,
Nitin Jadhav
Show quoted text
On Tue, Dec 20, 2022 at 2:38 AM Robert Haas <robertmhaas@gmail.com> wrote:
On Wed, Dec 14, 2022 at 2:32 AM Nitin Jadhav
<nitinjadhavpostgres@gmail.com> wrote:In order to fix this, the
PendingCheckpointerStats.buf_written_checkpoints should be incremented
in SlruInternalWritePage() similar to
CheckpointStats.ckpt_bufs_written. I have attached the patch for the
same. Please share your thoughts.Presumably we could make this consistent either by counting SLRU
writes in both places, or by counting them in neither place. This
proposal would count them in both places. But why is that the right
thing to do?I'm somewhat inclined to think that we should use "buffers" to mean
regular data buffers, and if SLRU buffers also need to be counted, we
ought to make that a separate counter. Or just leave it out
altogether.This is arguable, though, for sure....
--
Robert Haas
EDB: http://www.enterprisedb.com
On Tue, Dec 20, 2022 at 8:03 AM Nitin Jadhav
<nitinjadhavpostgres@gmail.com> wrote:
Thanks Robert for sharing your thoughts.
My first thought was to just remove counting SLRU buffers, then after
some more analysis, I found that the checkpointer is responsible for
including both regular data buffers and SLRU buffers.
I know that, but what the checkpointer handles and what ought to be
included in the stats are two separate questions.
I think that the SLRU information is potentially useful, but mixing it
with the information about regular buffers just seems confusing.
--
Robert Haas
EDB: http://www.enterprisedb.com
On 2022-12-20 08:18:36 -0500, Robert Haas wrote:
I think that the SLRU information is potentially useful, but mixing it
with the information about regular buffers just seems confusing.
+1
At least for now, it'd be different if/when we manage to move SLRUs to
the main buffer pool.
- Andres
On Tue, Dec 20, 2022 at 11:08 PM Andres Freund <andres@anarazel.de> wrote:
On 2022-12-20 08:18:36 -0500, Robert Haas wrote:
I think that the SLRU information is potentially useful, but mixing it
with the information about regular buffers just seems confusing.+1
At least for now, it'd be different if/when we manage to move SLRUs to
the main buffer pool.
+1 to not count SLRU writes in ckpt_bufs_written. If needed we can
have new fields CheckpointStats.ckpt_slru_bufs_written and
PendingCheckpointerStats.slru_buf_written_checkpoint.
--
Bharath Rupireddy
PostgreSQL Contributors Team
RDS Open Source Databases
Amazon Web Services: https://aws.amazon.com
Thanks Robert and Andres for sharing your thoughts.
I have modified the code accordingly and attached the new version of
patches. patch 0001 fixes the inconsistency in checkpointer stats and
patch 0002 separates main buffer and SLRU buffer count from checkpoint
complete log message. In 0001, I added a new column to
pg_stat_bgwriter view and named it as slru_buffers_checkpoint and kept
the existing column buffers_checkpoint as-is. Should I rename this to
something like main_buffers_checkpoint? Thoughts?
Please refer to sample checkpoint complete log message[1]2022-12-21 10:52:25.931 UTC [63530] LOG: checkpoint complete: wrote 4670 buffers (28.5%), wrote 3 slru buffers (0.0%); 0 WAL file(s) added, 0 removed, 4 recycled; write=0.045 s, sync=0.161 s, total=0.244 s; sync files=25, longest=0.146 s, average=0.007 s; distance=66130 kB, estimate=66130 kB; lsn=0/5557C78, redo lsn=0/5557C40. I am not
quite satisfied with the percentage of buffers written information
logged there. The percentage is calculated based on NBuffers in both
the cases but I am just worried that are we passing wrong information
to the user while user may
think that the percentage of buffers is based on the total number of
buffers available and the percentage of SLRU buffers is based on the
total number of SLRU buffers available.
Kindly review and share your comments.
[1]: 2022-12-21 10:52:25.931 UTC [63530] LOG: checkpoint complete: wrote 4670 buffers (28.5%), wrote 3 slru buffers (0.0%); 0 WAL file(s) added, 0 removed, 4 recycled; write=0.045 s, sync=0.161 s, total=0.244 s; sync files=25, longest=0.146 s, average=0.007 s; distance=66130 kB, estimate=66130 kB; lsn=0/5557C78, redo lsn=0/5557C40
2022-12-21 10:52:25.931 UTC [63530] LOG: checkpoint complete: wrote
4670 buffers (28.5%), wrote 3 slru buffers (0.0%); 0 WAL file(s)
added, 0 removed, 4 recycled; write=0.045 s, sync=0.161 s, total=0.244
s; sync files=25, longest=0.146 s, average=0.007 s; distance=66130 kB,
estimate=66130 kB; lsn=0/5557C78, redo lsn=0/5557C40
Thanks & Regards,
Nitin Jadhav
Show quoted text
On Tue, Dec 20, 2022 at 11:08 PM Andres Freund <andres@anarazel.de> wrote:
On 2022-12-20 08:18:36 -0500, Robert Haas wrote:
I think that the SLRU information is potentially useful, but mixing it
with the information about regular buffers just seems confusing.+1
At least for now, it'd be different if/when we manage to move SLRUs to
the main buffer pool.- Andres
Attachments:
v3-0002-Separate-main-buffer-and-SLRU-buffer-count-from-chec.patchapplication/octet-stream; name=v3-0002-Separate-main-buffer-and-SLRU-buffer-count-from-chec.patchDownload
From 4a78d3a9448625ce817f5ae683c475ee6f0294e2 Mon Sep 17 00:00:00 2001
From: Nitin Jadhav <nitinjadhav@microsoft.com>
Date: Wed, 21 Dec 2022 11:03:57 +0000
Subject: [PATCH 2/2] Separate main buffer and SLRU buffer count from
checkpoint complete log message
The buffers written information logged in checkpoint complete log message
includes main buffer count as well as SLRU buffer count. This patch separates
these two information.
---
src/backend/access/transam/slru.c | 2 +-
src/backend/access/transam/xlog.c | 28 ++++++++++++++++------------
src/include/access/xlog.h | 1 +
3 files changed, 18 insertions(+), 13 deletions(-)
diff --git a/src/backend/access/transam/slru.c b/src/backend/access/transam/slru.c
index 3379e20f30..714842cc1c 100644
--- a/src/backend/access/transam/slru.c
+++ b/src/backend/access/transam/slru.c
@@ -605,7 +605,7 @@ SlruInternalWritePage(SlruCtl ctl, int slotno, SlruWriteAll fdata)
/* If part of a checkpoint, count this as a buffer written. */
if (fdata)
{
- CheckpointStats.ckpt_bufs_written++;
+ CheckpointStats.ckpt_slru_written++;
PendingCheckpointerStats.slru_written_checkpoints++;
}
}
diff --git a/src/backend/access/transam/xlog.c b/src/backend/access/transam/xlog.c
index 91473b00d9..0f13b19ade 100644
--- a/src/backend/access/transam/xlog.c
+++ b/src/backend/access/transam/xlog.c
@@ -6280,14 +6280,16 @@ LogCheckpointEnd(bool restartpoint)
*/
if (restartpoint)
ereport(LOG,
- (errmsg("restartpoint complete: wrote %d buffers (%.1f%%); "
- "%d WAL file(s) added, %d removed, %d recycled; "
- "write=%ld.%03d s, sync=%ld.%03d s, total=%ld.%03d s; "
- "sync files=%d, longest=%ld.%03d s, average=%ld.%03d s; "
- "distance=%d kB, estimate=%d kB; "
- "lsn=%X/%X, redo lsn=%X/%X",
+ (errmsg("restartpoint complete: wrote %d buffers (%.1f%%), "
+ "wrote %d slru buffers (%.1f%%); %d WAL file(s) added, "
+ "%d removed, %d recycled; write=%ld.%03d s, "
+ "sync=%ld.%03d s, total=%ld.%03d s; sync files=%d, "
+ "longest=%ld.%03d s, average=%ld.%03d s; distance=%d kB, "
+ "estimate=%d kB; lsn=%X/%X, redo lsn=%X/%X",
CheckpointStats.ckpt_bufs_written,
(double) CheckpointStats.ckpt_bufs_written * 100 / NBuffers,
+ CheckpointStats.ckpt_slru_written,
+ (double) CheckpointStats.ckpt_slru_written * 100 / NBuffers,
CheckpointStats.ckpt_segs_added,
CheckpointStats.ckpt_segs_removed,
CheckpointStats.ckpt_segs_recycled,
@@ -6303,14 +6305,16 @@ LogCheckpointEnd(bool restartpoint)
LSN_FORMAT_ARGS(ControlFile->checkPointCopy.redo))));
else
ereport(LOG,
- (errmsg("checkpoint complete: wrote %d buffers (%.1f%%); "
- "%d WAL file(s) added, %d removed, %d recycled; "
- "write=%ld.%03d s, sync=%ld.%03d s, total=%ld.%03d s; "
- "sync files=%d, longest=%ld.%03d s, average=%ld.%03d s; "
- "distance=%d kB, estimate=%d kB; "
- "lsn=%X/%X, redo lsn=%X/%X",
+ (errmsg("checkpoint complete: wrote %d buffers (%.1f%%), "
+ "wrote %d slru buffers (%.1f%%); %d WAL file(s) added, "
+ "%d removed, %d recycled; write=%ld.%03d s, "
+ "sync=%ld.%03d s, total=%ld.%03d s; sync files=%d, "
+ "longest=%ld.%03d s, average=%ld.%03d s; distance=%d kB, "
+ "estimate=%d kB; lsn=%X/%X, redo lsn=%X/%X",
CheckpointStats.ckpt_bufs_written,
(double) CheckpointStats.ckpt_bufs_written * 100 / NBuffers,
+ CheckpointStats.ckpt_slru_written,
+ (double) CheckpointStats.ckpt_slru_written * 100 / NBuffers,
CheckpointStats.ckpt_segs_added,
CheckpointStats.ckpt_segs_removed,
CheckpointStats.ckpt_segs_recycled,
diff --git a/src/include/access/xlog.h b/src/include/access/xlog.h
index 1fbd48fbda..9b6d7cfe57 100644
--- a/src/include/access/xlog.h
+++ b/src/include/access/xlog.h
@@ -162,6 +162,7 @@ typedef struct CheckpointStatsData
TimestampTz ckpt_end_t; /* end of checkpoint */
int ckpt_bufs_written; /* # of buffers written */
+ int ckpt_slru_written; /* # of SLRU buffers written */
int ckpt_segs_added; /* # of new xlog segments created */
int ckpt_segs_removed; /* # of xlog segments deleted */
--
2.25.1
v3-0001-Fix-inconsistency-in-checkpointer-stats.patchapplication/octet-stream; name=v3-0001-Fix-inconsistency-in-checkpointer-stats.patchDownload
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
At Mon, 19 Dec 2022 18:05:38 +0530, Bharath Rupireddy <bharath.rupireddyforpostgres@gmail.com> wrote in
On Fri, Dec 16, 2022 at 2:14 PM Kyotaro Horiguchi
<horikyota.ntt@gmail.com> wrote:In the first place I don't like that we count the same things twice.
Couldn't we count the number only by any one of them?If we remove CheckPointerStats.ckpt_bufs_written, CreateCheckPoint can
get the final number as the difference between the start-end values of
*the shared stats*. As long as a checkpoint runs on a single process,
trace info in BufferSync will work fine. Assuming single process
checkpointing there must be no problem to do that. (Anyway the current
shared stats update for checkpointer is assuming single-process).What if someone resets checkpointer shared stats with
pg_stat_reset_shared()? In such a case, the checkpoint complete
message will not have the stats, no?
I don't know. I don't believe the stats system doesn't follow such a
strict resetting policy.
regards.
--
Kyotaro Horiguchi
NTT Open Source Software Center
At Wed, 21 Dec 2022 17:14:12 +0530, Nitin Jadhav <nitinjadhavpostgres@gmail.com> wrote in
[1]:
2022-12-21 10:52:25.931 UTC [63530] LOG: checkpoint complete: wrote
4670 buffers (28.5%), wrote 3 slru buffers (0.0%); 0 WAL file(s)
added, 0 removed, 4 recycled; write=0.045 s, sync=0.161 s, total=0.244
s; sync files=25, longest=0.146 s, average=0.007 s; distance=66130 kB,
estimate=66130 kB; lsn=0/5557C78, redo lsn=0/5557C40Thanks & Regards,
Nitin JadhavOn Tue, Dec 20, 2022 at 11:08 PM Andres Freund <andres@anarazel.de> wrote:
On 2022-12-20 08:18:36 -0500, Robert Haas wrote:
I think that the SLRU information is potentially useful, but mixing it
with the information about regular buffers just seems confusing.+1
At least for now, it'd be different if/when we manage to move SLRUs to
the main buffer pool.
It sounds reasonable to exclude SRLU write from buffer writes. But I'm
not sure its useful to count SLRU writes separately since it is under
the noise level of buffer writes in reglular cases and the value
doesn't lead to tuning. However I'm not strongly opposed to adding it
either.
regards.
--
Kyotaro Horiguchi
NTT Open Source Software Center
On Wed, Dec 21, 2022 at 5:15 PM Nitin Jadhav
<nitinjadhavpostgres@gmail.com> wrote:
I have modified the code accordingly and attached the new version of
patches. patch 0001 fixes the inconsistency in checkpointer stats and
patch 0002 separates main buffer and SLRU buffer count from checkpoint
complete log message.
IMO, there's no need for 2 separate patches for these changes.
+ (errmsg("restartpoint complete: wrote %d buffers (%.1f%%), "
+ "wrote %d slru buffers (%.1f%%); %d WAL
file(s) added, "
+ "%d removed, %d recycled; write=%ld.%03d s, "
+ "sync=%ld.%03d s, total=%ld.%03d s; sync files=%d, "
+ "longest=%ld.%03d s, average=%ld.%03d s;
distance=%d kB, "
+ "estimate=%d kB; lsn=%X/%X, redo lsn=%X/%X",
Hm, restartpoint /checkpoint complete message is already too long to
read and adding slru buffers to it make it further longer. Note that
we don't need to add every checkpoint stat to the log message but to
pg_stat_bgwriter. Isn't it enough to show SLRU buffers information in
pg_stat_bgwriter alone?
Can't one look at pg_stat_slru's blks_written
(pgstat_count_slru_page_written()) to really track the SLRUs written?
Or is it that one may want to track SLRUs during a checkpoint
separately? Is there a real use-case/customer reported issue driving
this change?
After looking at pg_stat_slru.blks_written, I think the best way is to
just leave things as-is and let CheckpointStats count slru buffers too
unless there's really a reported issue that says
pg_stat_slru.blks_written doesn't serve the purpose.
--
Bharath Rupireddy
PostgreSQL Contributors Team
RDS Open Source Databases
Amazon Web Services: https://aws.amazon.com
IMO, there's no need for 2 separate patches for these changes.
I will make it a single patch while sharing the next patch.
+ (errmsg("restartpoint complete: wrote %d buffers (%.1f%%), " + "wrote %d slru buffers (%.1f%%); %d WAL file(s) added, " + "%d removed, %d recycled; write=%ld.%03d s, " + "sync=%ld.%03d s, total=%ld.%03d s; sync files=%d, " + "longest=%ld.%03d s, average=%ld.%03d s; distance=%d kB, " + "estimate=%d kB; lsn=%X/%X, redo lsn=%X/%X", Hm, restartpoint /checkpoint complete message is already too long to read and adding slru buffers to it make it further longer. Note that we don't need to add every checkpoint stat to the log message but to pg_stat_bgwriter. Isn't it enough to show SLRU buffers information in pg_stat_bgwriter alone?
I understand that the log message is too long already but I feel it is
ok since it logs only one time per checkpoint and as discussed
upthread, SLRU information is potentially useful.
Can't one look at pg_stat_slru's blks_written
(pgstat_count_slru_page_written()) to really track the SLRUs written?
Or is it that one may want to track SLRUs during a checkpoint
separately? Is there a real use-case/customer reported issue driving
this change?After looking at pg_stat_slru.blks_written, I think the best way is to
just leave things as-is and let CheckpointStats count slru buffers too
unless there's really a reported issue that says
pg_stat_slru.blks_written doesn't serve the purpose.
The v1 patch corresponds to what you are suggesting. But the question
is not about tracking slru buffers, it is about separating this
information from main buffers count during checkpoint. I think there
is enough discussion done upthread to exclude slru buffers from
CheckpointStats.ckpt_bufs_written. Please share if you still strongly
feel that a separate counter is not required.
Thanks & Regards,
Nitin Jadhav
On Fri, Jan 27, 2023 at 10:45 AM Bharath Rupireddy
<bharath.rupireddyforpostgres@gmail.com> wrote:
Show quoted text
On Wed, Dec 21, 2022 at 5:15 PM Nitin Jadhav
<nitinjadhavpostgres@gmail.com> wrote:I have modified the code accordingly and attached the new version of
patches. patch 0001 fixes the inconsistency in checkpointer stats and
patch 0002 separates main buffer and SLRU buffer count from checkpoint
complete log message.IMO, there's no need for 2 separate patches for these changes.
+ (errmsg("restartpoint complete: wrote %d buffers (%.1f%%), " + "wrote %d slru buffers (%.1f%%); %d WAL file(s) added, " + "%d removed, %d recycled; write=%ld.%03d s, " + "sync=%ld.%03d s, total=%ld.%03d s; sync files=%d, " + "longest=%ld.%03d s, average=%ld.%03d s; distance=%d kB, " + "estimate=%d kB; lsn=%X/%X, redo lsn=%X/%X", Hm, restartpoint /checkpoint complete message is already too long to read and adding slru buffers to it make it further longer. Note that we don't need to add every checkpoint stat to the log message but to pg_stat_bgwriter. Isn't it enough to show SLRU buffers information in pg_stat_bgwriter alone?Can't one look at pg_stat_slru's blks_written
(pgstat_count_slru_page_written()) to really track the SLRUs written?
Or is it that one may want to track SLRUs during a checkpoint
separately? Is there a real use-case/customer reported issue driving
this change?After looking at pg_stat_slru.blks_written, I think the best way is to
just leave things as-is and let CheckpointStats count slru buffers too
unless there's really a reported issue that says
pg_stat_slru.blks_written doesn't serve the purpose.--
Bharath Rupireddy
PostgreSQL Contributors Team
RDS Open Source Databases
Amazon Web Services: https://aws.amazon.com
On 2022-12-21 17:14:12 +0530, Nitin Jadhav wrote:
Kindly review and share your comments.
This doesn't pass the tests, because the regression tests weren't adjusted:
This doesn't pass the tests, because the regression tests weren't adjusted:
https://api.cirrus-ci.com/v1/artifact/task/5937624817336320/testrun/build/testrun/regress/regress/regression.diffs
Thanks for sharing this. I have fixed this in the patch attached.
IMO, there's no need for 2 separate patches for these changes.
I will make it a single patch while sharing the next patch.
Clubbed both patches into one.
Thanks & Regards,
Nitin Jadhav
Show quoted text
On Tue, Feb 14, 2023 at 6:08 AM Andres Freund <andres@anarazel.de> wrote:
On 2022-12-21 17:14:12 +0530, Nitin Jadhav wrote:
Kindly review and share your comments.
This doesn't pass the tests, because the regression tests weren't adjusted:
Attachments:
v4-0001-Fix-inconsistency-in-reporting-checkpointer-stats.patchapplication/octet-stream; name=v4-0001-Fix-inconsistency-in-reporting-checkpointer-stats.patchDownload
From f4b4a9a6c3ce60b343e799071f6f974a9066ec00 Mon Sep 17 00:00:00 2001
From: Nitin Jadhav <nitinjadhav@microsoft.com>
Date: Sun, 19 Feb 2023 15:11:16 +0530
Subject: [PATCH] Fix inconsistency in reporting 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. Also
the buffers written information logged in checkpoint complete log message
includes main buffer count as well as SLRU buffer count. This patch separates
these two information.
---
doc/src/sgml/monitoring.sgml | 9 ++++++
src/backend/access/transam/slru.c | 5 +++-
src/backend/access/transam/xlog.c | 28 +++++++++++--------
src/backend/catalog/system_views.sql | 1 +
.../utils/activity/pgstat_checkpointer.c | 1 +
src/backend/utils/adt/pgstatfuncs.c | 6 ++++
src/include/access/xlog.h | 1 +
src/include/catalog/pg_proc.dat | 5 ++++
src/include/pgstat.h | 1 +
src/test/regress/expected/rules.out | 1 +
10 files changed, 45 insertions(+), 13 deletions(-)
diff --git a/doc/src/sgml/monitoring.sgml b/doc/src/sgml/monitoring.sgml
index b0b997f092..d1be6f512a 100644
--- a/doc/src/sgml/monitoring.sgml
+++ b/doc/src/sgml/monitoring.sgml
@@ -4045,6 +4045,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 5ab86238a9..76c202eccf 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++;
+ {
+ CheckpointStats.ckpt_slru_written++;
+ PendingCheckpointerStats.slru_written_checkpoints++;
+ }
}
/*
diff --git a/src/backend/access/transam/xlog.c b/src/backend/access/transam/xlog.c
index f9f0f6db8d..3a55a5dd27 100644
--- a/src/backend/access/transam/xlog.c
+++ b/src/backend/access/transam/xlog.c
@@ -6282,14 +6282,16 @@ LogCheckpointEnd(bool restartpoint)
*/
if (restartpoint)
ereport(LOG,
- (errmsg("restartpoint complete: wrote %d buffers (%.1f%%); "
- "%d WAL file(s) added, %d removed, %d recycled; "
- "write=%ld.%03d s, sync=%ld.%03d s, total=%ld.%03d s; "
- "sync files=%d, longest=%ld.%03d s, average=%ld.%03d s; "
- "distance=%d kB, estimate=%d kB; "
- "lsn=%X/%X, redo lsn=%X/%X",
+ (errmsg("restartpoint complete: wrote %d buffers (%.1f%%), "
+ "wrote %d slru buffers (%.1f%%); %d WAL file(s) added, "
+ "%d removed, %d recycled; write=%ld.%03d s, "
+ "sync=%ld.%03d s, total=%ld.%03d s; sync files=%d, "
+ "longest=%ld.%03d s, average=%ld.%03d s; distance=%d kB, "
+ "estimate=%d kB; lsn=%X/%X, redo lsn=%X/%X",
CheckpointStats.ckpt_bufs_written,
(double) CheckpointStats.ckpt_bufs_written * 100 / NBuffers,
+ CheckpointStats.ckpt_slru_written,
+ (double) CheckpointStats.ckpt_slru_written * 100 / NBuffers,
CheckpointStats.ckpt_segs_added,
CheckpointStats.ckpt_segs_removed,
CheckpointStats.ckpt_segs_recycled,
@@ -6305,14 +6307,16 @@ LogCheckpointEnd(bool restartpoint)
LSN_FORMAT_ARGS(ControlFile->checkPointCopy.redo))));
else
ereport(LOG,
- (errmsg("checkpoint complete: wrote %d buffers (%.1f%%); "
- "%d WAL file(s) added, %d removed, %d recycled; "
- "write=%ld.%03d s, sync=%ld.%03d s, total=%ld.%03d s; "
- "sync files=%d, longest=%ld.%03d s, average=%ld.%03d s; "
- "distance=%d kB, estimate=%d kB; "
- "lsn=%X/%X, redo lsn=%X/%X",
+ (errmsg("checkpoint complete: wrote %d buffers (%.1f%%), "
+ "wrote %d slru buffers (%.1f%%); %d WAL file(s) added, "
+ "%d removed, %d recycled; write=%ld.%03d s, "
+ "sync=%ld.%03d s, total=%ld.%03d s; sync files=%d, "
+ "longest=%ld.%03d s, average=%ld.%03d s; distance=%d kB, "
+ "estimate=%d kB; lsn=%X/%X, redo lsn=%X/%X",
CheckpointStats.ckpt_bufs_written,
(double) CheckpointStats.ckpt_bufs_written * 100 / NBuffers,
+ CheckpointStats.ckpt_slru_written,
+ (double) CheckpointStats.ckpt_slru_written * 100 / NBuffers,
CheckpointStats.ckpt_segs_added,
CheckpointStats.ckpt_segs_removed,
CheckpointStats.ckpt_segs_recycled,
diff --git a/src/backend/catalog/system_views.sql b/src/backend/catalog/system_views.sql
index 34ca0e739f..415b71264f 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 26dec112f6..b2a9cd0b4c 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 9d707c3521..45b7cfdf9f 100644
--- a/src/backend/utils/adt/pgstatfuncs.c
+++ b/src/backend/utils/adt/pgstatfuncs.c
@@ -1193,6 +1193,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/access/xlog.h b/src/include/access/xlog.h
index cfe5409738..669235c4e7 100644
--- a/src/include/access/xlog.h
+++ b/src/include/access/xlog.h
@@ -162,6 +162,7 @@ typedef struct CheckpointStatsData
TimestampTz ckpt_end_t; /* end of checkpoint */
int ckpt_bufs_written; /* # of buffers written */
+ int ckpt_slru_written; /* # of SLRU buffers written */
int ckpt_segs_added; /* # of new xlog segments created */
int ckpt_segs_removed; /* # of xlog segments deleted */
diff --git a/src/include/catalog/pg_proc.dat b/src/include/catalog/pg_proc.dat
index 66b73c3900..0bca329587 100644
--- a/src/include/catalog/pg_proc.dat
+++ b/src/include/catalog/pg_proc.dat
@@ -5680,6 +5680,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 db9675884f..380dd1ad4e 100644
--- a/src/include/pgstat.h
+++ b/src/include/pgstat.h
@@ -273,6 +273,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;
diff --git a/src/test/regress/expected/rules.out b/src/test/regress/expected/rules.out
index a3a5a62329..85c40faa98 100644
--- a/src/test/regress/expected/rules.out
+++ b/src/test/regress/expected/rules.out
@@ -1819,6 +1819,7 @@ pg_stat_bgwriter| SELECT pg_stat_get_bgwriter_timed_checkpoints() AS checkpoints
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,
--
2.34.1
On Sun, 19 Feb 2023 at 04:58, Nitin Jadhav
<nitinjadhavpostgres@gmail.com> wrote:
This doesn't pass the tests, because the regression tests weren't adjusted:
https://api.cirrus-ci.com/v1/artifact/task/5937624817336320/testrun/build/testrun/regress/regress/regression.diffsThanks for sharing this. I have fixed this in the patch attached.
AFAICS this patch was marked Waiting on Author due to this feedback on
Feb 14 but the patch was updated Feb 19 and is still passing today.
I've marked it Needs Review.
I'm not sure if all of the feedback from Bharath Rupireddy and Kyotaro
Horiguchi was addressed.
If there's any specific questions remaining you need feedback on it
would be good to ask explicitly. Otherwise if you think it's ready you
could mark it Ready for Commit.
--
Gregory Stark
As Commitfest Manager
On Sun, 19 Feb 2023 at 15:28, Nitin Jadhav
<nitinjadhavpostgres@gmail.com> wrote:
This doesn't pass the tests, because the regression tests weren't adjusted:
https://api.cirrus-ci.com/v1/artifact/task/5937624817336320/testrun/build/testrun/regress/regress/regression.diffsThanks for sharing this. I have fixed this in the patch attached.
IMO, there's no need for 2 separate patches for these changes.
I will make it a single patch while sharing the next patch.
Clubbed both patches into one.
The patch does not apply anymore, please post a rebased version of the patch :
1 out of 1 hunk FAILED -- saving rejects to file
src/backend/catalog/system_views.sql.rej
patching file src/backend/utils/activity/pgstat_checkpointer.c
Hunk #1 FAILED at 52.
1 out of 1 hunk FAILED -- saving rejects to file
src/backend/utils/activity/pgstat_checkpointer.c.rej
patching file src/backend/utils/adt/pgstatfuncs.c
Hunk #1 succeeded at 1217 with fuzz 1 (offset 24 lines).
patching file src/include/access/xlog.h
Hunk #1 succeeded at 165 (offset 3 lines).
patching file src/include/catalog/pg_proc.dat
Hunk #1 FAILED at 5680.
1 out of 1 hunk FAILED -- saving rejects to file
src/include/catalog/pg_proc.dat.rej
Regards,
Vignesh
On Sat, Jan 20, 2024 at 08:10:03AM +0530, vignesh C wrote:
The patch does not apply anymore, please post a rebased version of the patch :
There is more to it. Some of the columns of pg_stat_bgwriter have
been moved to a different view, aka pg_stat_checkpointer. I have
marked the patch as returned with feedback for now, so feel free to
resubmit if you can get a new version of the patch.
--
Michael
I apologize for not being active on this thread. However, I have now
returned to the thread and confirmed that the inconsistency is still
present in the latest code. I believe it’s crucial to address this
issue, and I am currently submitting the v5 version of the patch. The
v4 version had addressed the feedback from Bharath, Kyotaro, Andres,
and Robert. The current version has been rebased to incorporate
Vignesh’s suggestions. In response to Michael’s comments, I’ve moved
the new ‘slru_written’ column from the ‘pg_stat_bgwriter’ view to the
‘pg_stat_checkpointer’ in the attached patch.
To summarize our discussions, we’ve reached a consensus to correct the
mismatch between the information on buffers written as displayed in
the ‘pg_stat_checkpointer’ view and the checkpointer log message.
We’ve also agreed to separate the SLRU buffers data from the buffers
written and present the SLRU buffers data in a distinct field.
I have created the new commitfest entry here
https://commitfest.postgresql.org/49/5130/.
Kindly share if any comments.
Best Regards,
Nitin Jadhav
Azure Database for PostgreSQL
Microsoft
Show quoted text
On Tue, Jan 30, 2024 at 1:20 PM Michael Paquier <michael@paquier.xyz> wrote:
On Sat, Jan 20, 2024 at 08:10:03AM +0530, vignesh C wrote:
The patch does not apply anymore, please post a rebased version of the patch :
There is more to it. Some of the columns of pg_stat_bgwriter have
been moved to a different view, aka pg_stat_checkpointer. I have
marked the patch as returned with feedback for now, so feel free to
resubmit if you can get a new version of the patch.
--
Michael
Attachments:
v5-0001-Fix-inconsistency-in-reporting-checkpointer-stats.patchapplication/x-patch; name=v5-0001-Fix-inconsistency-in-reporting-checkpointer-stats.patchDownload
From f17300193ab350c20100c8101bc2ca5f74b5c109 Mon Sep 17 00:00:00 2001
From: Nitin Jadhav <nitinjadhav@microsoft.com>
Date: Tue, 16 Jul 2024 08:32:00 +0000
Subject: [PATCH] Fix inconsistency in reporting checkpointer stats.
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
The information about buffers written, which is revealed through the
pg_stat_checkpointer view, has been found to be inconsistent with the
data in the checkpoint complete log message. To address this, a new
column named ‘slru_written’ has been added to the pg_stat_checkpointer
view. This column displays the SLRU buffers written during checkpoints.
The existing ‘buffers_written’ column continues to represent the main
buffers written during checkpoints. Furthermore, the information about
buffers written, which is logged in the checkpoint complete log message,
includes both the main buffer count and the SLRU buffer count. This
patch distinguishes between these two types of information.
---
doc/src/sgml/monitoring.sgml | 9 ++++++
src/backend/access/transam/slru.c | 5 +++-
src/backend/access/transam/xlog.c | 28 +++++++++++--------
src/backend/catalog/system_views.sql | 1 +
.../utils/activity/pgstat_checkpointer.c | 1 +
src/backend/utils/adt/pgstatfuncs.c | 6 ++++
src/include/access/xlog.h | 1 +
src/include/catalog/pg_proc.dat | 5 ++++
src/include/pgstat.h | 1 +
src/test/regress/expected/rules.out | 1 +
10 files changed, 45 insertions(+), 13 deletions(-)
diff --git a/doc/src/sgml/monitoring.sgml b/doc/src/sgml/monitoring.sgml
index 55417a6fa9..b2fe425268 100644
--- a/doc/src/sgml/monitoring.sgml
+++ b/doc/src/sgml/monitoring.sgml
@@ -3049,6 +3049,15 @@ description | Waiting for a newly initialized WAL file to reach durable storage
</para></entry>
</row>
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>slru_written</structfield> <type>bigint</type>
+ </para>
+ <para>
+ Number of SLRU buffers written during checkpoints and restartpoints
+ </para></entry>
+ </row>
+
<row>
<entry role="catalog_table_entry"><para role="column_definition">
<structfield>stats_reset</structfield> <type>timestamp with time zone</type>
diff --git a/src/backend/access/transam/slru.c b/src/backend/access/transam/slru.c
index 77b05cc0a7..de59bcdf1c 100644
--- a/src/backend/access/transam/slru.c
+++ b/src/backend/access/transam/slru.c
@@ -703,7 +703,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++;
+ {
+ CheckpointStats.ckpt_slru_written++;
+ PendingCheckpointerStats.slru_written++;
+ }
}
/*
diff --git a/src/backend/access/transam/xlog.c b/src/backend/access/transam/xlog.c
index 33e27a6e72..19d7fbf70a 100644
--- a/src/backend/access/transam/xlog.c
+++ b/src/backend/access/transam/xlog.c
@@ -6666,14 +6666,16 @@ LogCheckpointEnd(bool restartpoint)
*/
if (restartpoint)
ereport(LOG,
- (errmsg("restartpoint complete: wrote %d buffers (%.1f%%); "
- "%d WAL file(s) added, %d removed, %d recycled; "
- "write=%ld.%03d s, sync=%ld.%03d s, total=%ld.%03d s; "
- "sync files=%d, longest=%ld.%03d s, average=%ld.%03d s; "
- "distance=%d kB, estimate=%d kB; "
- "lsn=%X/%X, redo lsn=%X/%X",
+ (errmsg("restartpoint complete: wrote %d buffers (%.1f%%), "
+ "wrote %d slru buffers (%.1f%%); %d WAL file(s) added, "
+ "%d removed, %d recycled; write=%ld.%03d s, "
+ "sync=%ld.%03d s, total=%ld.%03d s; sync files=%d, "
+ "longest=%ld.%03d s, average=%ld.%03d s; distance=%d kB, "
+ "estimate=%d kB; lsn=%X/%X, redo lsn=%X/%X",
CheckpointStats.ckpt_bufs_written,
(double) CheckpointStats.ckpt_bufs_written * 100 / NBuffers,
+ CheckpointStats.ckpt_slru_written,
+ (double) CheckpointStats.ckpt_slru_written * 100 / NBuffers,
CheckpointStats.ckpt_segs_added,
CheckpointStats.ckpt_segs_removed,
CheckpointStats.ckpt_segs_recycled,
@@ -6689,14 +6691,16 @@ LogCheckpointEnd(bool restartpoint)
LSN_FORMAT_ARGS(ControlFile->checkPointCopy.redo))));
else
ereport(LOG,
- (errmsg("checkpoint complete: wrote %d buffers (%.1f%%); "
- "%d WAL file(s) added, %d removed, %d recycled; "
- "write=%ld.%03d s, sync=%ld.%03d s, total=%ld.%03d s; "
- "sync files=%d, longest=%ld.%03d s, average=%ld.%03d s; "
- "distance=%d kB, estimate=%d kB; "
- "lsn=%X/%X, redo lsn=%X/%X",
+ (errmsg("checkpoint complete: wrote %d buffers (%.1f%%), "
+ "wrote %d slru buffers (%.1f%%); %d WAL file(s) added, "
+ "%d removed, %d recycled; write=%ld.%03d s, "
+ "sync=%ld.%03d s, total=%ld.%03d s; sync files=%d, "
+ "longest=%ld.%03d s, average=%ld.%03d s; distance=%d kB, "
+ "estimate=%d kB; lsn=%X/%X, redo lsn=%X/%X",
CheckpointStats.ckpt_bufs_written,
(double) CheckpointStats.ckpt_bufs_written * 100 / NBuffers,
+ CheckpointStats.ckpt_slru_written,
+ (double) CheckpointStats.ckpt_slru_written * 100 / NBuffers,
CheckpointStats.ckpt_segs_added,
CheckpointStats.ckpt_segs_removed,
CheckpointStats.ckpt_segs_recycled,
diff --git a/src/backend/catalog/system_views.sql b/src/backend/catalog/system_views.sql
index 19cabc9a47..aaaa2b3474 100644
--- a/src/backend/catalog/system_views.sql
+++ b/src/backend/catalog/system_views.sql
@@ -1144,6 +1144,7 @@ CREATE VIEW pg_stat_checkpointer AS
pg_stat_get_checkpointer_write_time() AS write_time,
pg_stat_get_checkpointer_sync_time() AS sync_time,
pg_stat_get_checkpointer_buffers_written() AS buffers_written,
+ pg_stat_get_checkpointer_slru_written() AS slru_written,
pg_stat_get_checkpointer_stat_reset_time() AS stats_reset;
CREATE VIEW pg_stat_io AS
diff --git a/src/backend/utils/activity/pgstat_checkpointer.c b/src/backend/utils/activity/pgstat_checkpointer.c
index bbfc9c7e18..98d16c7868 100644
--- a/src/backend/utils/activity/pgstat_checkpointer.c
+++ b/src/backend/utils/activity/pgstat_checkpointer.c
@@ -55,6 +55,7 @@ pgstat_report_checkpointer(void)
CHECKPOINTER_ACC(write_time);
CHECKPOINTER_ACC(sync_time);
CHECKPOINTER_ACC(buffers_written);
+ CHECKPOINTER_ACC(slru_written);
#undef CHECKPOINTER_ACC
pgstat_end_changecount_write(&stats_shmem->changecount);
diff --git a/src/backend/utils/adt/pgstatfuncs.c b/src/backend/utils/adt/pgstatfuncs.c
index 3876339ee1..f3ca746818 100644
--- a/src/backend/utils/adt/pgstatfuncs.c
+++ b/src/backend/utils/adt/pgstatfuncs.c
@@ -1215,6 +1215,12 @@ pg_stat_get_checkpointer_buffers_written(PG_FUNCTION_ARGS)
PG_RETURN_INT64(pgstat_fetch_stat_checkpointer()->buffers_written);
}
+Datum
+pg_stat_get_checkpointer_slru_written(PG_FUNCTION_ARGS)
+{
+ PG_RETURN_INT64(pgstat_fetch_stat_checkpointer()->slru_written);
+}
+
Datum
pg_stat_get_bgwriter_buf_written_clean(PG_FUNCTION_ARGS)
{
diff --git a/src/include/access/xlog.h b/src/include/access/xlog.h
index 1a1f11a943..23a264ef23 100644
--- a/src/include/access/xlog.h
+++ b/src/include/access/xlog.h
@@ -165,6 +165,7 @@ typedef struct CheckpointStatsData
TimestampTz ckpt_end_t; /* end of checkpoint */
int ckpt_bufs_written; /* # of buffers written */
+ int ckpt_slru_written; /* # of SLRU buffers written */
int ckpt_segs_added; /* # of new xlog segments created */
int ckpt_segs_removed; /* # of xlog segments deleted */
diff --git a/src/include/catalog/pg_proc.dat b/src/include/catalog/pg_proc.dat
index 73d9cf8582..6adb683553 100644
--- a/src/include/catalog/pg_proc.dat
+++ b/src/include/catalog/pg_proc.dat
@@ -5757,6 +5757,11 @@
proname => 'pg_stat_get_checkpointer_buffers_written', provolatile => 's',
proparallel => 'r', prorettype => 'int8', proargtypes => '',
prosrc => 'pg_stat_get_checkpointer_buffers_written' },
+{ oid => '3814',
+ descr => 'statistics: number of SLRU buffers written during checkpoints and restartpoints',
+ proname => 'pg_stat_get_checkpointer_slru_written', provolatile => 's',
+ proparallel => 'r', prorettype => 'int8', proargtypes => '',
+ prosrc => 'pg_stat_get_checkpointer_slru_written' },
{ oid => '6314', descr => 'statistics: last reset for the checkpointer',
proname => 'pg_stat_get_checkpointer_stat_reset_time', provolatile => 's',
proparallel => 'r', prorettype => 'timestamptz', proargtypes => '',
diff --git a/src/include/pgstat.h b/src/include/pgstat.h
index 6b99bb8aad..eedcc7d4a2 100644
--- a/src/include/pgstat.h
+++ b/src/include/pgstat.h
@@ -268,6 +268,7 @@ typedef struct PgStat_CheckpointerStats
PgStat_Counter write_time; /* times in milliseconds */
PgStat_Counter sync_time;
PgStat_Counter buffers_written;
+ PgStat_Counter slru_written;
TimestampTz stat_reset_timestamp;
} PgStat_CheckpointerStats;
diff --git a/src/test/regress/expected/rules.out b/src/test/regress/expected/rules.out
index 4c789279e5..4b1ff2d26e 100644
--- a/src/test/regress/expected/rules.out
+++ b/src/test/regress/expected/rules.out
@@ -1830,6 +1830,7 @@ pg_stat_checkpointer| SELECT pg_stat_get_checkpointer_num_timed() AS num_timed,
pg_stat_get_checkpointer_write_time() AS write_time,
pg_stat_get_checkpointer_sync_time() AS sync_time,
pg_stat_get_checkpointer_buffers_written() AS buffers_written,
+ pg_stat_get_checkpointer_slru_written() AS slru_written,
pg_stat_get_checkpointer_stat_reset_time() AS stats_reset;
pg_stat_database| SELECT oid AS datid,
datname,
--
2.43.0
On 2024/07/18 16:08, Nitin Jadhav wrote:
I apologize for not being active on this thread. However, I have now
returned to the thread and confirmed that the inconsistency is still
present in the latest code. I believe it’s crucial to address this
issue, and I am currently submitting the v5 version of the patch. The
v4 version had addressed the feedback from Bharath, Kyotaro, Andres,
and Robert. The current version has been rebased to incorporate
Vignesh’s suggestions. In response to Michael’s comments, I’ve moved
the new ‘slru_written’ column from the ‘pg_stat_bgwriter’ view to the
‘pg_stat_checkpointer’ in the attached patch.To summarize our discussions, we’ve reached a consensus to correct the
mismatch between the information on buffers written as displayed in
the ‘pg_stat_checkpointer’ view and the checkpointer log message.
We’ve also agreed to separate the SLRU buffers data from the buffers
written and present the SLRU buffers data in a distinct field.I have created the new commitfest entry here
https://commitfest.postgresql.org/49/5130/.
Kindly share if any comments.
Thanks for updating the patch!
In pgstat_checkpointer.c, it looks like you missed adding
CHECKPOINTER_COMP(slru_written) in pgstat_checkpointer_snapshot_cb().
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>slru_written</structfield> <type>bigint</type>
+ </para>
+ <para>
+ Number of SLRU buffers written during checkpoints and restartpoints
+ </para></entry>
+ </row>
This entry should be moved to the pg_stat_checkpointer documentation.
+ CheckpointStats.ckpt_slru_written,
+ (double) CheckpointStats.ckpt_slru_written * 100 / NBuffers,
I don't think NBuffers represents the maximum number of SLRU buffers.
We might need to calculate this based on specific GUC settings,
like transaction_buffers.
Regards,
--
Fujii Masao
Advanced Computing Technology Center
Research and Development Headquarters
NTT DATA CORPORATION
Thanks for the review.
In pgstat_checkpointer.c, it looks like you missed adding
CHECKPOINTER_COMP(slru_written) in pgstat_checkpointer_snapshot_cb().
Fixed it.
+ <row> + <entry role="catalog_table_entry"><para role="column_definition"> + <structfield>slru_written</structfield> <type>bigint</type> + </para> + <para> + Number of SLRU buffers written during checkpoints and restartpoints + </para></entry> + </row>This entry should be moved to the pg_stat_checkpointer documentation.
Fixed it.
+ CheckpointStats.ckpt_slru_written, + (double) CheckpointStats.ckpt_slru_written * 100 / NBuffers,I don't think NBuffers represents the maximum number of SLRU buffers.
We might need to calculate this based on specific GUC settings,
like transaction_buffers.
Great observation. Since the SLRU buffers written during a checkpoint
can include transaction_buffers, commit_timestamp_buffers,
subtransaction_buffers, multixact_member_buffers,
multixact_offset_buffers, and serializable_buffers, the total count of
SLRU buffers should be the sum of all these types. We might need to
introduce a global variable, such as total_slru_count, in the
globals.c file to hold this sum. The num_slots variable in the
SlruSharedData structure needs to be accessed from all types of SLRU
and stored in total_slru_count. This can then be used during logging
to calculate the percentage of SLRU buffers written. However, I’m
unsure if this effort is justified. While it makes sense for normal
buffers to display the percentage, the additional code required might
not provide significant value to users. Therefore, I have removed this
in the attached v6 patch. If it is really required, I am happy to make
the above changes and share the updated patch.
Best Regards,
Nitin Jadhav
Azure Database for PostgreSQL
Microsoft
Show quoted text
On Wed, Sep 18, 2024 at 6:57 PM Fujii Masao <masao.fujii@oss.nttdata.com> wrote:
On 2024/07/18 16:08, Nitin Jadhav wrote:
I apologize for not being active on this thread. However, I have now
returned to the thread and confirmed that the inconsistency is still
present in the latest code. I believe it’s crucial to address this
issue, and I am currently submitting the v5 version of the patch. The
v4 version had addressed the feedback from Bharath, Kyotaro, Andres,
and Robert. The current version has been rebased to incorporate
Vignesh’s suggestions. In response to Michael’s comments, I’ve moved
the new ‘slru_written’ column from the ‘pg_stat_bgwriter’ view to the
‘pg_stat_checkpointer’ in the attached patch.To summarize our discussions, we’ve reached a consensus to correct the
mismatch between the information on buffers written as displayed in
the ‘pg_stat_checkpointer’ view and the checkpointer log message.
We’ve also agreed to separate the SLRU buffers data from the buffers
written and present the SLRU buffers data in a distinct field.I have created the new commitfest entry here
https://commitfest.postgresql.org/49/5130/.
Kindly share if any comments.Thanks for updating the patch!
In pgstat_checkpointer.c, it looks like you missed adding
CHECKPOINTER_COMP(slru_written) in pgstat_checkpointer_snapshot_cb().+ <row> + <entry role="catalog_table_entry"><para role="column_definition"> + <structfield>slru_written</structfield> <type>bigint</type> + </para> + <para> + Number of SLRU buffers written during checkpoints and restartpoints + </para></entry> + </row>This entry should be moved to the pg_stat_checkpointer documentation.
+ CheckpointStats.ckpt_slru_written, + (double) CheckpointStats.ckpt_slru_written * 100 / NBuffers,I don't think NBuffers represents the maximum number of SLRU buffers.
We might need to calculate this based on specific GUC settings,
like transaction_buffers.Regards,
--
Fujii Masao
Advanced Computing Technology Center
Research and Development Headquarters
NTT DATA CORPORATION
Attachments:
v6-0001-Fix-inconsistency-in-reporting-checkpointer-stats.patchapplication/octet-stream; name=v6-0001-Fix-inconsistency-in-reporting-checkpointer-stats.patchDownload
From e81427ad6da4bac608d188180569abe02914013e Mon Sep 17 00:00:00 2001
From: Nitin Jadhav <nitinjadhav@microsoft.com>
Date: Sun, 22 Sep 2024 17:04:23 +0530
Subject: [PATCH] Fix inconsistency in reporting checkpointer stats.
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
The information about buffers written, which is revealed through the
pg_stat_checkpointer view, has been found to be inconsistent with the
data in the checkpoint complete log message. To address this, a new
column named ‘slru_written’ has been added to the pg_stat_checkpointer
view. This column displays the SLRU buffers written during checkpoints.
The existing ‘buffers_written’ column continues to represent the main
buffers written during checkpoints. Furthermore, the information about
buffers written, which is logged in the checkpoint complete log message,
includes both the main buffer count and the SLRU buffer count. This
patch distinguishes between these two types of information.
---
doc/src/sgml/monitoring.sgml | 9 +++++++
src/backend/access/transam/slru.c | 7 +++--
src/backend/access/transam/xlog.c | 26 ++++++++++---------
src/backend/catalog/system_views.sql | 1 +
.../utils/activity/pgstat_checkpointer.c | 2 ++
src/backend/utils/adt/pgstatfuncs.c | 6 +++++
src/include/access/xlog.h | 1 +
src/include/catalog/pg_proc.dat | 5 ++++
src/include/pgstat.h | 1 +
src/test/regress/expected/rules.out | 1 +
10 files changed, 45 insertions(+), 14 deletions(-)
diff --git a/doc/src/sgml/monitoring.sgml b/doc/src/sgml/monitoring.sgml
index a2fda4677d..6cbbb1ca5c 100644
--- a/doc/src/sgml/monitoring.sgml
+++ b/doc/src/sgml/monitoring.sgml
@@ -3125,6 +3125,15 @@ description | Waiting for a newly initialized WAL file to reach durable storage
</para></entry>
</row>
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>slru_written</structfield> <type>bigint</type>
+ </para>
+ <para>
+ Number of SLRU buffers written during checkpoints and restartpoints
+ </para></entry>
+ </row>
+
<row>
<entry role="catalog_table_entry"><para role="column_definition">
<structfield>stats_reset</structfield> <type>timestamp with time zone</type>
diff --git a/src/backend/access/transam/slru.c b/src/backend/access/transam/slru.c
index e7f73bf427..bf8deccdc0 100644
--- a/src/backend/access/transam/slru.c
+++ b/src/backend/access/transam/slru.c
@@ -716,9 +716,12 @@ SlruInternalWritePage(SlruCtl ctl, int slotno, SlruWriteAll fdata)
if (!ok)
SlruReportIOError(ctl, pageno, InvalidTransactionId);
- /* If part of a checkpoint, count this as a buffer written. */
+ /* If part of a checkpoint, count this as a slru written. */
if (fdata)
- CheckpointStats.ckpt_bufs_written++;
+ {
+ CheckpointStats.ckpt_slru_written++;
+ PendingCheckpointerStats.slru_written++;
+ }
}
/*
diff --git a/src/backend/access/transam/xlog.c b/src/backend/access/transam/xlog.c
index 853ab06812..d9f25a9046 100644
--- a/src/backend/access/transam/xlog.c
+++ b/src/backend/access/transam/xlog.c
@@ -6727,14 +6727,15 @@ LogCheckpointEnd(bool restartpoint)
*/
if (restartpoint)
ereport(LOG,
- (errmsg("restartpoint complete: wrote %d buffers (%.1f%%); "
- "%d WAL file(s) added, %d removed, %d recycled; "
- "write=%ld.%03d s, sync=%ld.%03d s, total=%ld.%03d s; "
- "sync files=%d, longest=%ld.%03d s, average=%ld.%03d s; "
- "distance=%d kB, estimate=%d kB; "
- "lsn=%X/%X, redo lsn=%X/%X",
+ (errmsg("restartpoint complete: wrote %d buffers (%.1f%%), "
+ "wrote %d slru buffers; %d WAL file(s) added, "
+ "%d removed, %d recycled; write=%ld.%03d s, "
+ "sync=%ld.%03d s, total=%ld.%03d s; sync files=%d, "
+ "longest=%ld.%03d s, average=%ld.%03d s; distance=%d kB, "
+ "estimate=%d kB; lsn=%X/%X, redo lsn=%X/%X",
CheckpointStats.ckpt_bufs_written,
(double) CheckpointStats.ckpt_bufs_written * 100 / NBuffers,
+ CheckpointStats.ckpt_slru_written,
CheckpointStats.ckpt_segs_added,
CheckpointStats.ckpt_segs_removed,
CheckpointStats.ckpt_segs_recycled,
@@ -6750,14 +6751,15 @@ LogCheckpointEnd(bool restartpoint)
LSN_FORMAT_ARGS(ControlFile->checkPointCopy.redo))));
else
ereport(LOG,
- (errmsg("checkpoint complete: wrote %d buffers (%.1f%%); "
- "%d WAL file(s) added, %d removed, %d recycled; "
- "write=%ld.%03d s, sync=%ld.%03d s, total=%ld.%03d s; "
- "sync files=%d, longest=%ld.%03d s, average=%ld.%03d s; "
- "distance=%d kB, estimate=%d kB; "
- "lsn=%X/%X, redo lsn=%X/%X",
+ (errmsg("checkpoint complete: wrote %d buffers (%.1f%%), "
+ "wrote %d slru buffers; %d WAL file(s) added, "
+ "%d removed, %d recycled; write=%ld.%03d s, "
+ "sync=%ld.%03d s, total=%ld.%03d s; sync files=%d, "
+ "longest=%ld.%03d s, average=%ld.%03d s; distance=%d kB, "
+ "estimate=%d kB; lsn=%X/%X, redo lsn=%X/%X",
CheckpointStats.ckpt_bufs_written,
(double) CheckpointStats.ckpt_bufs_written * 100 / NBuffers,
+ CheckpointStats.ckpt_slru_written,
CheckpointStats.ckpt_segs_added,
CheckpointStats.ckpt_segs_removed,
CheckpointStats.ckpt_segs_recycled,
diff --git a/src/backend/catalog/system_views.sql b/src/backend/catalog/system_views.sql
index 7fd5d256a1..a12db38d45 100644
--- a/src/backend/catalog/system_views.sql
+++ b/src/backend/catalog/system_views.sql
@@ -1144,6 +1144,7 @@ CREATE VIEW pg_stat_checkpointer AS
pg_stat_get_checkpointer_write_time() AS write_time,
pg_stat_get_checkpointer_sync_time() AS sync_time,
pg_stat_get_checkpointer_buffers_written() AS buffers_written,
+ pg_stat_get_checkpointer_slru_written() AS slru_written,
pg_stat_get_checkpointer_stat_reset_time() AS stats_reset;
CREATE VIEW pg_stat_io AS
diff --git a/src/backend/utils/activity/pgstat_checkpointer.c b/src/backend/utils/activity/pgstat_checkpointer.c
index bbfc9c7e18..21fda77276 100644
--- a/src/backend/utils/activity/pgstat_checkpointer.c
+++ b/src/backend/utils/activity/pgstat_checkpointer.c
@@ -55,6 +55,7 @@ pgstat_report_checkpointer(void)
CHECKPOINTER_ACC(write_time);
CHECKPOINTER_ACC(sync_time);
CHECKPOINTER_ACC(buffers_written);
+ CHECKPOINTER_ACC(slru_written);
#undef CHECKPOINTER_ACC
pgstat_end_changecount_write(&stats_shmem->changecount);
@@ -133,5 +134,6 @@ pgstat_checkpointer_snapshot_cb(void)
CHECKPOINTER_COMP(write_time);
CHECKPOINTER_COMP(sync_time);
CHECKPOINTER_COMP(buffers_written);
+ CHECKPOINTER_COMP(slru_written);
#undef CHECKPOINTER_COMP
}
diff --git a/src/backend/utils/adt/pgstatfuncs.c b/src/backend/utils/adt/pgstatfuncs.c
index 9c23ac7c8c..58d72e4361 100644
--- a/src/backend/utils/adt/pgstatfuncs.c
+++ b/src/backend/utils/adt/pgstatfuncs.c
@@ -1215,6 +1215,12 @@ pg_stat_get_checkpointer_buffers_written(PG_FUNCTION_ARGS)
PG_RETURN_INT64(pgstat_fetch_stat_checkpointer()->buffers_written);
}
+Datum
+pg_stat_get_checkpointer_slru_written(PG_FUNCTION_ARGS)
+{
+ PG_RETURN_INT64(pgstat_fetch_stat_checkpointer()->slru_written);
+}
+
Datum
pg_stat_get_bgwriter_buf_written_clean(PG_FUNCTION_ARGS)
{
diff --git a/src/include/access/xlog.h b/src/include/access/xlog.h
index 083810f5b4..5296be3d6c 100644
--- a/src/include/access/xlog.h
+++ b/src/include/access/xlog.h
@@ -167,6 +167,7 @@ typedef struct CheckpointStatsData
TimestampTz ckpt_end_t; /* end of checkpoint */
int ckpt_bufs_written; /* # of buffers written */
+ int ckpt_slru_written; /* # of SLRU buffers written */
int ckpt_segs_added; /* # of new xlog segments created */
int ckpt_segs_removed; /* # of xlog segments deleted */
diff --git a/src/include/catalog/pg_proc.dat b/src/include/catalog/pg_proc.dat
index 43f608d7a0..0eb6e5c57b 100644
--- a/src/include/catalog/pg_proc.dat
+++ b/src/include/catalog/pg_proc.dat
@@ -5839,6 +5839,11 @@
proname => 'pg_stat_get_checkpointer_buffers_written', provolatile => 's',
proparallel => 'r', prorettype => 'int8', proargtypes => '',
prosrc => 'pg_stat_get_checkpointer_buffers_written' },
+{ oid => '3814',
+ descr => 'statistics: number of SLRU buffers written during checkpoints and restartpoints',
+ proname => 'pg_stat_get_checkpointer_slru_written', provolatile => 's',
+ proparallel => 'r', prorettype => 'int8', proargtypes => '',
+ prosrc => 'pg_stat_get_checkpointer_slru_written' },
{ oid => '6314', descr => 'statistics: last reset for the checkpointer',
proname => 'pg_stat_get_checkpointer_stat_reset_time', provolatile => 's',
proparallel => 'r', prorettype => 'timestamptz', proargtypes => '',
diff --git a/src/include/pgstat.h b/src/include/pgstat.h
index 4752dfe719..ea437f4273 100644
--- a/src/include/pgstat.h
+++ b/src/include/pgstat.h
@@ -300,6 +300,7 @@ typedef struct PgStat_CheckpointerStats
PgStat_Counter write_time; /* times in milliseconds */
PgStat_Counter sync_time;
PgStat_Counter buffers_written;
+ PgStat_Counter slru_written;
TimestampTz stat_reset_timestamp;
} PgStat_CheckpointerStats;
diff --git a/src/test/regress/expected/rules.out b/src/test/regress/expected/rules.out
index a1626f3fae..322e24d16a 100644
--- a/src/test/regress/expected/rules.out
+++ b/src/test/regress/expected/rules.out
@@ -1830,6 +1830,7 @@ pg_stat_checkpointer| SELECT pg_stat_get_checkpointer_num_timed() AS num_timed,
pg_stat_get_checkpointer_write_time() AS write_time,
pg_stat_get_checkpointer_sync_time() AS sync_time,
pg_stat_get_checkpointer_buffers_written() AS buffers_written,
+ pg_stat_get_checkpointer_slru_written() AS slru_written,
pg_stat_get_checkpointer_stat_reset_time() AS stats_reset;
pg_stat_database| SELECT oid AS datid,
datname,
--
2.25.1
On 2024/09/22 20:44, Nitin Jadhav wrote:
+ CheckpointStats.ckpt_slru_written, + (double) CheckpointStats.ckpt_slru_written * 100 / NBuffers,I don't think NBuffers represents the maximum number of SLRU buffers.
We might need to calculate this based on specific GUC settings,
like transaction_buffers.Great observation. Since the SLRU buffers written during a checkpoint
can include transaction_buffers, commit_timestamp_buffers,
subtransaction_buffers, multixact_member_buffers,
multixact_offset_buffers, and serializable_buffers, the total count of
SLRU buffers should be the sum of all these types. We might need to
introduce a global variable, such as total_slru_count, in the
globals.c file to hold this sum. The num_slots variable in the
SlruSharedData structure needs to be accessed from all types of SLRU
and stored in total_slru_count. This can then be used during logging
to calculate the percentage of SLRU buffers written. However, I’m
unsure if this effort is justified. While it makes sense for normal
buffers to display the percentage, the additional code required might
not provide significant value to users. Therefore, I have removed this
in the attached v6 patch.
+1
Thanks for updating the patch! It looks good to me.
Barring any objections, I will commit this patch.
Regards,
--
Fujii Masao
Advanced Computing Technology Center
Research and Development Headquarters
NTT DATA CORPORATION
On 2024/10/01 3:33, Fujii Masao wrote:
On 2024/09/22 20:44, Nitin Jadhav wrote:
+ CheckpointStats.ckpt_slru_written, + (double) CheckpointStats.ckpt_slru_written * 100 / NBuffers,I don't think NBuffers represents the maximum number of SLRU buffers.
We might need to calculate this based on specific GUC settings,
like transaction_buffers.Great observation. Since the SLRU buffers written during a checkpoint
can include transaction_buffers, commit_timestamp_buffers,
subtransaction_buffers, multixact_member_buffers,
multixact_offset_buffers, and serializable_buffers, the total count of
SLRU buffers should be the sum of all these types. We might need to
introduce a global variable, such as total_slru_count, in the
globals.c file to hold this sum. The num_slots variable in the
SlruSharedData structure needs to be accessed from all types of SLRU
and stored in total_slru_count. This can then be used during logging
to calculate the percentage of SLRU buffers written. However, I’m
unsure if this effort is justified. While it makes sense for normal
buffers to display the percentage, the additional code required might
not provide significant value to users. Therefore, I have removed this
in the attached v6 patch.+1
Thanks for updating the patch! It looks good to me.
Barring any objections, I will commit this patch.
Before committing the patch, I revised it with the following changes:
- I added "shared" to the description of pg_stat_checkpointer.buffers_written
to clarify that it tracks shared buffers.
- In the checkpoint log message, I replaced "slru" with "SLRU" for consistency,
as uppercase is typically used for SLRU.
- I updated the commit message.
Regards,
--
Fujii Masao
Advanced Computing Technology Center
Research and Development Headquarters
NTT DATA CORPORATION
Attachments:
v7-0001-Fix-inconsistent-reporting-of-checkpointer-stats.patchtext/plain; charset=UTF-8; name=v7-0001-Fix-inconsistent-reporting-of-checkpointer-stats.patchDownload
From 150a915995115a882b18ad94c104b58dd1673cb1 Mon Sep 17 00:00:00 2001
From: Nitin Jadhav <nitinjadhav@microsoft.com>
Date: Sun, 22 Sep 2024 17:04:23 +0530
Subject: [PATCH v7] Fix inconsistent reporting of checkpointer stats
Previously, the pg_stat_checkpointer view and the checkpoint completion
log message could show different numbers for buffers written
during checkpoints. The view only counted shared buffers,
while the log message included both shared and SLRU buffers,
causing inconsistencies.
This commit resolves the issue by updating both the view and the log message
to separately report shared and SLRU buffers written during checkpoints.
A new slru_written column is added to the pg_stat_checkpointer view
to track SLRU buffers, while the existing buffers_written column now
tracks only shared buffers. This change would help users distinguish
between the two types of buffers, in the pg_stat_checkpointer view and
the checkpoint complete log message, respectively.
Bump catalog version.
Author: Nitin Jadhav
Reviewed-by: Bharath Rupireddy, Michael Paquier, Kyotaro Horiguchi, Robert Haas
Reviewed-by: Andres Freund, vignesh C
Discussion: https://postgr.es/m/CAMm1aWb18EpT0whJrjG+-nyhNouXET6ZUw0pNYYAe+NezpvsAA@mail.gmail.com
---
doc/src/sgml/monitoring.sgml | 11 +++++++-
src/backend/access/transam/slru.c | 7 +++--
src/backend/access/transam/xlog.c | 26 ++++++++++---------
src/backend/catalog/system_views.sql | 1 +
.../utils/activity/pgstat_checkpointer.c | 2 ++
src/backend/utils/adt/pgstatfuncs.c | 6 +++++
src/include/access/xlog.h | 1 +
src/include/catalog/catversion.h | 2 +-
src/include/catalog/pg_proc.dat | 5 ++++
src/include/pgstat.h | 1 +
src/test/regress/expected/rules.out | 1 +
11 files changed, 47 insertions(+), 16 deletions(-)
diff --git a/doc/src/sgml/monitoring.sgml b/doc/src/sgml/monitoring.sgml
index 48ffe87241..331315f8d3 100644
--- a/doc/src/sgml/monitoring.sgml
+++ b/doc/src/sgml/monitoring.sgml
@@ -3127,7 +3127,16 @@ description | Waiting for a newly initialized WAL file to reach durable storage
<structfield>buffers_written</structfield> <type>bigint</type>
</para>
<para>
- Number of buffers written during checkpoints and restartpoints
+ Number of shared buffers written during checkpoints and restartpoints
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>slru_written</structfield> <type>bigint</type>
+ </para>
+ <para>
+ Number of SLRU buffers written during checkpoints and restartpoints
</para></entry>
</row>
diff --git a/src/backend/access/transam/slru.c b/src/backend/access/transam/slru.c
index e7f73bf427..889eff1815 100644
--- a/src/backend/access/transam/slru.c
+++ b/src/backend/access/transam/slru.c
@@ -716,9 +716,12 @@ SlruInternalWritePage(SlruCtl ctl, int slotno, SlruWriteAll fdata)
if (!ok)
SlruReportIOError(ctl, pageno, InvalidTransactionId);
- /* If part of a checkpoint, count this as a buffer written. */
+ /* If part of a checkpoint, count this as a SLRU buffer written. */
if (fdata)
- CheckpointStats.ckpt_bufs_written++;
+ {
+ CheckpointStats.ckpt_slru_written++;
+ PendingCheckpointerStats.slru_written++;
+ }
}
/*
diff --git a/src/backend/access/transam/xlog.c b/src/backend/access/transam/xlog.c
index 64304d77d3..9102c8d772 100644
--- a/src/backend/access/transam/xlog.c
+++ b/src/backend/access/transam/xlog.c
@@ -6727,14 +6727,15 @@ LogCheckpointEnd(bool restartpoint)
*/
if (restartpoint)
ereport(LOG,
- (errmsg("restartpoint complete: wrote %d buffers (%.1f%%); "
- "%d WAL file(s) added, %d removed, %d recycled; "
- "write=%ld.%03d s, sync=%ld.%03d s, total=%ld.%03d s; "
- "sync files=%d, longest=%ld.%03d s, average=%ld.%03d s; "
- "distance=%d kB, estimate=%d kB; "
- "lsn=%X/%X, redo lsn=%X/%X",
+ (errmsg("restartpoint complete: wrote %d buffers (%.1f%%), "
+ "wrote %d SLRU buffers; %d WAL file(s) added, "
+ "%d removed, %d recycled; write=%ld.%03d s, "
+ "sync=%ld.%03d s, total=%ld.%03d s; sync files=%d, "
+ "longest=%ld.%03d s, average=%ld.%03d s; distance=%d kB, "
+ "estimate=%d kB; lsn=%X/%X, redo lsn=%X/%X",
CheckpointStats.ckpt_bufs_written,
(double) CheckpointStats.ckpt_bufs_written * 100 / NBuffers,
+ CheckpointStats.ckpt_slru_written,
CheckpointStats.ckpt_segs_added,
CheckpointStats.ckpt_segs_removed,
CheckpointStats.ckpt_segs_recycled,
@@ -6750,14 +6751,15 @@ LogCheckpointEnd(bool restartpoint)
LSN_FORMAT_ARGS(ControlFile->checkPointCopy.redo))));
else
ereport(LOG,
- (errmsg("checkpoint complete: wrote %d buffers (%.1f%%); "
- "%d WAL file(s) added, %d removed, %d recycled; "
- "write=%ld.%03d s, sync=%ld.%03d s, total=%ld.%03d s; "
- "sync files=%d, longest=%ld.%03d s, average=%ld.%03d s; "
- "distance=%d kB, estimate=%d kB; "
- "lsn=%X/%X, redo lsn=%X/%X",
+ (errmsg("checkpoint complete: wrote %d buffers (%.1f%%), "
+ "wrote %d SLRU buffers; %d WAL file(s) added, "
+ "%d removed, %d recycled; write=%ld.%03d s, "
+ "sync=%ld.%03d s, total=%ld.%03d s; sync files=%d, "
+ "longest=%ld.%03d s, average=%ld.%03d s; distance=%d kB, "
+ "estimate=%d kB; lsn=%X/%X, redo lsn=%X/%X",
CheckpointStats.ckpt_bufs_written,
(double) CheckpointStats.ckpt_bufs_written * 100 / NBuffers,
+ CheckpointStats.ckpt_slru_written,
CheckpointStats.ckpt_segs_added,
CheckpointStats.ckpt_segs_removed,
CheckpointStats.ckpt_segs_recycled,
diff --git a/src/backend/catalog/system_views.sql b/src/backend/catalog/system_views.sql
index 49109dbdc8..3456b821bc 100644
--- a/src/backend/catalog/system_views.sql
+++ b/src/backend/catalog/system_views.sql
@@ -1145,6 +1145,7 @@ CREATE VIEW pg_stat_checkpointer AS
pg_stat_get_checkpointer_write_time() AS write_time,
pg_stat_get_checkpointer_sync_time() AS sync_time,
pg_stat_get_checkpointer_buffers_written() AS buffers_written,
+ pg_stat_get_checkpointer_slru_written() AS slru_written,
pg_stat_get_checkpointer_stat_reset_time() AS stats_reset;
CREATE VIEW pg_stat_io AS
diff --git a/src/backend/utils/activity/pgstat_checkpointer.c b/src/backend/utils/activity/pgstat_checkpointer.c
index 4a0a2d1493..5a3fb4a9e0 100644
--- a/src/backend/utils/activity/pgstat_checkpointer.c
+++ b/src/backend/utils/activity/pgstat_checkpointer.c
@@ -56,6 +56,7 @@ pgstat_report_checkpointer(void)
CHECKPOINTER_ACC(write_time);
CHECKPOINTER_ACC(sync_time);
CHECKPOINTER_ACC(buffers_written);
+ CHECKPOINTER_ACC(slru_written);
#undef CHECKPOINTER_ACC
pgstat_end_changecount_write(&stats_shmem->changecount);
@@ -135,5 +136,6 @@ pgstat_checkpointer_snapshot_cb(void)
CHECKPOINTER_COMP(write_time);
CHECKPOINTER_COMP(sync_time);
CHECKPOINTER_COMP(buffers_written);
+ CHECKPOINTER_COMP(slru_written);
#undef CHECKPOINTER_COMP
}
diff --git a/src/backend/utils/adt/pgstatfuncs.c b/src/backend/utils/adt/pgstatfuncs.c
index 17b0fc02ef..f7b50e0b5a 100644
--- a/src/backend/utils/adt/pgstatfuncs.c
+++ b/src/backend/utils/adt/pgstatfuncs.c
@@ -1221,6 +1221,12 @@ pg_stat_get_checkpointer_buffers_written(PG_FUNCTION_ARGS)
PG_RETURN_INT64(pgstat_fetch_stat_checkpointer()->buffers_written);
}
+Datum
+pg_stat_get_checkpointer_slru_written(PG_FUNCTION_ARGS)
+{
+ PG_RETURN_INT64(pgstat_fetch_stat_checkpointer()->slru_written);
+}
+
Datum
pg_stat_get_bgwriter_buf_written_clean(PG_FUNCTION_ARGS)
{
diff --git a/src/include/access/xlog.h b/src/include/access/xlog.h
index 36f6e4e4b4..34ad46c067 100644
--- a/src/include/access/xlog.h
+++ b/src/include/access/xlog.h
@@ -167,6 +167,7 @@ typedef struct CheckpointStatsData
TimestampTz ckpt_end_t; /* end of checkpoint */
int ckpt_bufs_written; /* # of buffers written */
+ int ckpt_slru_written; /* # of SLRU buffers written */
int ckpt_segs_added; /* # of new xlog segments created */
int ckpt_segs_removed; /* # of xlog segments deleted */
diff --git a/src/include/catalog/catversion.h b/src/include/catalog/catversion.h
index 3c89b70f9e..946ee29af2 100644
--- a/src/include/catalog/catversion.h
+++ b/src/include/catalog/catversion.h
@@ -57,6 +57,6 @@
*/
/* yyyymmddN */
-#define CATALOG_VERSION_NO 202409302
+#define CATALOG_VERSION_NO 202410011
#endif
diff --git a/src/include/catalog/pg_proc.dat b/src/include/catalog/pg_proc.dat
index 05fcbf7515..77f54a79e6 100644
--- a/src/include/catalog/pg_proc.dat
+++ b/src/include/catalog/pg_proc.dat
@@ -5847,6 +5847,11 @@
proname => 'pg_stat_get_checkpointer_buffers_written', provolatile => 's',
proparallel => 'r', prorettype => 'int8', proargtypes => '',
prosrc => 'pg_stat_get_checkpointer_buffers_written' },
+{ oid => '8573',
+ descr => 'statistics: number of SLRU buffers written during checkpoints and restartpoints',
+ proname => 'pg_stat_get_checkpointer_slru_written', provolatile => 's',
+ proparallel => 'r', prorettype => 'int8', proargtypes => '',
+ prosrc => 'pg_stat_get_checkpointer_slru_written' },
{ oid => '6314', descr => 'statistics: last reset for the checkpointer',
proname => 'pg_stat_get_checkpointer_stat_reset_time', provolatile => 's',
proparallel => 'r', prorettype => 'timestamptz', proargtypes => '',
diff --git a/src/include/pgstat.h b/src/include/pgstat.h
index 476acd680c..df53fa2d4f 100644
--- a/src/include/pgstat.h
+++ b/src/include/pgstat.h
@@ -301,6 +301,7 @@ typedef struct PgStat_CheckpointerStats
PgStat_Counter write_time; /* times in milliseconds */
PgStat_Counter sync_time;
PgStat_Counter buffers_written;
+ PgStat_Counter slru_written;
TimestampTz stat_reset_timestamp;
} PgStat_CheckpointerStats;
diff --git a/src/test/regress/expected/rules.out b/src/test/regress/expected/rules.out
index f5434d8365..2b47013f11 100644
--- a/src/test/regress/expected/rules.out
+++ b/src/test/regress/expected/rules.out
@@ -1831,6 +1831,7 @@ pg_stat_checkpointer| SELECT pg_stat_get_checkpointer_num_timed() AS num_timed,
pg_stat_get_checkpointer_write_time() AS write_time,
pg_stat_get_checkpointer_sync_time() AS sync_time,
pg_stat_get_checkpointer_buffers_written() AS buffers_written,
+ pg_stat_get_checkpointer_slru_written() AS slru_written,
pg_stat_get_checkpointer_stat_reset_time() AS stats_reset;
pg_stat_database| SELECT oid AS datid,
datname,
--
2.45.2
Before committing the patch, I revised it with the following changes:
- I added "shared" to the description of pg_stat_checkpointer.buffers_written
to clarify that it tracks shared buffers.
- In the checkpoint log message, I replaced "slru" with "SLRU" for consistency,
as uppercase is typically used for SLRU.
- I updated the commit message.
Thanks for updating. Looks good to me.
Best Regards,
Nitin Jadhav
Azure Database for PostgreSQL
Microsoft
Show quoted text
On Tue, Oct 1, 2024 at 9:28 PM Fujii Masao <masao.fujii@oss.nttdata.com> wrote:
On 2024/10/01 3:33, Fujii Masao wrote:
On 2024/09/22 20:44, Nitin Jadhav wrote:
+ CheckpointStats.ckpt_slru_written, + (double) CheckpointStats.ckpt_slru_written * 100 / NBuffers,I don't think NBuffers represents the maximum number of SLRU buffers.
We might need to calculate this based on specific GUC settings,
like transaction_buffers.Great observation. Since the SLRU buffers written during a checkpoint
can include transaction_buffers, commit_timestamp_buffers,
subtransaction_buffers, multixact_member_buffers,
multixact_offset_buffers, and serializable_buffers, the total count of
SLRU buffers should be the sum of all these types. We might need to
introduce a global variable, such as total_slru_count, in the
globals.c file to hold this sum. The num_slots variable in the
SlruSharedData structure needs to be accessed from all types of SLRU
and stored in total_slru_count. This can then be used during logging
to calculate the percentage of SLRU buffers written. However, I’m
unsure if this effort is justified. While it makes sense for normal
buffers to display the percentage, the additional code required might
not provide significant value to users. Therefore, I have removed this
in the attached v6 patch.+1
Thanks for updating the patch! It looks good to me.
Barring any objections, I will commit this patch.Before committing the patch, I revised it with the following changes:
- I added "shared" to the description of pg_stat_checkpointer.buffers_written
to clarify that it tracks shared buffers.
- In the checkpoint log message, I replaced "slru" with "SLRU" for consistency,
as uppercase is typically used for SLRU.
- I updated the commit message.Regards,
--
Fujii Masao
Advanced Computing Technology Center
Research and Development Headquarters
NTT DATA CORPORATION
On 2024/10/02 1:50, Nitin Jadhav wrote:
Before committing the patch, I revised it with the following changes:
- I added "shared" to the description of pg_stat_checkpointer.buffers_written
to clarify that it tracks shared buffers.
- In the checkpoint log message, I replaced "slru" with "SLRU" for consistency,
as uppercase is typically used for SLRU.
- I updated the commit message.Thanks for updating. Looks good to me.
Thanks for the review! Pushed.
Regards,
--
Fujii Masao
Advanced Computing Technology Center
Research and Development Headquarters
NTT DATA CORPORATION