PS_20250131_v4_updates.txt

text/plain

Filename: PS_20250131_v4_updates.txt
Type: text/plain
Part: 0
Message: Re: Improve error handling for invalid slots and ensure a same 'inactive_since' time for inactive slots
diff --git a/src/backend/replication/slot.c b/src/backend/replication/slot.c
index 74f7d56..29f0af9 100644
--- a/src/backend/replication/slot.c
+++ b/src/backend/replication/slot.c
@@ -565,6 +565,19 @@ retry:
 						name)));
 	}
 
+	/* Invalid slots can't be modified or used before accessing the WAL. */
+	if (error_if_invalid && s->data.invalidated != RS_INVAL_NONE)
+	{
+		LWLockRelease(ReplicationSlotControlLock);
+
+		ereport(ERROR,
+				errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
+				errmsg("can no longer access replication slot \"%s\"",
+					   NameStr(s->data.name)),
+				errdetail("This replication slot has been invalidated due to \"%s\".",
+						  SlotInvalidationCauses[s->data.invalidated]));
+	}
+
 	/*
 	 * This is the slot we want; check if it's active under some other
 	 * process.  In single user mode, we don't need this check.
@@ -589,18 +602,6 @@ retry:
 		active_pid = MyProcPid;
 	LWLockRelease(ReplicationSlotControlLock);
 
-	/* We made this slot active, so it's ours now. */
-	MyReplicationSlot = s;
-
-	/* Invalid slots can't be modified or used before accessing the WAL. */
-	if (error_if_invalid && s->data.invalidated != RS_INVAL_NONE)
-		ereport(ERROR,
-				errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
-				errmsg("can no longer access replication slot \"%s\"",
-					   NameStr(s->data.name)),
-				errdetail("This replication slot has been invalidated due to \"%s\".",
-						  SlotInvalidationCauses[s->data.invalidated]));
-
 	/*
 	 * If we found the slot but it's already active in another process, we
 	 * wait until the owning process signals us that it's been released, or
@@ -628,6 +629,9 @@ retry:
 	/* Let everybody know we've modified this slot */
 	ConditionVariableBroadcast(&s->active_cv);
 
+	/* We made this slot active, so it's ours now. */
+	MyReplicationSlot = s;
+
 	/*
 	 * The call to pgstat_acquire_replslot() protects against stats for a
 	 * different slot, from before a restart or such, being present during