Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commitb78647a

Browse files
committed
Restrict infomask bits to set on multixacts
We must only set the bit(s) for the strongest lock held in the tuple;otherwise, a multixact containing members with exclusive lock andkey-share lock will behave as though only a share lock is held.This bug was introduced in commit0ac5ad5, somewhere alongdevelopment, when we allowed a singleton FOR SHARE lock to beimplemented without a MultiXact by using a multi-bit pattern.I overlooked that GetMultiXactIdHintBits() needed to be tweaked as well.Previously, we could have the bits for FOR KEY SHARE and FOR UPDATEsimultaneously set and it wouldn't cause a problem.Per report from digoal@126.com
1 parent77a3082 commitb78647a

File tree

1 file changed

+37
-9
lines changed

1 file changed

+37
-9
lines changed

‎src/backend/access/heap/heapam.c

Lines changed: 37 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -3269,7 +3269,13 @@ heap_update(Relation relation, ItemPointer otid, HeapTuple newtup,
32693269
&xmax_old_tuple,&infomask_old_tuple,
32703270
&infomask2_old_tuple);
32713271

3272-
/* And also prepare an Xmax value for the new copy of the tuple */
3272+
/*
3273+
* And also prepare an Xmax value for the new copy of the tuple. If there
3274+
* was no xmax previously, or there was one but all lockers are now gone,
3275+
* then use InvalidXid; otherwise, get the xmax from the old tuple. (In
3276+
* rare cases that might also be InvalidXid and yet not have the
3277+
* HEAP_XMAX_INVALID bit set; that's fine.)
3278+
*/
32733279
if ((oldtup.t_data->t_infomask&HEAP_XMAX_INVALID)||
32743280
(checked_lockers&& !locker_remains))
32753281
xmax_new_tuple=InvalidTransactionId;
@@ -3283,6 +3289,12 @@ heap_update(Relation relation, ItemPointer otid, HeapTuple newtup,
32833289
}
32843290
else
32853291
{
3292+
/*
3293+
* If we found a valid Xmax for the new tuple, then the infomask bits
3294+
* to use on the new tuple depend on what was there on the old one.
3295+
* Note that since we're doing an update, the only possibility is that
3296+
* the lockers had FOR KEY SHARE lock.
3297+
*/
32863298
if (oldtup.t_data->t_infomask&HEAP_XMAX_IS_MULTI)
32873299
{
32883300
GetMultiXactIdHintBits(xmax_new_tuple,&infomask_new_tuple,
@@ -5161,6 +5173,7 @@ GetMultiXactIdHintBits(MultiXactId multi, uint16 *new_infomask,
51615173
uint16bits=HEAP_XMAX_IS_MULTI;
51625174
uint16bits2=0;
51635175
boolhas_update= false;
5176+
LockTupleModestrongest=LockTupleKeyShare;
51645177

51655178
/*
51665179
* We only use this in multis we just created, so they cannot be values
@@ -5170,32 +5183,47 @@ GetMultiXactIdHintBits(MultiXactId multi, uint16 *new_infomask,
51705183

51715184
for (i=0;i<nmembers;i++)
51725185
{
5186+
LockTupleModemode;
5187+
5188+
/*
5189+
* Remember the strongest lock mode held by any member of the
5190+
* multixact.
5191+
*/
5192+
mode=TUPLOCK_from_mxstatus(members[i].status);
5193+
if (mode>strongest)
5194+
strongest=mode;
5195+
5196+
/* See what other bits we need */
51735197
switch (members[i].status)
51745198
{
51755199
caseMultiXactStatusForKeyShare:
5176-
bits |=HEAP_XMAX_KEYSHR_LOCK;
5177-
break;
51785200
caseMultiXactStatusForShare:
5179-
bits |=HEAP_XMAX_SHR_LOCK;
5180-
break;
51815201
caseMultiXactStatusForNoKeyUpdate:
5182-
bits |=HEAP_XMAX_EXCL_LOCK;
51835202
break;
5203+
51845204
caseMultiXactStatusForUpdate:
5185-
bits |=HEAP_XMAX_EXCL_LOCK;
51865205
bits2 |=HEAP_KEYS_UPDATED;
51875206
break;
5207+
51885208
caseMultiXactStatusNoKeyUpdate:
5189-
bits |=HEAP_XMAX_EXCL_LOCK;
51905209
has_update= true;
51915210
break;
5211+
51925212
caseMultiXactStatusUpdate:
5193-
bits |=HEAP_XMAX_EXCL_LOCK;
51945213
bits2 |=HEAP_KEYS_UPDATED;
51955214
has_update= true;
51965215
break;
51975216
}
51985217
}
5218+
5219+
if (strongest==LockTupleExclusive||
5220+
strongest==LockTupleNoKeyExclusive)
5221+
bits |=HEAP_XMAX_EXCL_LOCK;
5222+
elseif (strongest==LockTupleShare)
5223+
bits |=HEAP_XMAX_SHR_LOCK;
5224+
elseif (strongest==LockTupleKeyShare)
5225+
bits |=HEAP_XMAX_KEYSHR_LOCK;
5226+
51995227
if (!has_update)
52005228
bits |=HEAP_XMAX_LOCK_ONLY;
52015229

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp