mirror of
https://github.com/postgres/postgres.git
synced 2025-06-27 23:21:58 +03:00
Fix thinko in lock mode enum
Commit 0e5680f473
contained a thinko
mixing LOCKMODE with LockTupleMode. This caused misbehavior in the case
where a tuple is marked with a multixact with at most a FOR SHARE lock,
and another transaction tries to acquire a FOR NO KEY EXCLUSIVE lock;
this case should block but doesn't.
Include a new isolation tester spec file to explicitely try all the
tuple lock combinations; without the fix it shows the problem:
starting permutation: s1_begin s1_lcksvpt s1_tuplock2 s2_tuplock3 s1_commit
step s1_begin: BEGIN;
step s1_lcksvpt: SELECT * FROM multixact_conflict FOR KEY SHARE; SAVEPOINT foo;
a
1
step s1_tuplock2: SELECT * FROM multixact_conflict FOR SHARE;
a
1
step s2_tuplock3: SELECT * FROM multixact_conflict FOR NO KEY UPDATE;
a
1
step s1_commit: COMMIT;
With the fixed code, step s2_tuplock3 blocks until session 1 commits,
which is the correct behavior.
All other cases behave correctly.
Backpatch to 9.3, like the commit that introduced the problem.
This commit is contained in:
@ -6102,6 +6102,7 @@ DoesMultiXactIdConflict(MultiXactId multi, uint16 infomask,
|
||||
int nmembers;
|
||||
MultiXactMember *members;
|
||||
bool result = false;
|
||||
LOCKMODE wanted = tupleLockExtraInfo[lockmode].hwlock;
|
||||
|
||||
allow_old = !(infomask & HEAP_LOCK_MASK) && HEAP_XMAX_IS_LOCKED_ONLY(infomask);
|
||||
nmembers = GetMultiXactIdMembers(multi, &members, allow_old,
|
||||
@ -6113,11 +6114,12 @@ DoesMultiXactIdConflict(MultiXactId multi, uint16 infomask,
|
||||
for (i = 0; i < nmembers; i++)
|
||||
{
|
||||
TransactionId memxid;
|
||||
LockTupleMode memlockmode;
|
||||
LOCKMODE memlockmode;
|
||||
|
||||
memlockmode = LOCKMODE_from_mxstatus(members[i].status);
|
||||
|
||||
/* ignore members that don't conflict with the lock we want */
|
||||
if (!DoLockModesConflict(memlockmode, lockmode))
|
||||
if (!DoLockModesConflict(memlockmode, wanted))
|
||||
continue;
|
||||
|
||||
/* ignore members from current xact */
|
||||
|
Reference in New Issue
Block a user