From: Kevin Grittner Date: Sun, 28 Nov 2010 20:36:53 +0000 (-0600) Subject: Eliminate the last six falst positives from the receipting test. X-Git-Url: http://git.postgresql.org/gitweb/static/gitweb.js?a=commitdiff_plain;h=9425d7fa551a1433bdbec1de5cfb1bfa9f43da22;p=users%2Fkgrittn%2Fpostgres.git Eliminate the last six falst positives from the receipting test. This was done by using the lastCommitBeforeSnapshot for a differnt purpose in committed transactions which had a conflict out. This is OK since it is only useful for its named purpose after a commit if it is a read-only transaction, which can't have a read-write conflict out, so the usages are mutually exclusive. It's pretty ugly, though, so will look for advice on how to best make it less confusing to someone reading the code. --- diff --git a/src/backend/storage/lmgr/predicate.c b/src/backend/storage/lmgr/predicate.c index 621f776c24..8936e91685 100644 --- a/src/backend/storage/lmgr/predicate.c +++ b/src/backend/storage/lmgr/predicate.c @@ -1865,9 +1865,9 @@ ReleasePredicateLocks(const bool isCommit) } /* - * Release all outConflicts from committed transactions, but set - * SXACT_FLAG_CONFLICT_OUT if any exist. - * If we're rolling back clear them all. + * Release all outConflicts from committed transactions. If we're + * rolling back clear them all. Set SXACT_FLAG_CONFLICT_OUT if any + * point to previously committed transactions. */ conflict = (RWConflict) SHMQueueNext((SHM_QUEUE *) &MySerializableXact->outConflicts, @@ -1880,8 +1880,15 @@ ReleasePredicateLocks(const bool isCommit) &conflict->outLink, offsetof(RWConflictData, outLink)); - if (isCommit && SxactIsCommitted(conflict->sxactIn)) + if (isCommit + && !SxactIsReadOnly(conflict->sxactIn) + && SxactIsCommitted(conflict->sxactIn)) + { + if ((MySerializableXact->flags & SXACT_FLAG_CONFLICT_OUT) == 0 + || conflict->sxactIn->commitSeqNo < MySerializableXact->lastCommitBeforeSnapshot) + MySerializableXact->lastCommitBeforeSnapshot = conflict->sxactIn->commitSeqNo; MySerializableXact->flags |= SXACT_FLAG_CONFLICT_OUT; + } if (!isCommit || SxactIsCommitted(conflict->sxactIn)) ReleaseRWConflict(conflict); @@ -2235,7 +2242,8 @@ CheckForSerializableConflictOut(const bool valid, const Relation relation, */ if (SxactIsReadOnly(MySerializableXact) && SxactIsCommitted(sxact) - && !SxactHasConflictOut(sxact)) + && (!SxactHasConflictOut(sxact) + || MySerializableXact->lastCommitBeforeSnapshot < sxact->lastCommitBeforeSnapshot)) { /* Read-only transaction will appear to run first. No conflict. */ LWLockRelease(SerializableXactHashLock);