From 35e5767503e1292c321acd7af0953d75ee969f30 Mon Sep 17 00:00:00 2001 From: Kevin Grittner Date: Sat, 27 Nov 2010 10:24:02 -0600 Subject: [PATCH] Clean up rolled-back transaction immediately. Minor LW locking adjustments and comment improvements also included. --- src/backend/storage/lmgr/predicate.c | 33 ++++++++++++++++------------ 1 file changed, 19 insertions(+), 14 deletions(-) diff --git a/src/backend/storage/lmgr/predicate.c b/src/backend/storage/lmgr/predicate.c index 37d9c207c5..79d0216a46 100644 --- a/src/backend/storage/lmgr/predicate.c +++ b/src/backend/storage/lmgr/predicate.c @@ -217,6 +217,7 @@ #define SxactIsCommitted(sxact) (((sxact)->flags & SXACT_FLAG_COMMITTED) != 0) #define SxactIsRolledBack(sxact) (((sxact)->flags & SXACT_FLAG_ROLLED_BACK) != 0) #define SxactIsReadOnly(sxact) (((sxact)->flags & SXACT_FLAG_READ_ONLY) != 0) +#define SxactHasConflictOut(sxact) (((sxact)->flags & SXACT_FLAG_CONFLICT_OUT) != 0) #define SxactCommittedBefore(sxactPivotOut, sxactOther) \ ((!TransactionIdIsValid((sxactOther)->finishedBefore)) \ @@ -1859,6 +1860,7 @@ ReleasePredicateLocks(const bool isCommit) Assert(!SxactIsRolledBack((SERIALIZABLEXACT *) MySerializableXact)); Assert(SxactIsCommitted((SERIALIZABLEXACT *) MySerializableXact)); MySerializableXact->commitSeqNo = ++LastSerializableCommitSeqNo; + /* Recognize implicit read-only transaction (commit without write). */ if (!(MySerializableXact->flags & SXACT_FLAG_DID_WRITE)) MySerializableXact->flags |= SXACT_FLAG_READ_ONLY; } @@ -1915,11 +1917,12 @@ ReleasePredicateLocks(const bool isCommit) LWLockRelease(SerializableXactHashLock); - /* Add this to the list of transactions to check for later cleanup. */ LWLockAcquire(SerializableFinishedListLock, LW_EXCLUSIVE); - SHMQueueInsertBefore(FinishedSerializableTransactions, - (SHM_QUEUE *) &(MySerializableXact->finishedLink)); - LWLockRelease(SerializableFinishedListLock); + + /* Add this to the list of transactions to check for later cleanup. */ + if (isCommit) + SHMQueueInsertBefore(FinishedSerializableTransactions, + (SHM_QUEUE *) &(MySerializableXact->finishedLink)); /* * Check whether it's time to clean up old transactions. This can only be @@ -1929,17 +1932,22 @@ ReleasePredicateLocks(const bool isCommit) * was launched. */ needToClear = false; - LWLockAcquire(SerializableXactHashLock, LW_EXCLUSIVE); if (TransactionIdEquals(MySerializableXact->xmin, SerializableGlobalXmin)) { + LWLockAcquire(SerializableXactHashLock, LW_EXCLUSIVE); Assert(SerializableGlobalXminCount > 0); if (--SerializableGlobalXminCount == 0) { SetNewSerializableGlobalXmin(); needToClear = true; } + LWLockRelease(SerializableXactHashLock); } - LWLockRelease(SerializableXactHashLock); + + LWLockRelease(SerializableFinishedListLock); + + if (!isCommit) + ReleaseOneSerializableXact((SERIALIZABLEXACT *) MySerializableXact); if (needToClear) ClearOldPredicateLocks(); @@ -1978,6 +1986,7 @@ ClearOldPredicateLocks(void) SerializableGlobalXmin)) { LWLockRelease(SerializableXactHashLock); + SHMQueueDelete(&(finishedSxact->finishedLink)); ReleaseOneSerializableXact(finishedSxact); LWLockAcquire(SerializableXactHashLock, LW_SHARED); } @@ -2005,7 +2014,6 @@ ReleaseOneSerializableXact(SERIALIZABLEXACT *sxact) Assert(sxact != NULL); Assert(SxactIsRolledBack(sxact) || SxactIsCommitted(sxact)); - Assert(SxactIsOnFinishedList(sxact)); LWLockAcquire(SerializablePredicateLockListLock, LW_SHARED); predlock = (PREDICATELOCK *) @@ -2036,10 +2044,9 @@ ReleaseOneSerializableXact(SERIALIZABLEXACT *sxact) LWLockAcquire(partitionLock, LW_EXCLUSIVE); SHMQueueDelete(targetLink); - /* - * No need to do retail removal from transaction object; it's going - * away. + * No need to do retail removal of predicate locks from transaction + * object; it's going away. */ hash_search_with_hash_value(PredicateLockHash, &tag, PredicateLockHashCodeFromTargetHashCode(&tag, @@ -2053,8 +2060,6 @@ ReleaseOneSerializableXact(SERIALIZABLEXACT *sxact) } LWLockRelease(SerializablePredicateLockListLock); - SHMQueueDelete(&(sxact->finishedLink)); - sxidtag.xid = sxact->topXid; LWLockAcquire(SerializableXactHashLock, LW_EXCLUSIVE); @@ -2235,7 +2240,7 @@ CheckForSerializableConflictOut(const bool valid, const Relation relation, */ if (SxactIsReadOnly((SERIALIZABLEXACT *) MySerializableXact) && SxactIsCommitted(sxact) - && (sxact->flags & SXACT_FLAG_CONFLICT_OUT) == 0) + && !SxactHasConflictOut(sxact)) { /* Read-only transaction will appear to run first. No conflict. */ LWLockRelease(SerializableXactHashLock); @@ -2572,7 +2577,7 @@ OnConflict_CheckForSerializationFailure(const SERIALIZABLEXACT *reader, * Check for already-committed writer with rw-conflict out flagged. * This means that the reader must immediately fail. */ - if (SxactIsCommitted(writer) && (writer->flags & SXACT_FLAG_CONFLICT_OUT)) + if (SxactIsCommitted(writer) && SxactHasConflictOut(writer)) failure = true; /* -- 2.39.5