@@ -120,7 +120,7 @@ static void GetMultiXactIdHintBits(MultiXactId multi, uint16 *new_infomask,
120
120
static TransactionId MultiXactIdGetUpdateXid (TransactionId xmax ,
121
121
uint16 t_infomask );
122
122
static bool DoesMultiXactIdConflict (MultiXactId multi , uint16 infomask ,
123
- LockTupleMode lockmode , bool * current_is_member );
123
+ LockTupleMode lockmode );
124
124
static void MultiXactIdWait (MultiXactId multi , MultiXactStatus status , uint16 infomask ,
125
125
Relation rel , ItemPointer ctid , XLTW_Oper oper ,
126
126
int * remaining );
@@ -3161,20 +3161,15 @@ heap_delete(Relation relation, ItemPointer tid,
3161
3161
*/
3162
3162
if (infomask & HEAP_XMAX_IS_MULTI )
3163
3163
{
3164
- bool current_is_member = false;
3165
-
3164
+ /* wait for multixact */
3166
3165
if (DoesMultiXactIdConflict ((MultiXactId ) xwait , infomask ,
3167
- LockTupleExclusive , & current_is_member ))
3166
+ LockTupleExclusive ))
3168
3167
{
3169
3168
LockBuffer (buffer , BUFFER_LOCK_UNLOCK );
3170
3169
3171
- /*
3172
- * Acquire the lock, if necessary (but skip it when we're
3173
- * requesting a lock and already have one; avoids deadlock).
3174
- */
3175
- if (!current_is_member )
3176
- heap_acquire_tuplock (relation , & (tp .t_self ), LockTupleExclusive ,
3177
- LockWaitBlock , & have_tuple_lock );
3170
+ /* acquire tuple lock, if necessary */
3171
+ heap_acquire_tuplock (relation , & (tp .t_self ), LockTupleExclusive ,
3172
+ LockWaitBlock , & have_tuple_lock );
3178
3173
3179
3174
/* wait for multixact */
3180
3175
MultiXactIdWait ((MultiXactId ) xwait , MultiXactStatusUpdate , infomask ,
@@ -3773,20 +3768,15 @@ heap_update(Relation relation, ItemPointer otid, HeapTuple newtup,
3773
3768
{
3774
3769
TransactionId update_xact ;
3775
3770
int remain ;
3776
- bool current_is_member = false;
3777
3771
3778
3772
if (DoesMultiXactIdConflict ((MultiXactId ) xwait , infomask ,
3779
- * lockmode , & current_is_member ))
3773
+ * lockmode ))
3780
3774
{
3781
3775
LockBuffer (buffer , BUFFER_LOCK_UNLOCK );
3782
3776
3783
- /*
3784
- * Acquire the lock, if necessary (but skip it when we're
3785
- * requesting a lock and already have one; avoids deadlock).
3786
- */
3787
- if (!current_is_member )
3788
- heap_acquire_tuplock (relation , & (oldtup .t_self ), * lockmode ,
3789
- LockWaitBlock , & have_tuple_lock );
3777
+ /* acquire tuple lock, if necessary */
3778
+ heap_acquire_tuplock (relation , & (oldtup .t_self ), * lockmode ,
3779
+ LockWaitBlock , & have_tuple_lock );
3790
3780
3791
3781
/* wait for multixact */
3792
3782
MultiXactIdWait ((MultiXactId ) xwait , mxact_status , infomask ,
@@ -4756,7 +4746,6 @@ heap_lock_tuple(Relation relation, HeapTuple tuple,
4756
4746
uint16 infomask ;
4757
4747
uint16 infomask2 ;
4758
4748
bool require_sleep ;
4759
- bool skip_tuple_lock = false;
4760
4749
ItemPointerData t_ctid ;
4761
4750
4762
4751
/* must copy state data before unlocking buffer */
@@ -4810,21 +4799,6 @@ heap_lock_tuple(Relation relation, HeapTuple tuple,
4810
4799
result = HeapTupleMayBeUpdated ;
4811
4800
goto out_unlocked ;
4812
4801
}
4813
- else
4814
- {
4815
- /*
4816
- * Disable acquisition of the heavyweight tuple lock.
4817
- * Otherwise, when promoting a weaker lock, we might
4818
- * deadlock with another locker that has acquired the
4819
- * heavyweight tuple lock and is waiting for our
4820
- * transaction to finish.
4821
- *
4822
- * Note that in this case we still need to wait for
4823
- * the multixact if required, to avoid acquiring
4824
- * conflicting locks.
4825
- */
4826
- skip_tuple_lock = true;
4827
- }
4828
4802
}
4829
4803
4830
4804
if (members )
@@ -4979,7 +4953,7 @@ heap_lock_tuple(Relation relation, HeapTuple tuple,
4979
4953
if (infomask & HEAP_XMAX_IS_MULTI )
4980
4954
{
4981
4955
if (!DoesMultiXactIdConflict ((MultiXactId ) xwait , infomask ,
4982
- mode , NULL ))
4956
+ mode ))
4983
4957
{
4984
4958
/*
4985
4959
* No conflict, but if the xmax changed under us in the
@@ -5056,15 +5030,13 @@ heap_lock_tuple(Relation relation, HeapTuple tuple,
5056
5030
/*
5057
5031
* Acquire tuple lock to establish our priority for the tuple, or
5058
5032
* die trying. LockTuple will release us when we are next-in-line
5059
- * for the tuple. We must do this even if we are share-locking,
5060
- * but not if we already have a weaker lock on the tuple.
5033
+ * for the tuple. We must do this even if we are share-locking.
5061
5034
*
5062
5035
* If we are forced to "start over" below, we keep the tuple lock;
5063
5036
* this arranges that we stay at the head of the line while
5064
5037
* rechecking tuple state.
5065
5038
*/
5066
- if (!skip_tuple_lock &&
5067
- !heap_acquire_tuplock (relation , tid , mode , wait_policy ,
5039
+ if (!heap_acquire_tuplock (relation , tid , mode , wait_policy ,
5068
5040
& have_tuple_lock ))
5069
5041
{
5070
5042
/*
@@ -7242,13 +7214,10 @@ HeapTupleGetUpdateXid(HeapTupleHeader tuple)
7242
7214
* tuple lock of the given strength?
7243
7215
*
7244
7216
* The passed infomask pairs up with the given multixact in the tuple header.
7245
- *
7246
- * If current_is_member is not NULL, it is set to 'true' if the current
7247
- * transaction is a member of the given multixact.
7248
7217
*/
7249
7218
static bool
7250
7219
DoesMultiXactIdConflict (MultiXactId multi , uint16 infomask ,
7251
- LockTupleMode lockmode , bool * current_is_member )
7220
+ LockTupleMode lockmode )
7252
7221
{
7253
7222
int nmembers ;
7254
7223
MultiXactMember * members ;
@@ -7269,26 +7238,17 @@ DoesMultiXactIdConflict(MultiXactId multi, uint16 infomask,
7269
7238
TransactionId memxid ;
7270
7239
LOCKMODE memlockmode ;
7271
7240
7272
- if (result && (current_is_member == NULL || * current_is_member ))
7273
- break ;
7274
-
7275
7241
memlockmode = LOCKMODE_from_mxstatus (members [i ].status );
7276
7242
7277
- /* ignore members from current xact (but track their presence) */
7278
- memxid = members [i ].xid ;
7279
- if (TransactionIdIsCurrentTransactionId (memxid ))
7280
- {
7281
- if (current_is_member != NULL )
7282
- * current_is_member = true;
7283
- continue ;
7284
- }
7285
- else if (result )
7286
- continue ;
7287
-
7288
7243
/* ignore members that don't conflict with the lock we want */
7289
7244
if (!DoLockModesConflict (memlockmode , wanted ))
7290
7245
continue ;
7291
7246
7247
+ /* ignore members from current xact */
7248
+ memxid = members [i ].xid ;
7249
+ if (TransactionIdIsCurrentTransactionId (memxid ))
7250
+ continue ;
7251
+
7292
7252
if (ISUPDATE_from_mxstatus (members [i ].status ))
7293
7253
{
7294
7254
/* ignore aborted updaters */
@@ -7305,11 +7265,10 @@ DoesMultiXactIdConflict(MultiXactId multi, uint16 infomask,
7305
7265
/*
7306
7266
* Whatever remains are either live lockers that conflict with our
7307
7267
* wanted lock, and updaters that are not aborted. Those conflict
7308
- * with what we want. Set up to return true, but keep going to
7309
- * look for the current transaction among the multixact members,
7310
- * if needed.
7268
+ * with what we want, so return true.
7311
7269
*/
7312
7270
result = true;
7271
+ break ;
7313
7272
}
7314
7273
pfree (members );
7315
7274
}
0 commit comments