aboutsummaryrefslogtreecommitdiff
path: root/src/backend/utils/time/tqual.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/backend/utils/time/tqual.c')
-rw-r--r--src/backend/utils/time/tqual.c36
1 files changed, 34 insertions, 2 deletions
diff --git a/src/backend/utils/time/tqual.c b/src/backend/utils/time/tqual.c
index f787f2cbdc9..44b4ddcb02f 100644
--- a/src/backend/utils/time/tqual.c
+++ b/src/backend/utils/time/tqual.c
@@ -686,8 +686,36 @@ HeapTupleSatisfiesUpdate(HeapTupleHeader tuple, CommandId curcid,
if (tuple->t_infomask & HEAP_XMAX_INVALID) /* xid invalid */
return HeapTupleMayBeUpdated;
- if (HEAP_XMAX_IS_LOCKED_ONLY(tuple->t_infomask)) /* not deleter */
- return HeapTupleMayBeUpdated;
+ if (HEAP_XMAX_IS_LOCKED_ONLY(tuple->t_infomask))
+ {
+ TransactionId xmax;
+
+ xmax = HeapTupleHeaderGetRawXmax(tuple);
+
+ /*
+ * Careful here: even though this tuple was created by our own
+ * transaction, it might be locked by other transactions, if
+ * the original version was key-share locked when we updated
+ * it.
+ */
+
+ if (tuple->t_infomask & HEAP_XMAX_IS_MULTI)
+ {
+ if (MultiXactHasRunningRemoteMembers(xmax))
+ return HeapTupleBeingUpdated;
+ else
+ return HeapTupleMayBeUpdated;
+ }
+
+ /* if locker is gone, all's well */
+ if (!TransactionIdIsInProgress(xmax))
+ return HeapTupleMayBeUpdated;
+
+ if (!TransactionIdIsCurrentTransactionId(xmax))
+ return HeapTupleBeingUpdated;
+ else
+ return HeapTupleMayBeUpdated;
+ }
if (tuple->t_infomask & HEAP_XMAX_IS_MULTI)
{
@@ -700,7 +728,11 @@ HeapTupleSatisfiesUpdate(HeapTupleHeader tuple, CommandId curcid,
/* updating subtransaction must have aborted */
if (!TransactionIdIsCurrentTransactionId(xmax))
+ {
+ if (MultiXactHasRunningRemoteMembers(HeapTupleHeaderGetRawXmax(tuple)))
+ return HeapTupleBeingUpdated;
return HeapTupleMayBeUpdated;
+ }
else
{
if (HeapTupleHeaderGetCmax(tuple) >= curcid)