From fabee924c3131692addfe8941e4bdb3dc5540aae Mon Sep 17 00:00:00 2001 From: Bertrand Drouvot Date: Fri, 1 Mar 2024 10:04:17 +0000 Subject: [PATCH v2] Adding LWLock protection in pgstat_reset_replslot() and pgstat_fetch_replslot() pgstat_reset_replslot() and pgstat_fetch_replslot() are missing a LWLock protection as we don't have any guarantee that the slot is active (then preventing it to be dropped/recreated) when those functions are executed. --- src/backend/utils/activity/pgstat_replslot.c | 35 +++++++++++++++----- 1 file changed, 27 insertions(+), 8 deletions(-) 100.0% src/backend/utils/activity/ diff --git a/src/backend/utils/activity/pgstat_replslot.c b/src/backend/utils/activity/pgstat_replslot.c index 70cabf2881..7c409af670 100644 --- a/src/backend/utils/activity/pgstat_replslot.c +++ b/src/backend/utils/activity/pgstat_replslot.c @@ -30,7 +30,7 @@ #include "utils/pgstat_internal.h" -static int get_replslot_index(const char *name); +static int get_replslot_index(const char *name, bool need_lock); /* @@ -46,8 +46,10 @@ pgstat_reset_replslot(const char *name) Assert(name != NULL); + LWLockAcquire(ReplicationSlotControlLock, LW_SHARED); + /* Check if the slot exits with the given name. */ - slot = SearchNamedReplicationSlot(name, true); + slot = SearchNamedReplicationSlot(name, false); if (!slot) ereport(ERROR, @@ -60,11 +62,16 @@ pgstat_reset_replslot(const char *name) * slots. */ if (SlotIsPhysical(slot)) + { + LWLockRelease(ReplicationSlotControlLock); return; + } /* reset this one entry */ pgstat_reset(PGSTAT_KIND_REPLSLOT, InvalidOid, ReplicationSlotIndex(slot)); + + LWLockRelease(ReplicationSlotControlLock); } /* @@ -164,13 +171,25 @@ pgstat_drop_replslot(ReplicationSlot *slot) PgStat_StatReplSlotEntry * pgstat_fetch_replslot(NameData slotname) { - int idx = get_replslot_index(NameStr(slotname)); + int idx; + PgStat_StatReplSlotEntry *slotentry; + + LWLockAcquire(ReplicationSlotControlLock, LW_SHARED); + + idx = get_replslot_index(NameStr(slotname), false); if (idx == -1) + { + LWLockRelease(ReplicationSlotControlLock); return NULL; + } + + slotentry = (PgStat_StatReplSlotEntry *) pgstat_fetch_entry(PGSTAT_KIND_REPLSLOT, + InvalidOid, idx); + + LWLockRelease(ReplicationSlotControlLock); - return (PgStat_StatReplSlotEntry *) - pgstat_fetch_entry(PGSTAT_KIND_REPLSLOT, InvalidOid, idx); + return slotentry; } void @@ -189,7 +208,7 @@ pgstat_replslot_to_serialized_name_cb(const PgStat_HashKey *key, const PgStatSha bool pgstat_replslot_from_serialized_name_cb(const NameData *name, PgStat_HashKey *key) { - int idx = get_replslot_index(NameStr(*name)); + int idx = get_replslot_index(NameStr(*name), true); /* slot might have been deleted */ if (idx == -1) @@ -209,13 +228,13 @@ pgstat_replslot_reset_timestamp_cb(PgStatShared_Common *header, TimestampTz ts) } static int -get_replslot_index(const char *name) +get_replslot_index(const char *name, bool need_lock) { ReplicationSlot *slot; Assert(name != NULL); - slot = SearchNamedReplicationSlot(name, true); + slot = SearchNamedReplicationSlot(name, need_lock); if (!slot) return -1; -- 2.34.1