From 632f0faa7c975e8984ce0f1d6b631478e41a96c2 Mon Sep 17 00:00:00 2001 From: Robert Haas Date: Tue, 5 Apr 2011 15:16:59 -0400 Subject: [PATCH] Repair some flakiness in CheckTargetForConflictsIn. When we release and reacquire SerializableXactHashLock, we must recheck whether an R/W conflict still needs to be flagged, because it could have changed under us in the meantime. And when we release the partition lock, we must re-walk the list of predicate locks from the beginning, because our pointer could get invalidated under us. Bug report #5952 by Yamamoto Takashi. Patch by Kevin Grittner. --- src/backend/storage/lmgr/predicate.c | 25 ++++++++++++++++++++++++- 1 file changed, 24 insertions(+), 1 deletion(-) diff --git a/src/backend/storage/lmgr/predicate.c b/src/backend/storage/lmgr/predicate.c index 401acdb471..5096ea0c1c 100644 --- a/src/backend/storage/lmgr/predicate.c +++ b/src/backend/storage/lmgr/predicate.c @@ -3757,6 +3757,17 @@ CheckTargetForConflictsIn(PREDICATELOCKTARGETTAG *targettag) LWLockRelease(partitionLock); LWLockRelease(SerializablePredicateLockListLock); LWLockAcquire(partitionLock, LW_SHARED); + + /* + * The list may have been altered by another process + * while we weren't holding the partition lock. Start + * over at the front. + */ + nextpredlock = (PREDICATELOCK *) + SHMQueueNext(&(target->predicateLocks), + &(target->predicateLocks), + offsetof(PREDICATELOCK, targetLink)); + LWLockAcquire(SerializableXactHashLock, LW_SHARED); } } @@ -3770,7 +3781,19 @@ CheckTargetForConflictsIn(PREDICATELOCKTARGETTAG *targettag) LWLockRelease(SerializableXactHashLock); LWLockAcquire(SerializableXactHashLock, LW_EXCLUSIVE); - FlagRWConflict(sxact, (SERIALIZABLEXACT *) MySerializableXact); + /* + * Re-check after getting exclusive lock because the other + * transaction may have flagged a conflict. + */ + if (!SxactIsRolledBack(sxact) + && (!SxactIsCommitted(sxact) + || TransactionIdPrecedes(GetTransactionSnapshot()->xmin, + sxact->finishedBefore)) + && !RWConflictExists(sxact, + (SERIALIZABLEXACT *) MySerializableXact)) + { + FlagRWConflict(sxact, (SERIALIZABLEXACT *) MySerializableXact); + } LWLockRelease(SerializableXactHashLock); LWLockAcquire(SerializableXactHashLock, LW_SHARED); -- 2.40.0