aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorTom Lane <tgl@sss.pgh.pa.us>2007-03-30 00:13:05 +0000
committerTom Lane <tgl@sss.pgh.pa.us>2007-03-30 00:13:05 +0000
commit0e95abd64cd3d68da4e9134554ede4badcd106d4 (patch)
treefae6a30fc7f1209556d873200b2665e860ffbfdd /src
parent2dd336bba56d9caa7bcbca550fba34423f8d71e6 (diff)
downloadpostgresql-0e95abd64cd3d68da4e9134554ede4badcd106d4.tar.gz
postgresql-0e95abd64cd3d68da4e9134554ede4badcd106d4.zip
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.
Diffstat (limited to 'src')
-rw-r--r--src/backend/access/nbtree/nbtutils.c14
1 files changed, 13 insertions, 1 deletions
diff --git a/src/backend/access/nbtree/nbtutils.c b/src/backend/access/nbtree/nbtutils.c
index a562ee6cbd2..47abb5750dd 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.79 2006/10/04 00:29:49 momjian Exp $
+ * $PostgreSQL: pgsql/src/backend/access/nbtree/nbtutils.c,v 1.79.2.1 2007/03/30 00:13:05 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -998,13 +998,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;