@@ -95,7 +95,7 @@ static void GetMultiXactIdHintBits(MultiXactId multi, uint16 *new_infomask,
9595static TransactionId MultiXactIdGetUpdateXid (TransactionId xmax ,
9696 uint16 t_infomask );
9797static bool DoesMultiXactIdConflict (MultiXactId multi , uint16 infomask ,
98- LockTupleMode lockmode , bool * current_is_member );
98+ LockTupleMode lockmode );
9999static void MultiXactIdWait (MultiXactId multi , MultiXactStatus status , uint16 infomask ,
100100 Relation rel , ItemPointer ctid , XLTW_Oper oper ,
101101 int * remaining );
@@ -2547,20 +2547,15 @@ heap_delete(Relation relation, ItemPointer tid,
25472547 */
25482548 if (infomask & HEAP_XMAX_IS_MULTI )
25492549 {
2550- bool current_is_member = false;
2551-
2550+ /* wait for multixact */
25522551 if (DoesMultiXactIdConflict ((MultiXactId ) xwait , infomask ,
2553- LockTupleExclusive , & current_is_member ))
2552+ LockTupleExclusive ))
25542553 {
25552554 LockBuffer (buffer , BUFFER_LOCK_UNLOCK );
25562555
2557- /*
2558- * Acquire the lock, if necessary (but skip it when we're
2559- * requesting a lock and already have one; avoids deadlock).
2560- */
2561- if (!current_is_member )
2562- heap_acquire_tuplock (relation , & (tp .t_self ), LockTupleExclusive ,
2563- LockWaitBlock , & have_tuple_lock );
2556+ /* acquire tuple lock, if necessary */
2557+ heap_acquire_tuplock (relation , & (tp .t_self ), LockTupleExclusive ,
2558+ LockWaitBlock , & have_tuple_lock );
25642559
25652560 /* wait for multixact */
25662561 MultiXactIdWait ((MultiXactId ) xwait , MultiXactStatusUpdate , infomask ,
@@ -3131,20 +3126,15 @@ heap_update(Relation relation, ItemPointer otid, HeapTuple newtup,
31313126 {
31323127 TransactionId update_xact ;
31333128 int remain ;
3134- bool current_is_member = false;
31353129
31363130 if (DoesMultiXactIdConflict ((MultiXactId ) xwait , infomask ,
3137- * lockmode , & current_is_member ))
3131+ * lockmode ))
31383132 {
31393133 LockBuffer (buffer , BUFFER_LOCK_UNLOCK );
31403134
3141- /*
3142- * Acquire the lock, if necessary (but skip it when we're
3143- * requesting a lock and already have one; avoids deadlock).
3144- */
3145- if (!current_is_member )
3146- heap_acquire_tuplock (relation , & (oldtup .t_self ), * lockmode ,
3147- LockWaitBlock , & have_tuple_lock );
3135+ /* acquire tuple lock, if necessary */
3136+ heap_acquire_tuplock (relation , & (oldtup .t_self ), * lockmode ,
3137+ LockWaitBlock , & have_tuple_lock );
31483138
31493139 /* wait for multixact */
31503140 MultiXactIdWait ((MultiXactId ) xwait , mxact_status , infomask ,
@@ -4038,7 +4028,6 @@ heap_lock_tuple(Relation relation, HeapTuple tuple,
40384028 uint16 infomask ;
40394029 uint16 infomask2 ;
40404030 bool require_sleep ;
4041- bool skip_tuple_lock = false;
40424031 ItemPointerData t_ctid ;
40434032
40444033 /* must copy state data before unlocking buffer */
@@ -4092,21 +4081,6 @@ heap_lock_tuple(Relation relation, HeapTuple tuple,
40924081 result = TM_Ok ;
40934082 goto out_unlocked ;
40944083 }
4095- else
4096- {
4097- /*
4098- * Disable acquisition of the heavyweight tuple lock.
4099- * Otherwise, when promoting a weaker lock, we might
4100- * deadlock with another locker that has acquired the
4101- * heavyweight tuple lock and is waiting for our
4102- * transaction to finish.
4103- *
4104- * Note that in this case we still need to wait for
4105- * the multixact if required, to avoid acquiring
4106- * conflicting locks.
4107- */
4108- skip_tuple_lock = true;
4109- }
41104084 }
41114085
41124086 if (members )
@@ -4261,7 +4235,7 @@ heap_lock_tuple(Relation relation, HeapTuple tuple,
42614235 if (infomask & HEAP_XMAX_IS_MULTI )
42624236 {
42634237 if (!DoesMultiXactIdConflict ((MultiXactId ) xwait , infomask ,
4264- mode , NULL ))
4238+ mode ))
42654239 {
42664240 /*
42674241 * No conflict, but if the xmax changed under us in the
@@ -4338,15 +4312,13 @@ heap_lock_tuple(Relation relation, HeapTuple tuple,
43384312 /*
43394313 * Acquire tuple lock to establish our priority for the tuple, or
43404314 * die trying. LockTuple will release us when we are next-in-line
4341- * for the tuple. We must do this even if we are share-locking,
4342- * but not if we already have a weaker lock on the tuple.
4315+ * for the tuple. We must do this even if we are share-locking.
43434316 *
43444317 * If we are forced to "start over" below, we keep the tuple lock;
43454318 * this arranges that we stay at the head of the line while
43464319 * rechecking tuple state.
43474320 */
4348- if (!skip_tuple_lock &&
4349- !heap_acquire_tuplock (relation , tid , mode , wait_policy ,
4321+ if (!heap_acquire_tuplock (relation , tid , mode , wait_policy ,
43504322 & have_tuple_lock ))
43514323 {
43524324 /*
@@ -6544,13 +6516,10 @@ HeapTupleGetUpdateXid(HeapTupleHeader tuple)
65446516 * tuple lock of the given strength?
65456517 *
65466518 * The passed infomask pairs up with the given multixact in the tuple header.
6547- *
6548- * If current_is_member is not NULL, it is set to 'true' if the current
6549- * transaction is a member of the given multixact.
65506519 */
65516520static bool
65526521DoesMultiXactIdConflict (MultiXactId multi , uint16 infomask ,
6553- LockTupleMode lockmode , bool * current_is_member )
6522+ LockTupleMode lockmode )
65546523{
65556524 int nmembers ;
65566525 MultiXactMember * members ;
@@ -6571,26 +6540,17 @@ DoesMultiXactIdConflict(MultiXactId multi, uint16 infomask,
65716540 TransactionId memxid ;
65726541 LOCKMODE memlockmode ;
65736542
6574- if (result && (current_is_member == NULL || * current_is_member ))
6575- break ;
6576-
65776543 memlockmode = LOCKMODE_from_mxstatus (members [i ].status );
65786544
6579- /* ignore members from current xact (but track their presence) */
6580- memxid = members [i ].xid ;
6581- if (TransactionIdIsCurrentTransactionId (memxid ))
6582- {
6583- if (current_is_member != NULL )
6584- * current_is_member = true;
6585- continue ;
6586- }
6587- else if (result )
6588- continue ;
6589-
65906545 /* ignore members that don't conflict with the lock we want */
65916546 if (!DoLockModesConflict (memlockmode , wanted ))
65926547 continue ;
65936548
6549+ /* ignore members from current xact */
6550+ memxid = members [i ].xid ;
6551+ if (TransactionIdIsCurrentTransactionId (memxid ))
6552+ continue ;
6553+
65946554 if (ISUPDATE_from_mxstatus (members [i ].status ))
65956555 {
65966556 /* ignore aborted updaters */
@@ -6607,11 +6567,10 @@ DoesMultiXactIdConflict(MultiXactId multi, uint16 infomask,
66076567 /*
66086568 * Whatever remains are either live lockers that conflict with our
66096569 * wanted lock, and updaters that are not aborted. Those conflict
6610- * with what we want. Set up to return true, but keep going to
6611- * look for the current transaction among the multixact members,
6612- * if needed.
6570+ * with what we want, so return true.
66136571 */
66146572 result = true;
6573+ break ;
66156574 }
66166575 pfree (members );
66176576 }
0 commit comments