mirror of
https://github.com/postgres/postgres.git
synced 2025-08-05 07:41:25 +03:00
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.
This commit is contained in:
@@ -3757,6 +3757,17 @@ CheckTargetForConflictsIn(PREDICATELOCKTARGETTAG *targettag)
|
|||||||
LWLockRelease(partitionLock);
|
LWLockRelease(partitionLock);
|
||||||
LWLockRelease(SerializablePredicateLockListLock);
|
LWLockRelease(SerializablePredicateLockListLock);
|
||||||
LWLockAcquire(partitionLock, LW_SHARED);
|
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);
|
LWLockAcquire(SerializableXactHashLock, LW_SHARED);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -3770,7 +3781,19 @@ CheckTargetForConflictsIn(PREDICATELOCKTARGETTAG *targettag)
|
|||||||
LWLockRelease(SerializableXactHashLock);
|
LWLockRelease(SerializableXactHashLock);
|
||||||
LWLockAcquire(SerializableXactHashLock, LW_EXCLUSIVE);
|
LWLockAcquire(SerializableXactHashLock, LW_EXCLUSIVE);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* 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);
|
FlagRWConflict(sxact, (SERIALIZABLEXACT *) MySerializableXact);
|
||||||
|
}
|
||||||
|
|
||||||
LWLockRelease(SerializableXactHashLock);
|
LWLockRelease(SerializableXactHashLock);
|
||||||
LWLockAcquire(SerializableXactHashLock, LW_SHARED);
|
LWLockAcquire(SerializableXactHashLock, LW_SHARED);
|
||||||
|
Reference in New Issue
Block a user