summaryrefslogtreecommitdiff
path: root/src/backend/replication/slotfuncs.c
diff options
context:
space:
mode:
authorAlvaro Herrera2020-04-07 22:35:00 +0000
committerAlvaro Herrera2020-04-07 22:35:00 +0000
commitc6550776394e25c1620bc8258427c8f1d448080d (patch)
treeeb5a62fdc5dcca2911d82af615bac3d36f8cf611 /src/backend/replication/slotfuncs.c
parentb63c293bcbd7439f883cd4cf748f6755df0fbb3c (diff)
Allow users to limit storage reserved by replication slots
Replication slots are useful to retain data that may be needed by a replication system. But experience has shown that allowing them to retain excessive data can lead to the primary failing because of running out of space. This new feature allows the user to configure a maximum amount of space to be reserved using the new option max_slot_wal_keep_size. Slots that overrun that space are invalidated at checkpoint time, enabling the storage to be released. Author: Kyotaro HORIGUCHI <[email protected]> Reviewed-by: Masahiko Sawada <[email protected]> Reviewed-by: Jehan-Guillaume de Rorthais <[email protected]> Reviewed-by: Álvaro Herrera <[email protected]> Discussion: https://postgr.es/m/[email protected]
Diffstat (limited to 'src/backend/replication/slotfuncs.c')
-rw-r--r--src/backend/replication/slotfuncs.c44
1 files changed, 42 insertions, 2 deletions
diff --git a/src/backend/replication/slotfuncs.c b/src/backend/replication/slotfuncs.c
index ce0c9127bca..f776de3df7a 100644
--- a/src/backend/replication/slotfuncs.c
+++ b/src/backend/replication/slotfuncs.c
@@ -234,7 +234,7 @@ pg_drop_replication_slot(PG_FUNCTION_ARGS)
Datum
pg_get_replication_slots(PG_FUNCTION_ARGS)
{
-#define PG_GET_REPLICATION_SLOTS_COLS 11
+#define PG_GET_REPLICATION_SLOTS_COLS 13
ReturnSetInfo *rsinfo = (ReturnSetInfo *) fcinfo->resultinfo;
TupleDesc tupdesc;
Tuplestorestate *tupstore;
@@ -288,6 +288,8 @@ pg_get_replication_slots(PG_FUNCTION_ARGS)
Oid database;
NameData slot_name;
NameData plugin;
+ WALAvailability walstate;
+ XLogSegNo last_removed_seg;
int i;
if (!slot->in_use)
@@ -355,6 +357,40 @@ pg_get_replication_slots(PG_FUNCTION_ARGS)
else
nulls[i++] = true;
+ walstate = GetWALAvailability(restart_lsn);
+
+ switch (walstate)
+ {
+ case WALAVAIL_INVALID_LSN:
+ nulls[i++] = true;
+ break;
+
+ case WALAVAIL_NORMAL:
+ values[i++] = CStringGetTextDatum("normal");
+ break;
+
+ case WALAVAIL_RESERVED:
+ values[i++] = CStringGetTextDatum("reserved");
+ break;
+
+ case WALAVAIL_REMOVED:
+ values[i++] = CStringGetTextDatum("lost");
+ break;
+ }
+
+ if (max_slot_wal_keep_size_mb >= 0 &&
+ (walstate == WALAVAIL_NORMAL || walstate == WALAVAIL_RESERVED) &&
+ ((last_removed_seg = XLogGetLastRemovedSegno()) != 0))
+ {
+ XLogRecPtr min_safe_lsn;
+
+ XLogSegNoOffsetToRecPtr(last_removed_seg + 1, 0,
+ wal_segment_size, min_safe_lsn);
+ values[i++] = Int64GetDatum(min_safe_lsn);
+ }
+ else
+ nulls[i++] = true;
+
tuplestore_putvalues(tupstore, tupdesc, values, nulls);
}
LWLockRelease(ReplicationSlotControlLock);
@@ -377,6 +413,8 @@ pg_physical_replication_slot_advance(XLogRecPtr moveto)
XLogRecPtr startlsn = MyReplicationSlot->data.restart_lsn;
XLogRecPtr retlsn = startlsn;
+ Assert(moveto != InvalidXLogRecPtr);
+
if (startlsn < moveto)
{
SpinLockAcquire(&MyReplicationSlot->mutex);
@@ -414,6 +452,8 @@ pg_logical_replication_slot_advance(XLogRecPtr moveto)
ResourceOwner old_resowner = CurrentResourceOwner;
XLogRecPtr retlsn;
+ Assert(moveto != InvalidXLogRecPtr);
+
PG_TRY();
{
/*
@@ -552,7 +592,7 @@ pg_replication_slot_advance(PG_FUNCTION_ARGS)
moveto = Min(moveto, GetXLogReplayRecPtr(&ThisTimeLineID));
/* Acquire the slot so we "own" it */
- ReplicationSlotAcquire(NameStr(*slotname), true);
+ (void) ReplicationSlotAcquire(NameStr(*slotname), SAB_Error);
/* A slot whose restart_lsn has never been reserved cannot be advanced */
if (XLogRecPtrIsInvalid(MyReplicationSlot->data.restart_lsn))