diff options
author | Pavan Deolasee | 2016-01-05 07:20:32 +0000 |
---|---|---|
committer | Pavan Deolasee | 2016-10-18 09:24:58 +0000 |
commit | 4721cd702779d6a4971e755d315cee16b58e7f06 (patch) | |
tree | 465e142c014a95d05b2373386e76e243de5afc66 | |
parent | 45756267fd772d26f4fca908dfd65d2ba071ab88 (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.c | 11 |
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; |