Fallout from changing index locking rules: we can reduce the strength
authorTom Lane
Fri, 1 Oct 2004 17:11:50 +0000 (17:11 +0000)
committerTom Lane
Fri, 1 Oct 2004 17:11:50 +0000 (17:11 +0000)
of locking used by REINDEX.  REINDEX needs only ShareLock on the parent
table, same as CREATE INDEX, plus an exclusive lock on the specific index
being processed.

src/backend/catalog/index.c
src/backend/optimizer/util/plancat.c

index cace4852d5122343e6216e403866e03f2e87b47f..8fb2f8f4f222c44185ae6ea9c2b2702f3bcbb7c5 100644 (file)
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *   $PostgreSQL: pgsql/src/backend/catalog/index.c,v 1.239 2004/08/31 17:10:36 tgl Exp $
+ *   $PostgreSQL: pgsql/src/backend/catalog/index.c,v 1.240 2004/10/01 17:11:49 tgl Exp $
  *
  *
  * INTERFACE ROUTINES
@@ -777,7 +777,7 @@ index_drop(Oid indexId)
     * backend might be in the midst of devising a query plan that will
     * use the index.  The parser and planner take care to hold an
     * appropriate lock on the parent table while working, but having them
-    * hold locks on all the indexes too seems overly complex.  We do grab
+    * hold locks on all the indexes too seems overly expensive.  We do grab
     * exclusive lock on the index too, just to be safe. Both locks must
     * be held till end of transaction, else other backends will still see
     * this index in pg_index.
@@ -1655,26 +1655,19 @@ reindex_index(Oid indexId)
    bool        inplace;
 
    /*
-    * Open our index relation and get an exclusive lock on it.
-    *
-    * Note: for REINDEX INDEX, doing this before opening the parent heap
-    * relation means there's a possibility for deadlock failure against
-    * another xact that is doing normal accesses to the heap and index.
-    * However, it's not real clear why you'd be wanting to do REINDEX
-    * INDEX on a table that's in active use, so I'd rather have the
-    * protection of making sure the index is locked down.  In the REINDEX
-    * TABLE and REINDEX DATABASE cases, there is no problem because
-    * caller already holds exclusive lock on the parent table.
+    * Open and lock the parent heap relation.  ShareLock is sufficient
+    * since we only need to be sure no schema or data changes are going on.
+    */
+   heapId = IndexGetRelation(indexId);
+   heapRelation = heap_open(heapId, ShareLock);
+
+   /*
+    * Open the target index relation and get an exclusive lock on it,
+    * to ensure that no one else is touching this particular index.
     */
    iRel = index_open(indexId);
    LockRelation(iRel, AccessExclusiveLock);
 
-   /* Get OID of index's parent table */
-   heapId = iRel->rd_index->indrelid;
-
-   /* Open and lock the parent heap relation */
-   heapRelation = heap_open(heapId, AccessExclusiveLock);
-
    /*
     * If it's a shared index, we must do inplace processing (because we
     * have no way to update relfilenode in other databases).  Otherwise
@@ -1759,11 +1752,10 @@ reindex_relation(Oid relid, bool toast_too)
    ListCell   *indexId;
 
    /*
-    * Ensure to hold an exclusive lock throughout the transaction. The
-    * lock could perhaps be less intensive (in the non-overwrite case)
-    * but for now it's AccessExclusiveLock for simplicity.
+    * Open and lock the relation.  ShareLock is sufficient since we only
+    * need to prevent schema and data changes in it.
     */
-   rel = heap_open(relid, AccessExclusiveLock);
+   rel = heap_open(relid, ShareLock);
 
    toast_relid = rel->rd_rel->reltoastrelid;
 
index ba58251919bd037aff69f7229e58d36808ef7acf..ed76fe8fb8cb6091d397439f81a893bdcf5c630d 100644 (file)
@@ -9,7 +9,7 @@
  *
  *
  * IDENTIFICATION
- *   $PostgreSQL: pgsql/src/backend/optimizer/util/plancat.c,v 1.96 2004/08/29 05:06:44 momjian Exp $
+ *   $PostgreSQL: pgsql/src/backend/optimizer/util/plancat.c,v 1.97 2004/10/01 17:11:50 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -90,7 +90,14 @@ get_relation_info(Oid relationObjectId, RelOptInfo *rel)
            int         i;
            int16       amorderstrategy;
 
-           /* Extract info from the relation descriptor for the index */
+           /*
+            * Extract info from the relation descriptor for the index.
+            *
+            * Note that we take no lock on the index; we assume our lock on
+            * the parent table will protect the index's schema information.
+            * When and if the executor actually uses the index, it will take
+            * a lock as needed to protect the access to the index contents.
+            */
            indexRelation = index_open(indexoid);
            index = indexRelation->rd_index;