Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Commit 4ae08cd

Browse files
committed
Persist slot invalidation correctly
We failed to save slot to disk after invalidating it, so the state was lost in case of server restart or crash. Fix by marking it dirty and flushing. Also, if the slot is known invalidated we don't need to reason about the LSN at all -- it's known invalidated. Only test the LSN if the slot is known not invalidated. Author: Fujii Masao <masao.fujii@oss.nttdata.com> Author: Kyotaro Horiguchi <horikyota.ntt@gmail.com> Reviewed-by: Álvaro Herrera <alvherre@alvh.no-ip.org> Discussion: https://postgr.es/m/17a69cfe-f1c1-a416-ee25-ae15427c69eb@oss.nttdata.com
1 parent eca08f5 commit 4ae08cd

File tree

2 files changed

+13
-12
lines changed

2 files changed

+13
-12
lines changed

src/backend/replication/slot.c

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1157,6 +1157,7 @@ InvalidateObsoleteReplicationSlots(XLogSegNo oldestSegno)
11571157
if (XLogRecPtrIsInvalid(restart_lsn) || restart_lsn >= oldestLSN)
11581158
continue;
11591159
LWLockRelease(ReplicationSlotControlLock);
1160+
CHECK_FOR_INTERRUPTS();
11601161

11611162
/* Get ready to sleep on the slot in case it is active */
11621163
ConditionVariablePrepareToSleep(&s->active_cv);
@@ -1214,10 +1215,7 @@ InvalidateObsoleteReplicationSlots(XLogSegNo oldestSegno)
12141215
* already been dropped.
12151216
*/
12161217
if (wspid == -1)
1217-
{
1218-
CHECK_FOR_INTERRUPTS();
12191218
goto restart;
1220-
}
12211219

12221220
ereport(LOG,
12231221
(errmsg("invalidating slot \"%s\" because its restart_lsn %X/%X exceeds max_slot_wal_keep_size",
@@ -1229,10 +1227,13 @@ InvalidateObsoleteReplicationSlots(XLogSegNo oldestSegno)
12291227
s->data.invalidated_at = s->data.restart_lsn;
12301228
s->data.restart_lsn = InvalidXLogRecPtr;
12311229
SpinLockRelease(&s->mutex);
1230+
1231+
/* Make sure the invalidated state persists across server restart */
1232+
ReplicationSlotMarkDirty();
1233+
ReplicationSlotSave();
12321234
ReplicationSlotRelease();
12331235

12341236
/* if we did anything, start from scratch */
1235-
CHECK_FOR_INTERRUPTS();
12361237
goto restart;
12371238
}
12381239
LWLockRelease(ReplicationSlotControlLock);

src/backend/replication/slotfuncs.c

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -283,7 +283,6 @@ pg_get_replication_slots(PG_FUNCTION_ARGS)
283283
bool nulls[PG_GET_REPLICATION_SLOTS_COLS];
284284
WALAvailability walstate;
285285
XLogSegNo last_removed_seg;
286-
XLogRecPtr targetLSN;
287286
int i;
288287

289288
if (!slot->in_use)
@@ -344,14 +343,15 @@ pg_get_replication_slots(PG_FUNCTION_ARGS)
344343
nulls[i++] = true;
345344

346345
/*
347-
* Report availability from invalidated_at when the slot has been
348-
* invalidated; otherwise slots would appear as invalid without any
349-
* more clues as to what happened.
346+
* If invalidated_at is valid and restart_lsn is invalid, we know for
347+
* certain that the slot has been invalidated. Otherwise, test
348+
* availability from restart_lsn.
350349
*/
351-
targetLSN = XLogRecPtrIsInvalid(slot_contents.data.restart_lsn) ?
352-
slot_contents.data.invalidated_at :
353-
slot_contents.data.restart_lsn;
354-
walstate = GetWALAvailability(targetLSN);
350+
if (XLogRecPtrIsInvalid(slot_contents.data.restart_lsn) &&
351+
!XLogRecPtrIsInvalid(slot_contents.data.invalidated_at))
352+
walstate = WALAVAIL_REMOVED;
353+
else
354+
walstate = GetWALAvailability(slot_contents.data.restart_lsn);
355355

356356
switch (walstate)
357357
{

0 commit comments

Comments
 (0)