RE: Conflict detection for update_deleted in logical replication
Zhijie Hou (Fujitsu) <houzj.fnst@fujitsu.com>
On Tuesday, January 7, 2025 2:00 PM Masahiko Sawada <sawada.mshk@gmail.com> wrote: Hi, > > On Mon, Jan 6, 2025 at 3:22 AM Zhijie Hou (Fujitsu) <houzj.fnst@fujitsu.com> > wrote: > > > > On Friday, January 3, 2025 2:36 PM Masahiko Sawada > <sawada.mshk@gmail.com> wrote: > > > > > > > > I have one comment on the 0001 patch: > > > > Thanks for the comments! > > > > > > > > + /* > > > + * The changes made by this and later transactions are still > > > non-removable > > > + * to allow for the detection of update_deleted conflicts > > > + when > > > applying > > > + * changes in this logical replication worker. > > > + * > > > + * Note that this info cannot directly protect dead tuples from > being > > > + * prematurely frozen or removed. The logical replication launcher > > > + * asynchronously collects this info to determine whether to > > > + advance > > > the > > > + * xmin value of the replication slot. > > > + * > > > + * Therefore, FullTransactionId that includes both the > > > transaction ID and > > > + * its epoch is used here instead of a single Transaction ID. This is > > > + * critical because without considering the epoch, the transaction > ID > > > + * alone may appear as if it is in the future due to transaction ID > > > + * wraparound. > > > + */ > > > + FullTransactionId oldest_nonremovable_xid; > > > > > > The last paragraph of the comment mentions that we need to use > > > FullTransactionId to properly compare XIDs even after the XID > > > wraparound happens. But once we set the oldest-nonremovable-xid it > > > prevents XIDs from being wraparound, no? I mean that workers' > > > oldest-nonremovable-xid values and slot's non-removal-xid (i.e., its > > > xmin) are never away from more than 2^31 XIDs. > > > > I think the issue is that the launcher may create the replication slot > > after the apply worker has already set the 'oldest_nonremovable_xid' > > because the launcher are doing that asynchronously. So, Before the > > slot is created, there's a window where transaction IDs might wrap > > around. If initially the apply worker has computed a candidate_xid > > (755) and the xid wraparound before the launcher creates the slot, > > causing the new current xid to be (740), then the old > > candidate_xid(755) looks like a xid in the future, and the launcher > > could advance the xmin to 755 which cause the dead tuples to be removed > prematurely. > > (We are trying to reproduce this to ensure that it's a real issue and > > will share after finishing) > > The slot's first xmin is calculated by > GetOldestSafeDecodingTransactionId(false). The initial computed > cancidate_xid could be newer than this xid? I think the issue occurs when the slot is created after an XID wraparound. As a result, GetOldestSafeDecodingTransactionId() returns the current XID (after wraparound), which appears older than the computed candidate_xid (e.g., oldest_nonremovable_xid). Nisha has shared detailed steps to reproduce the issue in [1]. What do you think ? [1] https://www.postgresql.org/message-id/CABdArM6P0zoEVRN%2B3YHNET_oOaAVOKc-EPUnXiHkcBJ-uDKQVw%40mail.gmail.com Best Regards, Hou zj
Commits
-
Fix intermittent BF failures in 035_conflicts.
- 0f42206531b3 19 (unreleased) landed
-
Resume conflict-relevant data retention automatically.
- 0d48d393d465 19 (unreleased) landed
-
Fix intermittent test failure introduced in 6456c6e2c4.
- 01d793698f59 19 (unreleased) landed
-
Fix Coverity issue reported in commit a850be2fe.
- 5ac3c1ac22cb 19 (unreleased) landed
-
Add test to prevent premature removal of conflict-relevant data.
- 6456c6e2c4ad 19 (unreleased) landed
-
Post-commit review fixes for 228c370868.
- 1f7e9ba3ac4e 19 (unreleased) landed
-
Add max_retention_duration option to subscriptions.
- a850be2fe653 19 (unreleased) landed
-
Detect and report update_deleted conflicts.
- fd5a1a0c3e56 19 (unreleased) landed
-
Preserve conflict-relevant data during logical replication.
- 228c37086855 19 (unreleased) landed
-
Integrate FullTransactionIds deeper into two-phase code
- 62a17a92833d 19 (unreleased) cited
-
Improve checks for GUC recovery_target_timeline
- fd7d7b719137 19 (unreleased) cited
-
Prevent excessive delays before launching new logrep workers.
- fd519419c948 18.0 cited
-
Keep WAL segments by slot's last saved restart LSN
- ca307d5cec90 18.0 cited
-
Rework some code handling pg_subscription data in psql and pg_dump
- 08691ea958c2 18.0 cited
-
Use generateClonedIndexStmt to propagate CREATE INDEX to partitions.
- 68dfecbef210 18.0 cited