On Sat, Jul 25, 2026 at 11:03:52PM +0000, Scott Ray wrote: > 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.
Hmm. It looks like you are right here. I am not the most fluent here
with this area of the code, so adding in CC a couple of folks who
could perhaps comment, being usually interested on these matters.
> 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.
+ /*
+ * Scan until no conflicting VXID remains.
[...]
+ for (;;)
+ {
Adding a code pattern that could potentially cause this code path to
loop infinitely is not what I would call a principled approach, I
would call it a risky one.
--
Michael
signature.asc
Description: PGP signature
