From: Pavan Deolasee Date: Tue, 5 Jan 2016 07:20:32 +0000 (+0530) Subject: Ensure commit ordering at the GTM when a transaction's update/delete operation X-Git-Tag: XL9_5_R1BETA1~117 X-Git-Url: http://git.postgresql.org/gitweb/static/gitweb.js?a=commitdiff_plain;h=b43bf01e6e5054d164dcd7c8cf52027653172613;p=postgres-xl.git 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 --- 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;