@@ -115,7 +115,7 @@ static void GetMultiXactIdHintBits(MultiXactId multi, uint16 *new_infomask,
115115static TransactionId MultiXactIdGetUpdateXid (TransactionId xmax ,
116116uint16 t_infomask );
117117static bool DoesMultiXactIdConflict (MultiXactId multi ,uint16 infomask ,
118- LockTupleMode lockmode , bool * current_is_member );
118+ LockTupleMode lockmode );
119119static void MultiXactIdWait (MultiXactId multi ,MultiXactStatus status ,uint16 infomask ,
120120Relation rel ,ItemPointer ctid ,XLTW_Oper oper ,
121121int * remaining );
@@ -3112,20 +3112,15 @@ heap_delete(Relation relation, ItemPointer tid,
31123112 */
31133113if (infomask & HEAP_XMAX_IS_MULTI )
31143114{
3115- bool current_is_member = false;
3116-
3115+ /* wait for multixact */
31173116if (DoesMultiXactIdConflict ((MultiXactId )xwait ,infomask ,
3118- LockTupleExclusive , & current_is_member ))
3117+ LockTupleExclusive ))
31193118{
31203119LockBuffer (buffer ,BUFFER_LOCK_UNLOCK );
31213120
3122- /*
3123- * Acquire the lock, if necessary (but skip it when we're
3124- * requesting a lock and already have one; avoids deadlock).
3125- */
3126- if (!current_is_member )
3127- heap_acquire_tuplock (relation ,& (tp .t_self ),LockTupleExclusive ,
3128- LockWaitBlock ,& have_tuple_lock );
3121+ /* acquire tuple lock, if necessary */
3122+ heap_acquire_tuplock (relation ,& (tp .t_self ),LockTupleExclusive ,
3123+ LockWaitBlock ,& have_tuple_lock );
31293124
31303125/* wait for multixact */
31313126MultiXactIdWait ((MultiXactId )xwait ,MultiXactStatusUpdate ,infomask ,
@@ -3715,20 +3710,15 @@ heap_update(Relation relation, ItemPointer otid, HeapTuple newtup,
37153710{
37163711TransactionId update_xact ;
37173712int remain ;
3718- bool current_is_member = false;
37193713
37203714if (DoesMultiXactIdConflict ((MultiXactId )xwait ,infomask ,
3721- * lockmode , & current_is_member ))
3715+ * lockmode ))
37223716{
37233717LockBuffer (buffer ,BUFFER_LOCK_UNLOCK );
37243718
3725- /*
3726- * Acquire the lock, if necessary (but skip it when we're
3727- * requesting a lock and already have one; avoids deadlock).
3728- */
3729- if (!current_is_member )
3730- heap_acquire_tuplock (relation ,& (oldtup .t_self ),* lockmode ,
3731- LockWaitBlock ,& have_tuple_lock );
3719+ /* acquire tuple lock, if necessary */
3720+ heap_acquire_tuplock (relation ,& (oldtup .t_self ),* lockmode ,
3721+ LockWaitBlock ,& have_tuple_lock );
37323722
37333723/* wait for multixact */
37343724MultiXactIdWait ((MultiXactId )xwait ,mxact_status ,infomask ,
@@ -4610,7 +4600,6 @@ heap_lock_tuple(Relation relation, HeapTuple tuple,
46104600uint16 infomask ;
46114601uint16 infomask2 ;
46124602bool require_sleep ;
4613- bool skip_tuple_lock = false;
46144603ItemPointerData t_ctid ;
46154604
46164605/* must copy state data before unlocking buffer */
@@ -4664,21 +4653,6 @@ heap_lock_tuple(Relation relation, HeapTuple tuple,
46644653result = HeapTupleMayBeUpdated ;
46654654gotoout_unlocked ;
46664655}
4667- else
4668- {
4669- /*
4670- * Disable acquisition of the heavyweight tuple lock.
4671- * Otherwise, when promoting a weaker lock, we might
4672- * deadlock with another locker that has acquired the
4673- * heavyweight tuple lock and is waiting for our
4674- * transaction to finish.
4675- *
4676- * Note that in this case we still need to wait for
4677- * the multixact if required, to avoid acquiring
4678- * conflicting locks.
4679- */
4680- skip_tuple_lock = true;
4681- }
46824656}
46834657
46844658if (members )
@@ -4833,7 +4807,7 @@ heap_lock_tuple(Relation relation, HeapTuple tuple,
48334807if (infomask & HEAP_XMAX_IS_MULTI )
48344808{
48354809if (!DoesMultiXactIdConflict ((MultiXactId )xwait ,infomask ,
4836- mode , NULL ))
4810+ mode ))
48374811{
48384812/*
48394813 * No conflict, but if the xmax changed under us in the
@@ -4910,15 +4884,13 @@ heap_lock_tuple(Relation relation, HeapTuple tuple,
49104884/*
49114885 * Acquire tuple lock to establish our priority for the tuple, or
49124886 * die trying. LockTuple will release us when we are next-in-line
4913- * for the tuple. We must do this even if we are share-locking,
4914- * but not if we already have a weaker lock on the tuple.
4887+ * for the tuple. We must do this even if we are share-locking.
49154888 *
49164889 * If we are forced to "start over" below, we keep the tuple lock;
49174890 * this arranges that we stay at the head of the line while
49184891 * rechecking tuple state.
49194892 */
4920- if (!skip_tuple_lock &&
4921- !heap_acquire_tuplock (relation ,tid ,mode ,wait_policy ,
4893+ if (!heap_acquire_tuplock (relation ,tid ,mode ,wait_policy ,
49224894& have_tuple_lock ))
49234895{
49244896/*
@@ -7090,13 +7062,10 @@ HeapTupleGetUpdateXid(HeapTupleHeader tuple)
70907062 * tuple lock of the given strength?
70917063 *
70927064 * The passed infomask pairs up with the given multixact in the tuple header.
7093- *
7094- * If current_is_member is not NULL, it is set to 'true' if the current
7095- * transaction is a member of the given multixact.
70967065 */
70977066static bool
70987067DoesMultiXactIdConflict (MultiXactId multi ,uint16 infomask ,
7099- LockTupleMode lockmode , bool * current_is_member )
7068+ LockTupleMode lockmode )
71007069{
71017070int nmembers ;
71027071MultiXactMember * members ;
@@ -7117,26 +7086,17 @@ DoesMultiXactIdConflict(MultiXactId multi, uint16 infomask,
71177086TransactionId memxid ;
71187087LOCKMODE memlockmode ;
71197088
7120- if (result && (current_is_member == NULL || * current_is_member ))
7121- break ;
7122-
71237089memlockmode = LOCKMODE_from_mxstatus (members [i ].status );
71247090
7125- /* ignore members from current xact (but track their presence) */
7126- memxid = members [i ].xid ;
7127- if (TransactionIdIsCurrentTransactionId (memxid ))
7128- {
7129- if (current_is_member != NULL )
7130- * current_is_member = true;
7131- continue ;
7132- }
7133- else if (result )
7134- continue ;
7135-
71367091/* ignore members that don't conflict with the lock we want */
71377092if (!DoLockModesConflict (memlockmode ,wanted ))
71387093continue ;
71397094
7095+ /* ignore members from current xact */
7096+ memxid = members [i ].xid ;
7097+ if (TransactionIdIsCurrentTransactionId (memxid ))
7098+ continue ;
7099+
71407100if (ISUPDATE_from_mxstatus (members [i ].status ))
71417101{
71427102/* ignore aborted updaters */
@@ -7153,11 +7113,10 @@ DoesMultiXactIdConflict(MultiXactId multi, uint16 infomask,
71537113/*
71547114 * Whatever remains are either live lockers that conflict with our
71557115 * wanted lock, and updaters that are not aborted. Those conflict
7156- * with what we want. Set up to return true, but keep going to
7157- * look for the current transaction among the multixact members,
7158- * if needed.
7116+ * with what we want, so return true.
71597117 */
71607118result = true;
7119+ break ;
71617120}
71627121pfree (members );
71637122}