aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/backend/access/heap/heapam.c14
1 files changed, 14 insertions, 0 deletions
diff --git a/src/backend/access/heap/heapam.c b/src/backend/access/heap/heapam.c
index f55e612590f..39e5d2d26a1 100644
--- a/src/backend/access/heap/heapam.c
+++ b/src/backend/access/heap/heapam.c
@@ -4814,6 +4814,7 @@ heap_lock_updated_tuple_rec(Relation rel, ItemPointer tid, TransactionId xid,
old_infomask;
TransactionId xmax,
new_xmax;
+ TransactionId priorXmax = InvalidTransactionId;
ItemPointerCopy(tid, &tupid);
@@ -4839,6 +4840,18 @@ l4:
CHECK_FOR_INTERRUPTS();
LockBuffer(buf, BUFFER_LOCK_EXCLUSIVE);
+ /*
+ * Check the tuple XMIN against prior XMAX, if any. If we reached
+ * the end of the chain, we're done, so return success.
+ */
+ if (TransactionIdIsValid(priorXmax) &&
+ !TransactionIdEquals(HeapTupleHeaderGetXmin(mytup.t_data),
+ priorXmax))
+ {
+ UnlockReleaseBuffer(buf);
+ return HeapTupleMayBeUpdated;
+ }
+
old_infomask = mytup.t_data->t_infomask;
xmax = HeapTupleHeaderGetRawXmax(mytup.t_data);
@@ -4939,6 +4952,7 @@ l4:
}
/* tail recursion */
+ priorXmax = HeapTupleHeaderGetUpdateXid(mytup.t_data);
ItemPointerCopy(&(mytup.t_data->t_ctid), &tupid);
UnlockReleaseBuffer(buf);
}