Invent pgstat_fetch_stat_backend_by_pid()
authorMichael Paquier <[email protected]>
Fri, 28 Feb 2025 02:20:31 +0000 (11:20 +0900)
committerMichael Paquier <[email protected]>
Fri, 28 Feb 2025 02:20:31 +0000 (11:20 +0900)
This code is extracted from pg_stat_get_backend_io() in pgstatfuncs.c,
so as it can be shared with other areas that need backend pgstats
entries while having the benefits of the various sanity checks
refactored here.  As per its name, this retrieves backend statistics
based on a PID, with the option of retrieving a BackendType if given in
input.

Currently, this is used for the backend-level IO statistics.  The next
move would be to reuse that for the backend-level WAL statistics.

Author: Bertrand Drouvot <[email protected]>
Discussion: https://postgr.es/m/Z3zqc4o09dM/[email protected]

src/backend/utils/activity/pgstat_backend.c
src/backend/utils/adt/pgstatfuncs.c
src/include/pgstat.h

index 338da73a9a91bf55138101a8685e1bbbc6eec8b8..3c9ebbcd69c01603a42b66b1e00f97369959676a 100644 (file)
@@ -26,6 +26,8 @@
 
 #include "access/xlog.h"
 #include "storage/bufmgr.h"
+#include "storage/proc.h"
+#include "storage/procarray.h"
 #include "utils/memutils.h"
 #include "utils/pgstat_internal.h"
 
@@ -82,6 +84,57 @@ pgstat_fetch_stat_backend(ProcNumber procNumber)
    return backend_entry;
 }
 
+/*
+ * Returns statistics of a backend by pid.
+ *
+ * This routine includes sanity checks to ensire that the backend exists and
+ * is running.  "bktype" can be optionally defined to return the BackendType
+ * of the backend whose statistics are returned.
+ */
+PgStat_Backend *
+pgstat_fetch_stat_backend_by_pid(int pid, BackendType *bktype)
+{
+   PGPROC     *proc;
+   PgBackendStatus *beentry;
+   ProcNumber  procNumber;
+   PgStat_Backend *backend_stats;
+
+   proc = BackendPidGetProc(pid);
+   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().
+    */
+   if (!proc)
+       return NULL;
+
+   procNumber = GetNumberFromPGProc(proc);
+
+   beentry = pgstat_get_beentry_by_proc_number(procNumber);
+   if (!beentry)
+       return NULL;
+
+   backend_stats = pgstat_fetch_stat_backend(procNumber);
+   if (!backend_stats)
+       return NULL;
+
+   /* if PID does not match, leave */
+   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;
+
+   return backend_stats;
+}
+
 /*
  * Flush out locally pending backend IO statistics.  Locking is managed
  * by the caller.
index efb6d0032afe726b5a6d0d40861f499982ee83d7..68830db8633d919df85b1fdd4d9391512cc0ba28 100644 (file)
@@ -1576,46 +1576,18 @@ pg_stat_get_backend_io(PG_FUNCTION_ARGS)
    ReturnSetInfo *rsinfo;
    BackendType bktype;
    int         pid;
-   PGPROC     *proc;
-   ProcNumber  procNumber;
    PgStat_Backend *backend_stats;
    PgStat_BktypeIO *bktype_stats;
-   PgBackendStatus *beentry;
 
    InitMaterializedSRF(fcinfo, 0);
    rsinfo = (ReturnSetInfo *) fcinfo->resultinfo;
 
    pid = PG_GETARG_INT32(0);
-   proc = BackendPidGetProc(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().
-    */
-   if (!proc)
-       return (Datum) 0;
-
-   procNumber = GetNumberFromPGProc(proc);
+   backend_stats = pgstat_fetch_stat_backend_by_pid(pid, &bktype);
 
-   beentry = pgstat_get_beentry_by_proc_number(procNumber);
-   if (!beentry)
-       return (Datum) 0;
-
-   backend_stats = pgstat_fetch_stat_backend(procNumber);
    if (!backend_stats)
        return (Datum) 0;
 
-   bktype = beentry->st_backendType;
-
-   /* if PID does not match, leave */
-   if (beentry->st_procpid != pid)
-       return (Datum) 0;
-
-   /* backend may be gone, so recheck in case */
-   if (bktype == B_INVALID)
-       return (Datum) 0;
-
    bktype_stats = &backend_stats->io_stats;
 
    /*
index 67656264b62472cd5435cbd76da0dee60c2f7287..4aad10b0b6d5bed89957819db77bae7d871e3fbe 100644 (file)
@@ -554,6 +554,8 @@ extern void pgstat_count_backend_io_op(IOObject io_object,
                                       IOOp io_op, uint32 cnt,
                                       uint64 bytes);
 extern PgStat_Backend *pgstat_fetch_stat_backend(ProcNumber procNumber);
+extern PgStat_Backend *pgstat_fetch_stat_backend_by_pid(int pid,
+                                                       BackendType *bktype);
 extern bool pgstat_tracks_backend_bktype(BackendType bktype);
 extern void pgstat_create_backend(ProcNumber procnum);