"=?utf-8?B?55uP5LiA?=" <w...@www.hidva.com> writes: > The code in GetSnapshotData() that read the `xid` field of PGXACT > struct has a dependency on code in GetNewTransactionId() that write > `MyPgXact->xid`. It means that the store of xid should happen before the > load of it. In C11, we can use [Release-Acquire > ordering](https://en.cppreference.com/w/c/atomic/memory_order#Release-Acquire_ordering) > to achieve it. But now, there is no special operation to do it(, and the > [volatile](https://en.cppreference.com/w/c/language/volatile) keyword should > not play any role in this situation). > So it means that when a backend A returns from GetNewTransactionId(), the > newval of `MyPgXact->xid` maybe just in CPU store buffer, or CPU cache > line, so the newval is not yet visible to backend B that calling > GetSnapshotData(). So the assumption that 'all top-level XIDs <= > latestCompletedXid are either present in the ProcArray, or not running > anymore' may not be safe.
You'e ignoring the memory barriers that are implicit in LWLock acquisition and release; as well as the fact that it's transaction end, not start, that needs to be interlocked. Please read the section "Interlocking Transaction Begin, Transaction End, and Snapshots" in src/backend/access/transam/README. regards, tom lane