OSDN Git Service

Make DROP INDEX lock the parent table before locking the index. This behavior
authorTom Lane <tgl@sss.pgh.pa.us>
Sun, 15 Jun 2008 16:29:05 +0000 (16:29 +0000)
committerTom Lane <tgl@sss.pgh.pa.us>
Sun, 15 Jun 2008 16:29:05 +0000 (16:29 +0000)
is necessary to avoid deadlock against ordinary queries, but we'd broken it
with recent changes that made the DROP machinery lock the index before
arriving at index_drop.  Per intermittent buildfarm failures.

src/backend/commands/tablecmds.c

index b3d2187..639cd72 100644 (file)
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *       $PostgreSQL: pgsql/src/backend/commands/tablecmds.c,v 1.257 2008/06/15 01:25:53 tgl Exp $
+ *       $PostgreSQL: pgsql/src/backend/commands/tablecmds.c,v 1.258 2008/06/15 16:29:05 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -676,6 +676,28 @@ RemoveRelations(DropStmt *drop)
                        continue;
                }
 
+               /*
+                * In DROP INDEX, attempt to acquire lock on the parent table before
+                * locking the index.  index_drop() will need this anyway, and since
+                * regular queries lock tables before their indexes, we risk deadlock
+                * if we do it the other way around.  No error if we don't find a
+                * pg_index entry, though --- that most likely means it isn't an
+                * index, and we'll fail below.
+                */
+               if (relkind == RELKIND_INDEX)
+               {
+                       tuple = SearchSysCache(INDEXRELID,
+                                                                  ObjectIdGetDatum(relOid),
+                                                                  0, 0, 0);
+                       if (HeapTupleIsValid(tuple))
+                       {
+                               Form_pg_index index = (Form_pg_index) GETSTRUCT(tuple);
+
+                               LockRelationOid(index->indrelid, AccessExclusiveLock);
+                               ReleaseSysCache(tuple);
+                       }
+               }
+
                /* Get the lock before trying to fetch the syscache entry */
                LockRelationOid(relOid, AccessExclusiveLock);