Add more monitoring data for WAL writes in the WAL receiver
authorMichael Paquier <[email protected]>
Thu, 6 Mar 2025 00:39:45 +0000 (09:39 +0900)
committerMichael Paquier <[email protected]>
Thu, 6 Mar 2025 00:41:37 +0000 (09:41 +0900)
This commit adds two improvements related to the monitoring of WAL
writes for the WAL receiver.

First, write counts and timings are now counted in pg_stat_io for the
WAL receiver.  These have been discarded from pg_stat_wal in
ff99918c625a due to performance concerns, related to the fact that we
still relied on an on-disk file for the stats back then, even with
track_wal_io_timing to avoid the overhead of the timestamp calculations.
This implementation is simpler than the original proposal as it is
possible to rely on the APIs of pgstat_io.c to do the job.  Like the
fsync and read data, track_wal_io_timing needs to be enabled to track
the timings.

Second, a wait event is added around the pg_pwrite() call in charge of
the writes, using the exiting WAIT_EVENT_WAL_WRITE.  This is useful as
the WAL receiver data is tracked in pg_stat_activity.

Reviewed-by: Bertrand Drouvot <[email protected]>
Discussion: https://postgr.es/m/[email protected]

src/backend/replication/walreceiver.c

index 83129cb92afe3f43fc9ebf9a0325b394a2f91e7e..2e5dd6deb2c2e4b4c8d4ff78d7250375ee78e5d6 100644 (file)
@@ -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];