| From: | Scott Ray <scott(at)scottray(dot)io> |
|---|---|
| To: | PostgreSQL Hackers <pgsql-hackers(at)lists(dot)postgresql(dot)org> |
| Subject: | Recovery conflict resolution misses backends that import snapshots |
| Date: | 2026-07-25 23:03:52 |
| Message-ID: | QpAansP4iVg_ttSs9x81PFAptL2sqR3AS06u8Jksm3_bHJvUwQjHOocRajbxBc3iiLdf9ZMC6gtXjZsxdxvOmqp98hLZcZuWyBDuQxS6uZc=@scottray.io |
| Views: | Whole Thread | Raw Message | Download mbox | Resend email |
| Thread: | |
| Lists: | pgsql-hackers |
Hello,
There is a silent bug in standby conflict resolution that can cause
incorrect results. In ResolveRecoveryConflictWithSnapshot, the standby
calls GetConflictingVirtualXIDs once, then waits for each returned VXID
to disappear. However, after GetConflictingVirtualXIDs releases the
ProcArrayLock, a backend may import a conflicting snapshot from one of
the backends GetConflictingVirtualXIDs identified as conflicting. The
resulting VXID conflicts with recovery, but
ResolveRecoveryConflictWithSnapshot doesn't know it has to wait for the
new VXID to disappear before proceeding, so the standby removes tuple
versions or index entries that the importing backend needs.
This problem has existed since PG 10 (6c2003f8a1b), which introduced
standby snapshot export and broke ResolveRecoveryConflictWithSnapshot's
assumption that after GetConflictingVirtualXIDs returns, no new
conflicting VXIDs can be created.
The first attached patch adds a TAP test that fails deterministically
on unpatched master. The second makes
ResolveRecoveryConflictWithSnapshot call GetConflictingVirtualXIDs
until the result is empty, at which point importing a conflicting
snapshot is impossible: acquiring a conflicting xmin requires a live,
conflicting VXID as a source.
--
Scott Ray
| Attachment | Content-Type | Size |
|---|---|---|
| v1-0002-Fix-recovery-conflict-resolution-to-account-for-i.patch | application/octet-stream | 4.6 KB |
| v1-0001-Add-TAP-test-for-recovery-conflicts-from-imported.patch | application/octet-stream | 6.9 KB |
| From | Date | Subject | |
|---|---|---|---|
| Next Message | Michael Paquier | 2026-07-25 23:36:42 | Re: NULL pointer dereference in syslogger with load_libraries() and -DEXEC_BACKEND at startup |
| Previous Message | Tom Lane | 2026-07-25 22:51:31 | Re: Self-join elimination drops an equality qual |