From 138b11e1a787f0d2b3fc913eec3c8d28527ee76c Mon Sep 17 00:00:00 2001 From: Heikki Linnakangas Date: Thu, 11 Dec 2025 18:03:10 +0200 Subject: [PATCH v1 2/2] Fix the bug with priorXmax --- src/backend/access/heap/heapam.c | 28 ++++++++++++++++++++++------ 1 file changed, 22 insertions(+), 6 deletions(-) diff --git a/src/backend/access/heap/heapam.c b/src/backend/access/heap/heapam.c index a69df8bd431..5fb81af8d4f 100644 --- a/src/backend/access/heap/heapam.c +++ b/src/backend/access/heap/heapam.c @@ -86,6 +86,7 @@ static void compute_new_xmax_infomask(TransactionId xmax, uint16 old_infomask, TransactionId *result_xmax, uint16 *result_infomask, uint16 *result_infomask2); static TM_Result heap_lock_updated_tuple(Relation rel, HeapTuple tuple, + TransactionId priorXmax, const ItemPointerData *ctid, TransactionId xid, LockTupleMode mode); static void GetMultiXactIdHintBits(MultiXactId multi, uint16 *new_infomask, @@ -4818,9 +4819,16 @@ l3: */ if (follow_updates && updated) { + TransactionId updateXid; TM_Result res; - res = heap_lock_updated_tuple(relation, tuple, &t_ctid, + if (infomask & HEAP_XMAX_IS_MULTI) + updateXid = MultiXactIdGetUpdateXid(xwait, infomask); + else + updateXid = xwait; + + res = heap_lock_updated_tuple(relation, tuple, updateXid, + &t_ctid, GetCurrentTransactionId(), mode); if (res != TM_Ok) @@ -5065,9 +5073,16 @@ l3: /* if there are updates, follow the update chain */ if (follow_updates && !HEAP_XMAX_IS_LOCKED_ONLY(infomask)) { + TransactionId updateXid; TM_Result res; - res = heap_lock_updated_tuple(relation, tuple, &t_ctid, + if (infomask & HEAP_XMAX_IS_MULTI) + updateXid = MultiXactIdGetUpdateXid(xwait, infomask); + else + updateXid = xwait; + + res = heap_lock_updated_tuple(relation, tuple, updateXid, + &t_ctid, GetCurrentTransactionId(), mode); if (res != TM_Ok) @@ -5721,7 +5736,8 @@ test_lockmode_for_conflict(MultiXactStatus status, TransactionId xid, * version as well. */ static TM_Result -heap_lock_updated_tuple_rec(Relation rel, const ItemPointerData *tid, TransactionId xid, +heap_lock_updated_tuple_rec(Relation rel, TransactionId priorXmax, + const ItemPointerData *tid, TransactionId xid, LockTupleMode mode) { TM_Result result; @@ -5734,7 +5750,6 @@ heap_lock_updated_tuple_rec(Relation rel, const ItemPointerData *tid, Transactio old_infomask2; TransactionId xmax, new_xmax; - TransactionId priorXmax = InvalidTransactionId; bool cleared_all_frozen = false; bool pinned_desired_page; Buffer vmbuffer = InvalidBuffer; @@ -6066,7 +6081,8 @@ out_unlocked: * levels, because that would lead to a serializability failure. */ static TM_Result -heap_lock_updated_tuple(Relation rel, HeapTuple tuple, const ItemPointerData *ctid, +heap_lock_updated_tuple(Relation rel, HeapTuple tuple, TransactionId priorXmax, + const ItemPointerData *ctid, TransactionId xid, LockTupleMode mode) { INJECTION_POINT("heap_lock_updated_tuple", NULL); @@ -6089,7 +6105,7 @@ heap_lock_updated_tuple(Relation rel, HeapTuple tuple, const ItemPointerData *ct */ MultiXactIdSetOldestMember(); - return heap_lock_updated_tuple_rec(rel, ctid, xid, mode); + return heap_lock_updated_tuple_rec(rel, priorXmax, ctid, xid, mode); } /* nothing to lock */ -- 2.47.3