From 6d3ea48ff1aea5fb1ccfed69424bf93a8643b4a4 Mon Sep 17 00:00:00 2001 From: Michael Paquier Date: Wed, 19 Mar 2025 08:03:06 +0900 Subject: [PATCH] Optimize check for pending backend IO stats This commit changes the backend stats code so as we rely on a single boolean rather than a repeated check based on pg_memory_is_all_zeros() in the code, making it cheaper should PgStat_PendingIO get bigger in size. The frequency of backend stats reports is not a bottleneck, but there is no reason to not make that cheaper, and the logic is simple as the only entry points updating backend IO stats are pgstat_count_backend_io_op() and pgstat_count_backend_io_op_time(). Author: Bertrand Drouvot Reviewed-by: Xuneng Zhou Discussion: https://postgr.es/m/Z8WYf1jyy4MwOveQ@ip-10-97-1-34.eu-west-3.compute.internal --- src/backend/utils/activity/pgstat_backend.c | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/src/backend/utils/activity/pgstat_backend.c b/src/backend/utils/activity/pgstat_backend.c index 5518a18e060..187c5c76e1e 100644 --- a/src/backend/utils/activity/pgstat_backend.c +++ b/src/backend/utils/activity/pgstat_backend.c @@ -37,6 +37,7 @@ * memory allocation. */ static PgStat_BackendPending PendingBackendStats; +static bool backend_has_iostats = false; /* * WAL usage counters saved from pgWalUsage at the previous call to @@ -63,6 +64,8 @@ pgstat_count_backend_io_op_time(IOObject io_object, IOContext io_context, INSTR_TIME_ADD(PendingBackendStats.pending_io.pending_times[io_object][io_context][io_op], io_time); + + backend_has_iostats = true; } void @@ -76,6 +79,8 @@ pgstat_count_backend_io_op(IOObject io_object, IOContext io_context, PendingBackendStats.pending_io.counts[io_object][io_context][io_op] += cnt; PendingBackendStats.pending_io.bytes[io_object][io_context][io_op] += bytes; + + backend_has_iostats = true; } /* @@ -158,8 +163,7 @@ pgstat_flush_backend_entry_io(PgStat_EntryRef *entry_ref) * statistics. In this case, avoid unnecessarily modifying the stats * entry. */ - if (pg_memory_is_all_zeros(&PendingBackendStats.pending_io, - sizeof(struct PgStat_PendingIO))) + if (!backend_has_iostats) return; shbackendent = (PgStatShared_Backend *) entry_ref->shared_stats; @@ -190,6 +194,8 @@ pgstat_flush_backend_entry_io(PgStat_EntryRef *entry_ref) * Clear out the statistics buffer, so it can be re-used. */ MemSet(&PendingBackendStats.pending_io, 0, sizeof(PgStat_PendingIO)); + + backend_has_iostats = false; } /* @@ -259,9 +265,7 @@ pgstat_flush_backend(bool nowait, bits32 flags) return false; /* Some IO data pending? */ - if ((flags & PGSTAT_BACKEND_FLUSH_IO) && - !pg_memory_is_all_zeros(&PendingBackendStats.pending_io, - sizeof(struct PgStat_PendingIO))) + if ((flags & PGSTAT_BACKEND_FLUSH_IO) && backend_has_iostats) has_pending_data = true; /* Some WAL data pending? */ @@ -298,9 +302,7 @@ pgstat_backend_have_pending_cb(void) if (!pgstat_tracks_backend_bktype(MyBackendType)) return false; - return (!pg_memory_is_all_zeros(&PendingBackendStats, - sizeof(struct PgStat_BackendPending)) || - pgstat_backend_wal_have_pending()); + return (backend_has_iostats || pgstat_backend_wal_have_pending()); } /* @@ -335,6 +337,7 @@ pgstat_create_backend(ProcNumber procnum) pgstat_unlock_entry(entry_ref); MemSet(&PendingBackendStats, 0, sizeof(PgStat_BackendPending)); + backend_has_iostats = false; /* * Initialize prevBackendWalUsage with pgWalUsage so that