1
0
mirror of https://github.com/postgres/postgres.git synced 2025-07-07 00:36:50 +03:00

Dirty replication slots when using sql interface

When pg_logical_slot_get_changes(...) sets confirmed_flush_lsn to the point at
which replay stopped, it doesn't dirty the replication slot.  So if the replay
didn't cause restart_lsn or catalog_xmin to change as well, this change will
not get written out to disk. Even on a clean shutdown.

If Pg crashes or restarts, a subsequent pg_logical_slot_get_changes(...) call
will see the same changes already replayed since it uses the slot's
confirmed_flush_lsn as the start point for fetching changes. The caller can't
specify a start LSN when using the SQL interface.

Mark the slot as dirty after reading changes using the SQL interface so that
users won't see repeated changes after a clean shutdown. Repeated changes still
occur when using the walsender interface or after an unclean shutdown.

Craig Ringer
This commit is contained in:
Simon Riggs
2016-09-05 09:44:38 +01:00
parent b6182081be
commit d851bef2d6
3 changed files with 57 additions and 0 deletions

View File

@ -321,7 +321,22 @@ pg_logical_slot_get_changes_guts(FunctionCallInfo fcinfo, bool confirm, bool bin
* business..)
*/
if (ctx->reader->EndRecPtr != InvalidXLogRecPtr && confirm)
{
LogicalConfirmReceivedLocation(ctx->reader->EndRecPtr);
/*
* If only the confirmed_flush_lsn has changed the slot won't get
* marked as dirty by the above. Callers on the walsender interface
* are expected to keep track of their own progress and don't need
* it written out. But SQL-interface users cannot specify their own
* start positions and it's harder for them to keep track of their
* progress, so we should make more of an effort to save it for them.
*
* Dirty the slot so it's written out at the next checkpoint. We'll
* still lose its position on crash, as documented, but it's better
* than always losing the position even on clean restart.
*/
ReplicationSlotMarkDirty();
}
/* free context, call shutdown callback */
FreeDecodingContext(ctx);