From 4046ddb8f5cf452e0aa404f0543ce2e9a96a9423 Mon Sep 17 00:00:00 2001 From: Kevin Grittner Date: Sat, 27 Nov 2010 14:06:46 -0600 Subject: [PATCH] Fix reversal of inSxact and outSxact from conflicts. Comment out a part of the READ ONLY special case which isn't working correctly, pending further investigation. This brings us to no false negatives, and a better false positive rate than we have had before. Not much left to do before jumping into the graceful degradation fixes. Also a minor tweak to the dtest script, to remove redundant READ ONLY specification. --- src/backend/storage/lmgr/predicate.c | 44 +++++++++++++++------------- src/test/regress/pg_dtester.py.in | 2 +- 2 files changed, 24 insertions(+), 22 deletions(-) diff --git a/src/backend/storage/lmgr/predicate.c b/src/backend/storage/lmgr/predicate.c index 79d0216a46..e088b9dd07 100644 --- a/src/backend/storage/lmgr/predicate.c +++ b/src/backend/storage/lmgr/predicate.c @@ -1797,7 +1797,7 @@ SetNewSerializableGlobalXmin(void) for (sxact = FirstPredTran(); sxact != NULL; sxact = NextPredTran(sxact)) { - if (!SxactIsOnFinishedList(sxact)) + if (!SxactIsRolledBack(sxact) && !SxactIsOnFinishedList(sxact)) { if (!TransactionIdIsValid(SerializableGlobalXmin) || TransactionIdPrecedes(sxact->xmin, SerializableGlobalXmin)) @@ -1888,7 +1888,7 @@ ReleasePredicateLocks(const bool isCommit) &conflict->outLink, offsetof(RWConflictData, outLink)); - if (!isCommit || SxactIsCommitted(conflict->sxactOut)) + if (!isCommit || SxactIsCommitted(conflict->sxactIn)) ReleaseRWConflict(conflict); conflict = nextConflict; @@ -1909,7 +1909,7 @@ ReleasePredicateLocks(const bool isCommit) &conflict->inLink, offsetof(RWConflictData, inLink)); - if (!isCommit || SxactIsCommitted(conflict->sxactIn)) + if (!isCommit || SxactIsCommitted(conflict->sxactOut)) ReleaseRWConflict(conflict); conflict = nextConflict; @@ -2238,7 +2238,7 @@ CheckForSerializableConflictOut(const bool valid, const Relation relation, * committed, and it doesn't have a rw-conflict to a transaction which * committed before it, no conflict. */ - if (SxactIsReadOnly((SERIALIZABLEXACT *) MySerializableXact) + if (SxactIsReadOnly(MySerializableXact) && SxactIsCommitted(sxact) && !SxactHasConflictOut(sxact)) { @@ -2593,11 +2593,11 @@ OnConflict_CheckForSerializationFailure(const SERIALIZABLEXACT *reader, offsetof(RWConflictData, inLink)); while (conflict) { - if (!SxactIsRolledBack(conflict->sxactIn) - && (!SxactIsCommitted(conflict->sxactIn) - || conflict->sxactIn->commitSeqNo >= writer->commitSeqNo) - && (!SxactIsReadOnly(conflict->sxactIn) - || conflict->sxactIn->lastCommitBeforeSnapshot >= writer->commitSeqNo)) + if (!SxactIsRolledBack(conflict->sxactOut) + && (!SxactIsCommitted(conflict->sxactOut) + || conflict->sxactOut->commitSeqNo >= writer->commitSeqNo) + && (!SxactIsReadOnly(conflict->sxactOut) + || conflict->sxactOut->lastCommitBeforeSnapshot >= writer->commitSeqNo)) { failure = true; break; @@ -2618,7 +2618,7 @@ OnConflict_CheckForSerializationFailure(const SERIALIZABLEXACT *reader, * the reader must not have been concurrent with the out-conflict * transaction.) */ - if (!failure && !SxactIsCommitted(writer) && !SxactIsCommitted(reader)) + if (!failure && !SxactIsCommitted(writer)) { conflict = (RWConflict) SHMQueueNext(&writer->outConflicts, @@ -2626,9 +2626,11 @@ OnConflict_CheckForSerializationFailure(const SERIALIZABLEXACT *reader, offsetof(RWConflictData, outLink)); while (conflict) { - if (SxactIsCommitted(conflict->sxactOut) - && (!SxactIsReadOnly(reader) - || conflict->sxactOut->commitSeqNo <= reader->lastCommitBeforeSnapshot)) + if (reader == conflict->sxactIn + || (SxactIsCommitted(conflict->sxactIn) + && !SxactIsCommitted(reader) + /*&& (!SxactIsReadOnly(reader) + || conflict->sxactIn->commitSeqNo <= reader->lastCommitBeforeSnapshot)*/)) { failure = true; break; @@ -2684,26 +2686,26 @@ PreCommit_CheckForSerializationFailure(void) offsetof(RWConflictData, inLink)); while (nearConflict) { - if (!SxactIsCommitted(nearConflict->sxactIn) - && !SxactIsRolledBack(nearConflict->sxactIn)) + if (!SxactIsCommitted(nearConflict->sxactOut) + && !SxactIsRolledBack(nearConflict->sxactOut)) { RWConflict farConflict; farConflict = (RWConflict) - SHMQueueNext(&nearConflict->sxactIn->inConflicts, - &nearConflict->sxactIn->inConflicts, + SHMQueueNext(&nearConflict->sxactOut->inConflicts, + &nearConflict->sxactOut->inConflicts, offsetof(RWConflictData, inLink)); while (farConflict) { - if (!SxactIsCommitted(farConflict->sxactIn) - && !SxactIsReadOnly(farConflict->sxactIn) - && !SxactIsRolledBack(nearConflict->sxactIn)) + if (!SxactIsCommitted(farConflict->sxactOut) + && !SxactIsReadOnly(farConflict->sxactOut) + && !SxactIsRolledBack(farConflict->sxactOut)) { failure = true; break; } farConflict = (RWConflict) - SHMQueueNext(&nearConflict->sxactIn->inConflicts, + SHMQueueNext(&nearConflict->sxactOut->inConflicts, &farConflict->inLink, offsetof(RWConflictData, inLink)); } diff --git a/src/test/regress/pg_dtester.py.in b/src/test/regress/pg_dtester.py.in index 861d254a0c..2fbdd85a54 100644 --- a/src/test/regress/pg_dtester.py.in +++ b/src/test/regress/pg_dtester.py.in @@ -775,7 +775,7 @@ class ReceiptReportTest(DatabasePermutationTest): self.syncCall(10, self.conn1.operation, "INSERT INTO receipt VALUES (2, (SELECT deposit_date FROM ctl WHERE k = 'receipt'), 2.00);") self.syncCall(10, self.conn1.operation, "BEGIN TRANSACTION ISOLATION LEVEL SERIALIZABLE;", "BEGIN") self.syncCall(10, self.conn2.operation, "BEGIN TRANSACTION ISOLATION LEVEL SERIALIZABLE;", "BEGIN") - self.syncCall(10, self.conn3.operation, "BEGIN TRANSACTION READ ONLY ISOLATION LEVEL SERIALIZABLE READ ONLY;", "BEGIN") + self.syncCall(10, self.conn3.operation, "BEGIN TRANSACTION ISOLATION LEVEL SERIALIZABLE, READ ONLY;", "BEGIN") def tearDownIteration(self, stepIdList): self.syncCall(10, self.conn1.operation, "ROLLBACK;") -- 2.39.5