From 020b9a770ceedce2e3769a6474e6b9ff76333046 Mon Sep 17 00:00:00 2001 From: Ubuntu Date: Thu, 4 Sep 2025 16:00:23 +0000 Subject: [PATCH v2 1/1] Fix PgStat_HashKey padding issue when passed by value Adding a new OID field to PgStat_HashKey introduced 4 bytes of hole padding. When the key was passed by value to pgstat_get_entry_ref_cached(), builds with -O2 or higher optimization sometimes left the padding uninitialized. Since hash/compare functions of the key rely on the the full struct contents, inconsistent padding caused spurious errors such as "entry ref vanished before deletion". Passing the key by reference ensures padding is preserved and avoids mismatches under optimization. Other hash key uses were reviewed and do not appear to be affected. --- src/backend/utils/activity/pgstat_shmem.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/src/backend/utils/activity/pgstat_shmem.c b/src/backend/utils/activity/pgstat_shmem.c index 9dc3212f7dd..2824b092cda 100644 --- a/src/backend/utils/activity/pgstat_shmem.c +++ b/src/backend/utils/activity/pgstat_shmem.c @@ -395,9 +395,13 @@ pgstat_acquire_entry_ref(PgStat_EntryRef *entry_ref, /* * Helper function for pgstat_get_entry_ref(). + * + * Use pass-by-reference for PgStat_HashKey to preserve any padding bytes + * previously zeroed by the caller. Passing by value could leave these + * bytes uninitialized, breaking key comparisons in pgstat_cmp_hash_key. */ static bool -pgstat_get_entry_ref_cached(PgStat_HashKey key, PgStat_EntryRef **entry_ref_p) +pgstat_get_entry_ref_cached(PgStat_HashKey *key, PgStat_EntryRef **entry_ref_p) { bool found; PgStat_EntryRefHashEntry *cache_entry; @@ -408,7 +412,7 @@ pgstat_get_entry_ref_cached(PgStat_HashKey key, PgStat_EntryRef **entry_ref_p) * out-of-memory errors after incrementing PgStatShared_Common->refcount. */ - cache_entry = pgstat_entry_ref_hash_insert(pgStatEntryRefHash, key, &found); + cache_entry = pgstat_entry_ref_hash_insert(pgStatEntryRefHash, *key, &found); if (!found || !cache_entry->entry_ref) { @@ -497,7 +501,7 @@ pgstat_get_entry_ref(PgStat_Kind kind, Oid dboid, uint64 objid, bool create, * First check the lookup cache hashtable in local memory. If we find a * match here we can avoid taking locks / causing contention. */ - if (pgstat_get_entry_ref_cached(key, &entry_ref)) + if (pgstat_get_entry_ref_cached(&key, &entry_ref)) return entry_ref; Assert(entry_ref != NULL); -- 2.43.0