agora inbox for [email protected]  
help / color / mirror / Atom feed
From: Bertrand Drouvot <[email protected]>
Subject: [PATCH v2] Adding LWLock protection in pgstat_reset_replslot() and pgstat_fetch_replslot()
Date: Fri, 1 Mar 2024 10:04:17 +0000

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


--dOK0twbJvFkC0VFs--





view thread (11+ messages)  latest in thread

reply

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Reply to all the recipients using the --to and --cc options:
  reply via email

  To: [email protected]
  Cc: [email protected]
  Subject: Re: [PATCH v2] Adding LWLock protection in pgstat_reset_replslot() and pgstat_fetch_replslot()
  In-Reply-To: <no-message-id-1858106@localhost>

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

This inbox is served by agora; see mirroring instructions
for how to clone and mirror all data and code used for this inbox