summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPavan Deolasee2016-01-05 07:20:32 +0000
committerPavan Deolasee2016-10-18 09:24:58 +0000
commit4721cd702779d6a4971e755d315cee16b58e7f06 (patch)
tree465e142c014a95d05b2373386e76e243de5afc66
parent45756267fd772d26f4fca908dfd65d2ba071ab88 (diff)
Ensure commit ordering at the GTM when a transaction's update/delete operation
is based on some other transaction's commit We had handled one part of this problem by recording transactions on which we wait before proceeding with update/delete. But there is another case where an updating transaction T1 may commit on the datanode, but before coordinator can commit the transaction on the GTM, another transaction T2 updates the record (seeing that the updating transaction is already committed) and also commits on the GTM. Now if a third transaction T3 takes a snapshot, it will see T1 as running and T2 as committed. Such a snapshot can then see both old and new versions of the updated tuple. So we must enforce commit ordering T1->T2 on the GTM since T2 based its actions on T1 being committed
-rw-r--r--src/backend/utils/time/tqual.c11
1 files changed, 11 insertions, 0 deletions
diff --git a/src/backend/utils/time/tqual.c b/src/backend/utils/time/tqual.c
index de7b3fc80c..7c94f537b1 100644
--- a/src/backend/utils/time/tqual.c
+++ b/src/backend/utils/time/tqual.c
@@ -595,6 +595,17 @@ HeapTupleSatisfiesUpdate(HeapTuple htup, CommandId curcid,
/* by here, the inserting transaction has committed */
+ /*
+ * If the committed xmin is a relatively recent transaction, we want to
+ * make sure that the GTM sees its commit before it sees our
+ * commit since our execution assumes that xmin is committed and hence that
+ * ordering must be followed. There is a small race condition which may
+ * violate this ordering and hence we record such dependencies and ensure
+ * ordering at the commit time
+ */
+ if (TransactionIdPrecedesOrEquals(RecentXmin, HeapTupleHeaderGetRawXmin(tuple)))
+ TransactionRecordXidWait(HeapTupleHeaderGetRawXmin(tuple));
+
if (tuple->t_infomask & HEAP_XMAX_INVALID) /* xid invalid or aborted */
return HeapTupleMayBeUpdated;