aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/backend/replication/slot.c32
1 files changed, 16 insertions, 16 deletions
diff --git a/src/backend/replication/slot.c b/src/backend/replication/slot.c
index d089085b491..719e531eb90 100644
--- a/src/backend/replication/slot.c
+++ b/src/backend/replication/slot.c
@@ -580,19 +580,6 @@ 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\".",
- GetSlotInvalidationCauseName(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.
@@ -650,13 +637,26 @@ retry:
else if (!nowait)
ConditionVariableCancelSleep(); /* no sleep needed after all */
- /* Let everybody know we've modified this slot */
- ConditionVariableBroadcast(&s->active_cv);
-
/* We made this slot active, so it's ours now. */
MyReplicationSlot = s;
/*
+ * We need to check for invalidation after making the slot ours to avoid
+ * the possible race condition with the checkpointer that can otherwise
+ * invalidate the slot immediately after the check.
+ */
+ 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\".",
+ GetSlotInvalidationCauseName(s->data.invalidated)));
+
+ /* Let everybody know we've modified this slot */
+ ConditionVariableBroadcast(&s->active_cv);
+
+ /*
* The call to pgstat_acquire_replslot() protects against stats for a
* different slot, from before a restart or such, being present during
* pgstat_report_replslot().