diff --git a/src/backend/replication/slot.c b/src/backend/replication/slot.c index 21ae8531b3..edf661521a 100644 --- a/src/backend/replication/slot.c +++ b/src/backend/replication/slot.c @@ -672,6 +672,23 @@ ReplicationSlotMarkDirty(void) SpinLockRelease(&slot->mutex); } +/* + * Verify whether currently acquired slot is dirty. + */ +bool +ReplicationSlotIsDirty(void) +{ + bool dirty; + + Assert(MyReplicationSlot != NULL); + + SpinLockAcquire(&MyReplicationSlot->mutex); + dirty = MyReplicationSlot->dirty; + SpinLockRelease(&MyReplicationSlot->mutex); + + return dirty; +} + /* * Convert a slot that's marked as RS_EPHEMERAL to a RS_PERSISTENT slot, * guaranteeing it will be there after an eventual crash. diff --git a/src/backend/replication/slotfuncs.c b/src/backend/replication/slotfuncs.c index 6683fc3f9b..d7a16a9071 100644 --- a/src/backend/replication/slotfuncs.c +++ b/src/backend/replication/slotfuncs.c @@ -370,6 +370,12 @@ pg_physical_replication_slot_advance(XLogRecPtr moveto) MyReplicationSlot->data.restart_lsn = moveto; SpinLockRelease(&MyReplicationSlot->mutex); retlsn = moveto; + + /* + * Dirty the slot as we updated data that is meant to be + * persistent on disk. + */ + ReplicationSlotMarkDirty(); } return retlsn; @@ -574,9 +580,8 @@ pg_replication_slot_advance(PG_FUNCTION_ARGS) nulls[0] = false; /* Update the on disk state when lsn was updated. */ - if (XLogRecPtrIsInvalid(endlsn)) + if (ReplicationSlotIsDirty()) { - ReplicationSlotMarkDirty(); ReplicationSlotsComputeRequiredXmin(false); ReplicationSlotsComputeRequiredLSN(); ReplicationSlotSave(); diff --git a/src/include/replication/slot.h b/src/include/replication/slot.h index 3a5763fb07..f76b84571f 100644 --- a/src/include/replication/slot.h +++ b/src/include/replication/slot.h @@ -189,6 +189,7 @@ extern void ReplicationSlotRelease(void); extern void ReplicationSlotCleanup(void); extern void ReplicationSlotSave(void); extern void ReplicationSlotMarkDirty(void); +extern bool ReplicationSlotIsDirty(void); /* misc stuff */ extern bool ReplicationSlotValidateName(const char *name, int elevel);