aboutsummaryrefslogtreecommitdiff
path: root/src/backend/replication/slot.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/backend/replication/slot.c')
-rw-r--r--src/backend/replication/slot.c26
1 files changed, 23 insertions, 3 deletions
diff --git a/src/backend/replication/slot.c b/src/backend/replication/slot.c
index 1dc7ec64e46..02047ea9207 100644
--- a/src/backend/replication/slot.c
+++ b/src/backend/replication/slot.c
@@ -1130,11 +1130,14 @@ ReplicationSlotReserveWal(void)
* Returns whether ReplicationSlotControlLock was released in the interim (and
* in that case we're not holding the lock at return, otherwise we are).
*
+ * Sets *invalidated true if the slot was invalidated. (Untouched otherwise.)
+ *
* This is inherently racy, because we release the LWLock
* for syscalls, so caller must restart if we return true.
*/
static bool
-InvalidatePossiblyObsoleteSlot(ReplicationSlot *s, XLogRecPtr oldestLSN)
+InvalidatePossiblyObsoleteSlot(ReplicationSlot *s, XLogRecPtr oldestLSN,
+ bool *invalidated)
{
int last_signaled_pid = 0;
bool released_lock = false;
@@ -1191,6 +1194,9 @@ InvalidatePossiblyObsoleteSlot(ReplicationSlot *s, XLogRecPtr oldestLSN)
s->active_pid = MyProcPid;
s->data.invalidated_at = restart_lsn;
s->data.restart_lsn = InvalidXLogRecPtr;
+
+ /* Let caller know */
+ *invalidated = true;
}
SpinLockRelease(&s->mutex);
@@ -1279,12 +1285,15 @@ InvalidatePossiblyObsoleteSlot(ReplicationSlot *s, XLogRecPtr oldestLSN)
* Mark any slot that points to an LSN older than the given segment
* as invalid; it requires WAL that's about to be removed.
*
+ * Returns true when any slot have got invalidated.
+ *
* NB - this runs as part of checkpoint, so avoid raising errors if possible.
*/
-void
+bool
InvalidateObsoleteReplicationSlots(XLogSegNo oldestSegno)
{
XLogRecPtr oldestLSN;
+ bool invalidated = false;
XLogSegNoOffsetToRecPtr(oldestSegno, 0, wal_segment_size, oldestLSN);
@@ -1297,13 +1306,24 @@ restart:
if (!s->in_use)
continue;
- if (InvalidatePossiblyObsoleteSlot(s, oldestLSN))
+ if (InvalidatePossiblyObsoleteSlot(s, oldestLSN, &invalidated))
{
/* if the lock was released, start from scratch */
goto restart;
}
}
LWLockRelease(ReplicationSlotControlLock);
+
+ /*
+ * If any slots have been invalidated, recalculate the resource limits.
+ */
+ if (invalidated)
+ {
+ ReplicationSlotsComputeRequiredXmin(false);
+ ReplicationSlotsComputeRequiredLSN();
+ }
+
+ return invalidated;
}
/*