On Fri, Sep 4, 2026 at 7:42 AM Zhijie Hou (Fujitsu) <[email protected]> wrote: > > Apart from above comments, I also addressed comments from Kuroda-San[1] and > Nisha[2]. >
Thanks for the updated patch.
I was testing/reviewing the retention stop-resume path when two dbs
(say db1 and db2) are involved. I see a race condition between the
launcher and the worker that leads to the same assert.
When a sub resumes retention on db2, update_retention_status(true)
sets subretentionactive = true and calls ApplyLauncherWakeup() before
the worker restarts itself through apply_worker_exit().
Now if the launcher runs its next cycle while the old worker's entry
is still in_use(say we hold it just before apply_worker_exit), then in
that cycle, launcher will -
- add the db2 to retained_dbids.
- fire the reset because db2 is not yet in the set.
- Finds w != NULL (still old worker), so
compute_min_nonremovable_xid() reads the "InvalidTransactionId" left
by the earlier stop and returns without contributing to the result.
Now the situation is that update_conflict_slot_xmin() advances the
slot to the horizon of db1 (which can be way ahead of db2's horizon).
When eventually a new worker starts for db2's subscription with a
valid oldest_xmin based on db2's horizon, in the next launcher cycle,
since db2 is already in the retained_dbids list, it will not fire the
reset again. The slot.xmin stays advanced, and when the db2 worker
reaches get_candidate_xid() with its old xmin, it hits the same
assertion.
TRAP: failed
Assert("TransactionIdPrecedesOrEquals(MyLogicalRepWorker->oldest_nonremovable_xid,
oldest_running_xid)"), File: "worker.c", Line: 4536, PID: 60377
0 postgres 0x0000000100ac5144
ExceptionalCondition + 216
1 postgres 0x00000001007979c4
get_candidate_xid + 196
2 postgres 0x00000001007978ac
process_rdt_phase_transition + 128
3 postgres 0x00000001007973bc
maybe_advance_nonremovable_xid + 56
4 postgres 0x0000000100791b6c
LogicalRepApplyLoop + 1456
5 postgres 0x00000001007914f0 start_apply + 120
...
Attached is a TAP test that reproduces this issue using an injection
point. The patch applies on top of v2-0001.
--
Thanks,
Nisha
v2-0002-Reproducer-TAP-test.patch
Description: Binary data
