From 1a85c94f93985d39a6090a35d155f6ee6c788c14 Mon Sep 17 00:00:00 2001 From: Naga Appani Date: Sat, 16 Aug 2025 17:51:52 +0000 Subject: [PATCH v4] Rename ReadMultiXactCounts() to GetMultiXactInfo() and make it public Following review feedback from Michael Paquier, this patch exposes GetMultiXactInfo(), a public accessor that returns snapshot of MultiXact state (counts and horizons) in one call, replacing ReadMultiXactCounts(). Provide a single snapshot of MultiXact state and return: - multixacts - members - oldestMultiXactId - oldestOffset Return false when the oldest offset is not known; in that case set all outputs to 0/invalid for consistency. Declare the function in multixact.h and switch MultiXactMemberFreezeThreshold() to the new API. This accessor underpins pg_get_multixact_stats() and is available to extensions that wish to monitor MultiXact usage. Author: Naga Appani Reviewed-by: Ashutosh Bapat Reviewed-by: Michael Paquier Discussion: https://www.postgresql.org/message-id/flat/CA%2BQeY%2BAAsYK6WvBW4qYzHz4bahHycDAY_q5ECmHkEV_eB9ckzg%40mail.gmail.com --- src/backend/access/transam/multixact.c | 45 ++++++++++++++++++-------- src/include/access/multixact.h | 1 + 2 files changed, 32 insertions(+), 14 deletions(-) diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index 3cb09c3d598..eeeec81abc9 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -2859,31 +2859,46 @@ find_multixact_start(MultiXactId multi, MultiXactOffset *result) } /* - * Determine how many multixacts, and how many multixact members, currently - * exist. Return false if unable to determine. + * GetMultiXactInfo + * + * Returns information about current MultiXact state in a single atomic read: + * - multixacts: Number of MultiXacts (nextMultiXactId - oldestMultiXactId) + * - members: Number of member entries (nextOffset - oldestOffset) + * - oldestMultiXactId: Oldest MultiXact ID still in use + * - oldestOffset: Oldest offset still in use + * + * Returns false if the oldest offset is not known, in which case all output + * parameters are set to 0/invalid values for consistency. */ -static bool -ReadMultiXactCounts(uint32 *multixacts, MultiXactOffset *members) +bool +GetMultiXactInfo(uint32 *multixacts, MultiXactOffset *members, + MultiXactId *oldestMultiXactId, MultiXactOffset *oldestOffset) { - MultiXactOffset nextOffset; - MultiXactOffset oldestOffset; - MultiXactId oldestMultiXactId; - MultiXactId nextMultiXactId; - bool oldestOffsetKnown; + MultiXactOffset nextOffset; + MultiXactId nextMultiXactId; + bool oldestOffsetKnown; + /* Take one consistent snapshot of the state */ LWLockAcquire(MultiXactGenLock, LW_SHARED); nextOffset = MultiXactState->nextOffset; - oldestMultiXactId = MultiXactState->oldestMultiXactId; + *oldestMultiXactId = MultiXactState->oldestMultiXactId; nextMultiXactId = MultiXactState->nextMXact; - oldestOffset = MultiXactState->oldestOffset; + *oldestOffset = MultiXactState->oldestOffset; oldestOffsetKnown = MultiXactState->oldestOffsetKnown; LWLockRelease(MultiXactGenLock); if (!oldestOffsetKnown) + { + /* Set all outputs to 0/invalid for consistency */ + *members = 0; + *multixacts = 0; + *oldestMultiXactId = InvalidMultiXactId; + *oldestOffset = 0; return false; + } - *members = nextOffset - oldestOffset; - *multixacts = nextMultiXactId - oldestMultiXactId; + *members = nextOffset - *oldestOffset; + *multixacts = nextMultiXactId - *oldestMultiXactId; return true; } @@ -2922,9 +2937,11 @@ MultiXactMemberFreezeThreshold(void) uint32 victim_multixacts; double fraction; int result; + MultiXactId oldestMultiXactId; + MultiXactOffset oldestOffset; /* If we can't determine member space utilization, assume the worst. */ - if (!ReadMultiXactCounts(&multixacts, &members)) + if (!GetMultiXactInfo(&multixacts, &members, &oldestMultiXactId, &oldestOffset)) return 0; /* If member space utilization is low, no special action is required. */ diff --git a/src/include/access/multixact.h b/src/include/access/multixact.h index b876e98f46e..e0878461c2c 100644 --- a/src/include/access/multixact.h +++ b/src/include/access/multixact.h @@ -158,5 +158,6 @@ extern void multixact_desc(StringInfo buf, XLogReaderState *record); extern const char *multixact_identify(uint8 info); extern char *mxid_to_string(MultiXactId multi, int nmembers, MultiXactMember *members); +extern bool GetMultiXactInfo(uint32 *multixacts, MultiXactOffset *members, MultiXactId *oldestMultiXactId, MultiXactOffset *oldestOffset); #endif /* MULTIXACT_H */ -- 2.47.3