From 4f4a79a65f81db82b8718ee5a2d0d1dae9f515fd Mon Sep 17 00:00:00 2001 From: Robert Haas Date: Fri, 2 Jan 2026 10:03:23 -0500 Subject: [PATCH v1] Always show an invalidated replication slot as "lost". Previously, pg_get_replication_slots() would show "lost" for a slot if either (1) the WAL it was using was thought to have been removed or (2) the slot had been invalidated. However, if the slot was still connected, it would instead show "unreserved" in these cases, which is possibly appropriate for case (1) because, due to a race condition, the diagnosis of "lost" might not be accurate, but is not appropriate for case (2), because slot invalidation is not reversible. Once a slot is invalidated, it is ignored for purposes of deciding how much WAL to reserve and for purposes of hot_standby_feedback, so it's important to be clear about which slots are actually being taken into consideration. In newer releases, this is more clear, because the view also shows the reason for the slot being invalidated -- but calling the state of an invalidated slot "unreserved" seems like a bad idea even if the cause is also shown. In older releases, the confusion is much worse, because there's no clear indication that the slot is invalidated. This problem dates to commit b8fd4e02c6d01183bf6def5897ad6cf7766bfff4, whose interaction with 4ae08cd5fd19d566538005c15e7bf992ebae4c72 most likely wasn't fully understood. Diagnosed-by: Nitin Chobisa Diagnosed-by: Pavan Deolasee Diagnosed-by: Robert Haas Author: Robert Haas --- src/backend/replication/slotfuncs.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/src/backend/replication/slotfuncs.c b/src/backend/replication/slotfuncs.c index 1ed2d80c2d2..95fa28dbc45 100644 --- a/src/backend/replication/slotfuncs.c +++ b/src/backend/replication/slotfuncs.c @@ -374,8 +374,16 @@ pg_get_replication_slots(PG_FUNCTION_ARGS) * still alive, then "unreserved" seems more appropriate. * * If we do change it, save the state for safe_wal_size below. + * + * As an exception to the above, if the slot has actually been + * invalidated, we always want the state to be reported as + * "lost". Invalidated slots are ignored by code such as + * ReplicationSlotsComputeRequiredXmin and + * ReplicationSlotsComputeLogicalRestartLSN, so calling them + * merely "unreserved" seems wrong. */ - if (XLogRecPtrIsValid(slot_contents.data.restart_lsn)) + if (slot_contents.data.invalidated == RS_INVAL_NONE && + XLogRecPtrIsValid(slot_contents.data.restart_lsn)) { int pid; -- 2.51.0