From 496966a89acca5eb8e406571637ad00d0135cb5c Mon Sep 17 00:00:00 2001 From: Thomas Munro Date: Fri, 30 Jul 2021 17:27:16 +1200 Subject: [PATCH v3 1/2] Fix race in SERIALIZABLE READ ONLY. Commit bdaabb9b started skipping doomed transactions when building the list of possible conflicts, when obtaining a snapshot for SERIALIZABLE READ ONLY. This had two unintended consequences: 1. With unlucky timing, a transaction will never benefit from the SXACT_FLAG_RO_SAFE optimization, because no one will ever set the flag. 2. In the same circumstances but with DEFERRABLE, an assertion that SXACT_FLAG_RO_SAFE has been set fails. This is really exactly the same as the "opt out" case for PredXact->WritableSxactCount == 0, it just happens a bit later in racy conditions. We should "opt out" in the same way in this case too. Back-patch to all supported releases. Discovered along with bug #17116, but a separate commit to back-patch further. Reported-by: Alexander Lakhin Discussion: https://postgr.es/m/17116-d6ca217acc180e30%40postgresql.org --- src/backend/storage/lmgr/predicate.c | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/src/backend/storage/lmgr/predicate.c b/src/backend/storage/lmgr/predicate.c index 6b5a416873..99386d36a2 100644 --- a/src/backend/storage/lmgr/predicate.c +++ b/src/backend/storage/lmgr/predicate.c @@ -1839,6 +1839,19 @@ GetSerializableTransactionSnapshotInt(Snapshot snapshot, SetPossibleUnsafeConflict(sxact, othersxact); } } + + /* + * If we didn't find any possibly unsafe conflicts because every + * uncommitted writable transaction turned out to be doomed (which + * should be rare), then we can "opt out" immediately. This is a + * variation of the opt out for PredXact->WritableSxactCount == 0. + */ + if (dlist_is_empty(&sxact->possibleUnsafeConflicts)) + { + ReleasePredXact(sxact); + LWLockRelease(SerializableXactHashLock); + return snapshot; + } } else { -- 2.39.1