From 46c333a9638b329a3c8076d978f27c5b05c0d5f0 Mon Sep 17 00:00:00 2001 From: Heikki Linnakangas <heikki.linnakangas@iki.fi> Date: Tue, 8 Mar 2011 21:01:29 +0200 Subject: [PATCH] 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. --- src/backend/storage/lmgr/predicate.c | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/src/backend/storage/lmgr/predicate.c b/src/backend/storage/lmgr/predicate.c index 15f0a64d3c2..870cf4277cf 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 -- GitLab