RE: Conflict detection for update_deleted in logical replication

Hayato Kuroda (Fujitsu) <kuroda.hayato@fujitsu.com>

From: "Hayato Kuroda (Fujitsu)" <kuroda.hayato@fujitsu.com>
To: 'Masahiko Sawada' <sawada.mshk@gmail.com>, "Zhijie Hou (Fujitsu)" <houzj.fnst@fujitsu.com>
Cc: Amit Kapila <amit.kapila16@gmail.com>, Nisha Moond <nisha.moond412@gmail.com>, shveta malik <shveta.malik@gmail.com>, pgsql-hackers <pgsql-hackers@postgresql.org>
Date: 2025-01-10T11:42:54Z
Lists: pgsql-hackers

Attachments

Dear Sawada-san,

Thanks for giving comments. I've created top-up patches for addressing them.

> 1. The launcher could still be sleeping even after the worker updates
> its oldest_nonremovable_xid. We compute the launcher's sleep time by
> doubling the sleep time with 3min maximum time. When I started the
> test, the launcher already entered 3min sleep, and it took a long time
> to advance the slot.xmin for the first time. I think we can improve
> this situation by having the worker send a signal to the launcher
> after updating the worker's oldest_nonremovable_xid so that it can
> quickly update the slot.xmin.

Done in 0006. Worker sends a signal when its oldest_nonremovable_xid is updated.
Also, for the testing purpose, the maximum nap time is shortened to 10s when
retain_conflict_info is enabled. This value can be tuned based on results.

> 2. The apply worker doesn't advance RetainConflictInfoPhase from the
> RCI_WAIT_FOR_LOCAL_FLUSH phase when it's busy. Regarding the phase
> transition from RCI_WAIT_FOR_LOCAL_FLUSH to RCI_GET_CANDIDATE_XID,
> we
> rely on calling maybe_advance_nonremovable_xid() (1) right after
> transitioning to RCI_WAIT_FOR_LOCAL_FLUSH phase, (2) after receiving
> 'k' message, and (3) there is no available incoming data. If we miss
> (1) opportunity (because we still need to wait for the local flush),
> we effectively need to consume all available data to call
> maybe_advance_nonremovable_xid() (note that the publisher doesn't need
> to send 'k' (keepalive) message if it sends data frequently). In the
> test, since I ran pgbench with 30 clients on the publisher and
> therefore there were some apply delays, the apply worker took 25 min
> to get out the inner apply loop in LogicalRepApplyLoop() and advance
> its oldest_nonremovable_xid. I think we need to consider having more
> opportunities to check the local flush LSN.

Done in 0007. The worker now can advance its state machine even when it is busy.
Latest flush position is updating in wait_for_local_flush() too.

> 3. If the apply worker cannot catch up, it could enter to a bad loop;
> the publisher sends huge amount of data -> the apply worker cannot
> catch up -> it needs to wait for a longer time to advance its
> oldest_nonremovable_xid -> more garbage are accumulated and then have
> the apply more slow -> (looping). I'm not sure how to deal with this
> point TBH. We might be able to avoid entering this bad loop once we
> resolve the other two points.

I hope this issue is fixed because the worker can wait the local-flush even
while they are busy.

Best regards,
Hayato Kuroda
FUJITSU LIMITED

Commits

  1. Fix intermittent BF failures in 035_conflicts.

  2. Resume conflict-relevant data retention automatically.

  3. Fix intermittent test failure introduced in 6456c6e2c4.

  4. Fix Coverity issue reported in commit a850be2fe.

  5. Add test to prevent premature removal of conflict-relevant data.

  6. Post-commit review fixes for 228c370868.

  7. Add max_retention_duration option to subscriptions.

  8. Detect and report update_deleted conflicts.

  9. Preserve conflict-relevant data during logical replication.

  10. Integrate FullTransactionIds deeper into two-phase code

  11. Improve checks for GUC recovery_target_timeline

  12. Prevent excessive delays before launching new logrep workers.

  13. Keep WAL segments by slot's last saved restart LSN

  14. Rework some code handling pg_subscription data in psql and pg_dump

  15. Use generateClonedIndexStmt to propagate CREATE INDEX to partitions.