From: Tom Lane Date: Fri, 30 Mar 2007 00:12:59 +0000 (+0000) Subject: Fix oversight in coding of _bt_start_vacuum: we can't assume that the LWLock X-Git-Tag: REL8_3_BETA1~925 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=8875d0987d767f0ea14bffd636841e003d41eca8;p=postgresql Fix oversight in coding of _bt_start_vacuum: we can't assume that the LWLock will be released by transaction abort before _bt_end_vacuum gets called. If either of these "can't happen" errors actually happened, we'd freeze up trying to acquire an already-held lock. Latest word is that this does not explain Martin Pitt's trouble report, but it still looks like a bug. --- diff --git a/src/backend/access/nbtree/nbtutils.c b/src/backend/access/nbtree/nbtutils.c index d453a93caf..9c227d7f6c 100644 --- a/src/backend/access/nbtree/nbtutils.c +++ b/src/backend/access/nbtree/nbtutils.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $PostgreSQL: pgsql/src/backend/access/nbtree/nbtutils.c,v 1.82 2007/01/09 02:14:10 tgl Exp $ + * $PostgreSQL: pgsql/src/backend/access/nbtree/nbtutils.c,v 1.83 2007/03/30 00:12:59 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -1214,13 +1214,25 @@ _bt_start_vacuum(Relation rel) vac = &btvacinfo->vacuums[i]; if (vac->relid.relId == rel->rd_lockInfo.lockRelId.relId && vac->relid.dbId == rel->rd_lockInfo.lockRelId.dbId) + { + /* + * Unlike most places in the backend, we have to explicitly + * release our LWLock before throwing an error. This is because + * we expect _bt_end_vacuum() to be called before transaction + * abort cleanup can run to release LWLocks. + */ + LWLockRelease(BtreeVacuumLock); elog(ERROR, "multiple active vacuums for index \"%s\"", RelationGetRelationName(rel)); + } } /* OK, add an entry */ if (btvacinfo->num_vacuums >= btvacinfo->max_vacuums) + { + LWLockRelease(BtreeVacuumLock); elog(ERROR, "out of btvacinfo slots"); + } vac = &btvacinfo->vacuums[btvacinfo->num_vacuums]; vac->relid = rel->rd_lockInfo.lockRelId; vac->cycleid = result;