From 86412fa32be2c2c0736714ebf868c62ed9824d3f Mon Sep 17 00:00:00 2001 From: Shihao Date: Mon, 21 Sep 2026 10:10:13 -0400 Subject: [PATCH v6 2/2] Store the PID of a backend in its statistics entry With stats_fetch_consistency set to "snapshot", the statistics of a backend could be reported under the PID of a newer backend that reused its proc number. Store the PID of the backend in PgStat_Backend when the entry is created, and ignore an entry whose PID does not match the one requested. A reset zeroes the whole entry, so a copy of the PID is kept in PgStatShared_Backend and restored by the reset callback. Reported-by: Bertrand Drouvot Author: Shihao Zhong Discussion: https://postgr.es/m/arD/w47Ug1GaObfq@bdtpg --- src/backend/utils/activity/pgstat_backend.c | 20 +++++++++++++++++++- src/include/pgstat.h | 1 + src/include/utils/pgstat_internal.h | 6 ++++++ 3 files changed, 26 insertions(+), 1 deletion(-) diff --git a/src/backend/utils/activity/pgstat_backend.c b/src/backend/utils/activity/pgstat_backend.c index 59bc7e699b5..b75563ca2fc 100644 --- a/src/backend/utils/activity/pgstat_backend.c +++ b/src/backend/utils/activity/pgstat_backend.c @@ -189,6 +189,17 @@ pgstat_fetch_stat_backend_by_pid(int pid, BackendType *bktype, Oid *userid) * value of stats_fetch_consistency, so do not access it from this point. */ backend_stats = pgstat_fetch_stat_backend(procNumber); + + if (backend_stats && backend_stats->pid != pid) + backend_stats = NULL; + if (!backend_stats) { if (bktype) @@ -414,6 +425,8 @@ pgstat_create_backend(ProcNumber procnum) * e.g. if we previously used this proc number. */ memset(&shstatent->stats, 0, sizeof(shstatent->stats)); + shstatent->stats.pid = MyProcPid; + shstatent->pid = MyProcPid; pgstat_unlock_entry(entry_ref); MemSet(&PendingBackendStats, 0, sizeof(PgStat_BackendPending)); @@ -483,5 +496,10 @@ pgstat_tracks_backend_bktype(BackendType bktype) void pgstat_backend_reset_timestamp_cb(PgStatShared_Common *header, TimestampTz ts) { - ((PgStatShared_Backend *) header)->stats.stat_reset_timestamp = ts; + PgStatShared_Backend *shstatent = (PgStatShared_Backend *) header; + + shstatent->stats.stat_reset_timestamp = ts; + + /* a reset zeroes the whole entry, so restore the PID of its owner */ + shstatent->stats.pid = shstatent->pid; } diff --git a/src/include/pgstat.h b/src/include/pgstat.h index 4c3dcc03df5..bce475aacab 100644 --- a/src/include/pgstat.h +++ b/src/include/pgstat.h @@ -591,6 +591,7 @@ typedef struct PgStat_WalStats */ typedef struct PgStat_Backend { + int pid; /* PID of the backend owning these stats */ TimestampTz stat_reset_timestamp; PgStat_BktypeIO io_stats; PgStat_WalCounters wal_counters; diff --git a/src/include/utils/pgstat_internal.h b/src/include/utils/pgstat_internal.h index 14369e59a1c..d512635fb30 100644 --- a/src/include/utils/pgstat_internal.h +++ b/src/include/utils/pgstat_internal.h @@ -536,6 +536,12 @@ typedef struct PgStatShared_Backend { PgStatShared_Common header; PgStat_Backend stats; + + int pid; } PgStatShared_Backend; /* -- 2.37.1 (Apple Git-137.1)