diff --git a/src/backend/replication/slot.c b/src/backend/replication/slot.c index e8761f3a18..57bbb6288c 100644 --- a/src/backend/replication/slot.c +++ b/src/backend/replication/slot.c @@ -1157,6 +1157,7 @@ restart: if (XLogRecPtrIsInvalid(restart_lsn) || restart_lsn >= oldestLSN) continue; LWLockRelease(ReplicationSlotControlLock); + CHECK_FOR_INTERRUPTS(); /* Get ready to sleep on the slot in case it is active */ ConditionVariablePrepareToSleep(&s->active_cv); @@ -1214,10 +1215,7 @@ restart: * already been dropped. */ if (wspid == -1) - { - CHECK_FOR_INTERRUPTS(); goto restart; - } ereport(LOG, (errmsg("invalidating slot \"%s\" because its restart_lsn %X/%X exceeds max_slot_wal_keep_size", @@ -1229,10 +1227,13 @@ restart: s->data.invalidated_at = s->data.restart_lsn; s->data.restart_lsn = InvalidXLogRecPtr; SpinLockRelease(&s->mutex); + + /* Make sure the invalidated state persists across server restart */ + ReplicationSlotMarkDirty(); + ReplicationSlotSave(); ReplicationSlotRelease(); /* if we did anything, start from scratch */ - CHECK_FOR_INTERRUPTS(); goto restart; } LWLockRelease(ReplicationSlotControlLock); diff --git a/src/backend/replication/slotfuncs.c b/src/backend/replication/slotfuncs.c index fca18ffae5..88033a79b2 100644 --- a/src/backend/replication/slotfuncs.c +++ b/src/backend/replication/slotfuncs.c @@ -283,7 +283,6 @@ pg_get_replication_slots(PG_FUNCTION_ARGS) bool nulls[PG_GET_REPLICATION_SLOTS_COLS]; WALAvailability walstate; XLogSegNo last_removed_seg; - XLogRecPtr targetLSN; int i; if (!slot->in_use) @@ -344,14 +343,15 @@ pg_get_replication_slots(PG_FUNCTION_ARGS) nulls[i++] = true; /* - * Report availability from invalidated_at when the slot has been - * invalidated; otherwise slots would appear as invalid without any - * more clues as to what happened. + * If invalidated_at is valid and restart_lsn is invalid, we know for + * certain that the slot has been invalidated. Otherwise, test + * availability from restart_lsn. */ - targetLSN = XLogRecPtrIsInvalid(slot_contents.data.restart_lsn) ? - slot_contents.data.invalidated_at : - slot_contents.data.restart_lsn; - walstate = GetWALAvailability(targetLSN); + if (XLogRecPtrIsInvalid(slot_contents.data.restart_lsn) && + !XLogRecPtrIsInvalid(slot_contents.data.invalidated_at)) + walstate = WALAVAIL_REMOVED; + else + walstate = GetWALAvailability(slot_contents.data.restart_lsn); switch (walstate) {