From c1ca96900c8e719820f37408bfff83af027401b1 Mon Sep 17 00:00:00 2001 From: Michael Paquier Date: Tue, 4 Mar 2025 09:15:08 +0900 Subject: [PATCH] Fix some gaps with pg_stat_wal and WAL-related processes The WAL receiver and WAL summarizer processes gain each one a call to pgstat_report_wal(), to make sure that they report their WAL statistics. pg_stat_io is adjusted so as these processes do not report any rows when the IOObject is not WAL, making the view easier to use. --- src/backend/postmaster/walsummarizer.c | 4 ++++ src/backend/replication/walreceiver.c | 10 ++++++++++ src/backend/utils/activity/pgstat_io.c | 12 +++++++++++- src/bin/pg_walsummary/t/002_blocks.pl | 7 +++++++ src/test/recovery/t/001_stream_rep.pl | 7 +++++++ 5 files changed, 39 insertions(+), 1 deletion(-) diff --git a/src/backend/postmaster/walsummarizer.c b/src/backend/postmaster/walsummarizer.c index f4d61c1f3bb8..17cb6984a01d 100644 --- a/src/backend/postmaster/walsummarizer.c +++ b/src/backend/postmaster/walsummarizer.c @@ -33,6 +33,7 @@ #include "common/blkreftable.h" #include "libpq/pqsignal.h" #include "miscadmin.h" +#include "pgstat.h" #include "postmaster/auxprocess.h" #include "postmaster/interrupt.h" #include "postmaster/walsummarizer.h" @@ -1543,6 +1544,9 @@ summarizer_read_local_xlog_page(XLogReaderState *state, HandleWalSummarizerInterrupts(); summarizer_wait_for_wal(); + /* report pending statistics to the cumulative stats system */ + pgstat_report_wal(false); + /* Recheck end-of-WAL. */ latest_lsn = GetLatestLSN(&latest_tli); if (private_data->tli == latest_tli) diff --git a/src/backend/replication/walreceiver.c b/src/backend/replication/walreceiver.c index 82f7302ff9fd..6cb22ec2bfd7 100644 --- a/src/backend/replication/walreceiver.c +++ b/src/backend/replication/walreceiver.c @@ -583,6 +583,16 @@ WalReceiverMain(const void *startup_data, size_t startup_data_len) */ bool requestReply = false; + /* + * Report pending statistics to the cumulative stats + * system. This location is useful for the report as it is + * not within a tight loop in the WAL receiver, which + * would bloat requests to pgstats, while also making sure + * that the reports happen at least each time a status + * update is sent. + */ + pgstat_report_wal(false); + /* * Check if time since last receive from primary has * reached the configured limit. diff --git a/src/backend/utils/activity/pgstat_io.c b/src/backend/utils/activity/pgstat_io.c index ba11545a17f3..eb5750255961 100644 --- a/src/backend/utils/activity/pgstat_io.c +++ b/src/backend/utils/activity/pgstat_io.c @@ -435,12 +435,22 @@ pgstat_tracks_io_object(BackendType bktype, IOObject io_object, */ no_temp_rel = bktype == B_AUTOVAC_LAUNCHER || bktype == B_BG_WRITER || bktype == B_CHECKPOINTER || bktype == B_AUTOVAC_WORKER || - bktype == B_STANDALONE_BACKEND || bktype == B_STARTUP; + bktype == B_STANDALONE_BACKEND || bktype == B_STARTUP || + bktype == B_WAL_SUMMARIZER || bktype == B_WAL_WRITER || + bktype == B_WAL_RECEIVER; if (no_temp_rel && io_context == IOCONTEXT_NORMAL && io_object == IOOBJECT_TEMP_RELATION) return false; + /* + * Some BackendTypes only perform IO under IOOBJECT_WAL, hence exclude all + * rows for all the other objects for these. + */ + if ((bktype == B_WAL_SUMMARIZER || bktype == B_WAL_RECEIVER || + bktype == B_WAL_WRITER) && io_object != IOOBJECT_WAL) + return false; + /* * Some BackendTypes do not currently perform any IO in certain * IOContexts, and, while it may not be inherently incorrect for them to diff --git a/src/bin/pg_walsummary/t/002_blocks.pl b/src/bin/pg_walsummary/t/002_blocks.pl index 27f29a3b0c68..270332780a45 100644 --- a/src/bin/pg_walsummary/t/002_blocks.pl +++ b/src/bin/pg_walsummary/t/002_blocks.pl @@ -46,6 +46,13 @@ SELECT EXISTS ( EOM ok($result, "WAL summarization caught up after insert"); +# The WAL summarizer should have generated some IO statistics. +my $stats_reads = $node1->safe_psql( + 'postgres', + qq{SELECT sum(reads) > 0 FROM pg_stat_io + WHERE backend_type = 'walsummarizer' AND object = 'wal'}); +is($stats_reads, 't', "WAL summarizer generates statistics for WAL reads"); + # Find the highest LSN that is summarized on disk. my $summarized_lsn = $node1->safe_psql('postgres', <append_conf('postgresql.conf', "primary_slot_name = ''"); $node_standby_2->enable_streaming($node_primary); $node_standby_2->reload; +# The WAL receiver should have generated some IO statistics. +my $stats_reads = $node_standby_1->safe_psql( + 'postgres', + qq{SELECT sum(writes) > 0 FROM pg_stat_io + WHERE backend_type = 'walreceiver' AND object = 'wal'}); +is($stats_reads, 't', "WAL receiver generates statistics for WAL writes"); + # be sure do not streaming from cascade $node_standby_1->stop; -- 2.47.2