]> granicus.if.org Git - postgresql/commitdiff
Fix overly strict assertion in SummarizeOldestCommittedSxact(). There's a
authorHeikki Linnakangas <heikki.linnakangas@iki.fi>
Tue, 8 Mar 2011 19:01:29 +0000 (21:01 +0200)
committerHeikki Linnakangas <heikki.linnakangas@iki.fi>
Tue, 8 Mar 2011 19:06:26 +0000 (21:06 +0200)
race condition where SummarizeOldestCommittedSxact() is called even though
another backend already cleared out all finished sxact entries. That's OK,
RegisterSerializableTransactionInt() can just retry getting a news xact
slot from the available-list when that happens.

Reported by YAMAMOTO Takashi, bug #5918.

src/backend/storage/lmgr/predicate.c

index 15f0a64d3c2f8d95468ae0c7006f1918709d5be6..870cf4277cf991aca1c588b70330d398843a8faf 100644 (file)
@@ -1314,15 +1314,21 @@ SummarizeOldestCommittedSxact(void)
 
        LWLockAcquire(SerializableFinishedListLock, LW_EXCLUSIVE);
 
-#ifdef TEST_OLDSERXID
+       /*
+        * This function is only called if there are no sxact slots available.
+        * Some of them must belong to old, already-finished transactions, so
+        * there should be something in FinishedSerializableTransactions list
+        * that we can summarize. However, there's a race condition: while we
+        * were not holding any locks, a transaction might have ended and cleaned
+        * up all the finished sxact entries already, freeing up their sxact
+        * slots. In that case, we have nothing to do here. The caller will find
+        * one of the slots released by the other backend when it retries.
+        */
        if (SHMQueueEmpty(FinishedSerializableTransactions))
        {
                LWLockRelease(SerializableFinishedListLock);
                return;
        }
-#else
-       Assert(!SHMQueueEmpty(FinishedSerializableTransactions));
-#endif
 
        /*
         * Grab the first sxact off the finished list -- this will be the earliest