Handle auxiliary processes in SQL functions of backend statistics
authorMichael Paquier <[email protected]>
Mon, 3 Mar 2025 00:57:48 +0000 (09:57 +0900)
committerMichael Paquier <[email protected]>
Mon, 3 Mar 2025 00:57:48 +0000 (09:57 +0900)
This commit impacts the following SQL functions, authorizing the access
to the PGPROC entries of auxiliary processes when attempting to fetch or
reset backend-level pgstats entries:
- pg_stat_reset_backend_stats()
- pg_stat_get_backend_io()

This is relevant since a051e71e28a1 for at least the WAL summarizer, WAL
receiver and WAL writer processes, that has changed the backend
statistics to authorize these three following the addition of WAL I/O
statistics in pg_stat_io and backend statistics.  The code is more
flexible with future changes written this way, adapting automatically to
any updates done in pgstat_tracks_backend_bktype().

While on it, pgstat_report_wal() gains a call to pgstat_flush_backend(),
making sure that backend I/O statistics are updated when calling this
routine.  This makes the statistics report correctly for the WAL writer.
WAL receiver and WAL summarizer do not call pgstat_report_wal() yet
(spoiler: both should).  It should be possible to lift some of the
existing restrictions for other auxiliary processes, as well, but this
is left as future work.

Reported-by: Rahila Syed <[email protected]>
Author: Bertrand Drouvot <[email protected]>
Discussion: https://postgr.es/m/CAH2L28v9BwN8_y0k6FQ591=0g2Hj_esHLGj3bP38c9nmVykoiA@mail.gmail.com

src/backend/utils/activity/pgstat_backend.c
src/backend/utils/activity/pgstat_wal.c
src/backend/utils/adt/pgstatfuncs.c

index 3c9ebbcd69c01603a42b66b1e00f97369959676a..a9343b7b59e93529d4e4969659fbe9808cc65890 100644 (file)
@@ -103,11 +103,10 @@ pgstat_fetch_stat_backend_by_pid(int pid, BackendType *bktype)
    if (bktype)
        *bktype = B_INVALID;
 
-   /*
-    * This could be an auxiliary process but these do not report backend
-    * statistics due to pgstat_tracks_backend_bktype(), so there is no need
-    * for an extra call to AuxiliaryPidGetProc().
-    */
+   /* this could be an auxiliary process */
+   if (!proc)
+       proc = AuxiliaryPidGetProc(pid);
+
    if (!proc)
        return NULL;
 
@@ -117,6 +116,10 @@ pgstat_fetch_stat_backend_by_pid(int pid, BackendType *bktype)
    if (!beentry)
        return NULL;
 
+   /* check if the backend type tracks statistics */
+   if (!pgstat_tracks_backend_bktype(beentry->st_backendType))
+       return NULL;
+
    backend_stats = pgstat_fetch_stat_backend(procNumber);
    if (!backend_stats)
        return NULL;
@@ -125,10 +128,6 @@ pgstat_fetch_stat_backend_by_pid(int pid, BackendType *bktype)
    if (beentry->st_procpid != pid)
        return NULL;
 
-   /* backend may be gone, so recheck in case */
-   if (beentry->st_backendType == B_INVALID)
-       return NULL;
-
    if (bktype)
        *bktype = beentry->st_backendType;
 
index 943be0cbeefd85a1e59ad3459d5dbf6b9bab316e..5d3da4b674e7a6f255647637fab23aa611fa1bec 100644 (file)
@@ -55,6 +55,7 @@ pgstat_report_wal(bool force)
 
    /* flush IO stats */
    pgstat_flush_io(nowait);
+   (void) pgstat_flush_backend(nowait, PGSTAT_BACKEND_FLUSH_IO);
 }
 
 /*
index 68830db8633d919df85b1fdd4d9391512cc0ba28..0212d8d5906b730e709ca8bd7f055eeb19dc4bc3 100644 (file)
@@ -1919,19 +1919,30 @@ Datum
 pg_stat_reset_backend_stats(PG_FUNCTION_ARGS)
 {
    PGPROC     *proc;
+   PgBackendStatus *beentry;
+   ProcNumber  procNumber;
    int         backend_pid = PG_GETARG_INT32(0);
 
    proc = BackendPidGetProc(backend_pid);
 
-   /*
-    * This could be an auxiliary process but these do not report backend
-    * statistics due to pgstat_tracks_backend_bktype(), so there is no need
-    * for an extra call to AuxiliaryPidGetProc().
-    */
+   /* This could be an auxiliary process */
+   if (!proc)
+       proc = AuxiliaryPidGetProc(backend_pid);
+
    if (!proc)
        PG_RETURN_VOID();
 
-   pgstat_reset(PGSTAT_KIND_BACKEND, InvalidOid, GetNumberFromPGProc(proc));
+   procNumber = GetNumberFromPGProc(proc);
+
+   beentry = pgstat_get_beentry_by_proc_number(procNumber);
+   if (!beentry)
+       PG_RETURN_VOID();
+
+   /* Check if the backend type tracks statistics */
+   if (!pgstat_tracks_backend_bktype(beentry->st_backendType))
+       PG_RETURN_VOID();
+
+   pgstat_reset(PGSTAT_KIND_BACKEND, InvalidOid, procNumber);
 
    PG_RETURN_VOID();
 }