Hi all, While doing some monitoring of a replication setup for a stable branch, I have been surprised by the fact that we have never tracked WAL statistics for the WAL receiver in pg_stat_wal because we have never bothered to update its code so as WAL stats are reported. This is relevant for the write and sync counts and timings. On HEAD, this information has been moved to pg_stat_io, but the stats reports happen with the same routine (pgstat_report_wal in 15~, and pgstat_send_wal in ~14).
As of f4694e0f35b2, the situation is better thanks to the addition of a pgstat_report_wal() in the WAL receiver main loop, so we have some data. However, we are only able to gather the data for segment syncs and initializations, not the writes themselves as these are managed by an independent code path, XLogWalRcvWrite(). A second thing that lacks in XLogWalRcvWrite() is a wait event around the pg_pwrite() call, which is useful as the WAL receiver is listed in pg_stat_activity. Note that it is possible to re-use the same wait event as XLogWrite() for the WAL receiver, WAL_WRITE, because the WAL receiver does not rely on the write and flush calls from xlog.c when doing its work, and both have the same meaning, aka they write WAL. The fsync calls use issue_xlog_fsync() and the segment inits happen in XLogFileInit(). Perhaps there's a point in backpatching a portion of what's in the attached patch (the wait event?), but I am not planning to bother much with the stable branches based on the lack of complaints. If you have an opinion about that, please feel free. Thoughts? -- Michael
From 31baeaf0b0b3291a9edafa76f59f40110d57d00b Mon Sep 17 00:00:00 2001 From: Michael Paquier <mich...@paquier.xyz> Date: Wed, 5 Mar 2025 12:35:01 +0900 Subject: [PATCH] Report WAL writes in stats of the WAL receiver These have never been counted since pg_stat_wal exists, as writes happen in a path of its own. Now these are moved to pg_stat_io. A wait event is added around the pg_pwrite() call in charge of the writes, using the exiting WAIT_EVENT_WAL_WRITE. --- src/backend/replication/walreceiver.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/src/backend/replication/walreceiver.c b/src/backend/replication/walreceiver.c index 83129cb92afe..2e5dd6deb2c2 100644 --- a/src/backend/replication/walreceiver.c +++ b/src/backend/replication/walreceiver.c @@ -922,6 +922,7 @@ XLogWalRcvWrite(char *buf, Size nbytes, XLogRecPtr recptr, TimeLineID tli) { int startoff; int byteswritten; + instr_time start; Assert(tli != 0); @@ -952,7 +953,18 @@ XLogWalRcvWrite(char *buf, Size nbytes, XLogRecPtr recptr, TimeLineID tli) /* OK to write the logs */ errno = 0; + /* + * Measure I/O timing to write WAL data, for pg_stat_io. + */ + start = pgstat_prepare_io_time(track_wal_io_timing); + + pgstat_report_wait_start(WAIT_EVENT_WAL_WRITE); byteswritten = pg_pwrite(recvFile, buf, segbytes, (off_t) startoff); + pgstat_report_wait_end(); + + pgstat_count_io_op_time(IOOBJECT_WAL, IOCONTEXT_NORMAL, + IOOP_WRITE, start, 1, byteswritten); + if (byteswritten <= 0) { char xlogfname[MAXFNAMELEN]; -- 2.47.2
signature.asc
Description: PGP signature