diff options
author | Heikki Linnakangas <heikki.linnakangas@iki.fi> | 2011-03-08 21:01:29 +0200 |
---|---|---|
committer | Heikki Linnakangas <heikki.linnakangas@iki.fi> | 2011-03-08 21:06:26 +0200 |
commit | 46c333a9638b329a3c8076d978f27c5b05c0d5f0 (patch) | |
tree | 6c21581ec177e29074cb639a6a1f3fd7f4775b9f | |
parent | 93d888232e80e4d676e24fe93ae6d27459d966be (diff) | |
download | postgresql-46c333a9638b329a3c8076d978f27c5b05c0d5f0.tar.gz |
Fix overly strict assertion in SummarizeOldestCommittedSxact(). There's a
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.
-rw-r--r-- | src/backend/storage/lmgr/predicate.c | 14 |
1 files changed, 10 insertions, 4 deletions
diff --git a/src/backend/storage/lmgr/predicate.c b/src/backend/storage/lmgr/predicate.c index 15f0a64d3c..870cf4277c 100644 --- a/src/backend/storage/lmgr/predicate.c +++ b/src/backend/storage/lmgr/predicate.c @@ -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 |