Skip to content

Commit f66885b

Browse files
committed
Allow special SKIP LOCKED condition in Assert()
Under concurrency, it is possible for two sessions to be merrily locking and releasing a tuple and marking it again as HEAP_XMAX_INVALID all the while a third session attempts to lock it, miserably fails at it, and then contemplates life, the universe and everything only to eventually fail an assertion that said bit is not set. Before SKIP LOCKED that was indeed a reasonable expectation, but alas! commit df630b0 falsified it. This bug is as old as time itself, and even older, if you think time begins with the oldest supported branch. Therefore, backpatch to all supported branches. Author: Simon Riggs <simon.riggs@enterprisedb.com> Discussion: https://postgr.es/m/CANbhV-FeEwMnN8yuMyss7if1ZKjOKfjcgqB26n8pqu1e=q0ebg@mail.gmail.com
1 parent 56a3e84 commit f66885b

File tree

1 file changed

+9
-1
lines changed

1 file changed

+9
-1
lines changed

src/backend/access/heap/heapam.c

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4751,7 +4751,15 @@ heap_lock_tuple(Relation relation, HeapTuple tuple,
47514751
{
47524752
Assert(result == TM_SelfModified || result == TM_Updated ||
47534753
result == TM_Deleted || result == TM_WouldBlock);
4754-
Assert(!(tuple->t_data->t_infomask & HEAP_XMAX_INVALID));
4754+
4755+
/*
4756+
* When locking a tuple under LockWaitSkip semantics and we fail with
4757+
* TM_WouldBlock above, it's possible for concurrent transactions to
4758+
* release the lock and set HEAP_XMAX_INVALID in the meantime. So
4759+
* this assert is slightly different from the equivalent one in
4760+
* heap_delete and heap_update.
4761+
*/
4762+
Assert(TM_WouldBlock || !(tuple->t_data->t_infomask & HEAP_XMAX_INVALID));
47554763
Assert(result != TM_Updated ||
47564764
!ItemPointerEquals(&tuple->t_self, &tuple->t_data->t_ctid));
47574765
tmfd->ctid = tuple->t_data->t_ctid;

0 commit comments

Comments
 (0)