From b1f8a37aa7b19f2e7a1965005503437dd15c7138 Mon Sep 17 00:00:00 2001
From: Tom Lane <tgl@sss.pgh.pa.us>
Date: Fri, 1 Oct 2004 17:11:50 +0000
Subject: [PATCH] Fallout from changing index locking rules: we can reduce the
 strength 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          | 36 +++++++++++-----------------
 src/backend/optimizer/util/plancat.c | 11 +++++++--
 2 files changed, 23 insertions(+), 24 deletions(-)

diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c
index cace4852d51..8fb2f8f4f22 100644
--- a/src/backend/catalog/index.c
+++ b/src/backend/catalog/index.c
@@ -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;
 
diff --git a/src/backend/optimizer/util/plancat.c b/src/backend/optimizer/util/plancat.c
index ba58251919b..ed76fe8fb8c 100644
--- a/src/backend/optimizer/util/plancat.c
+++ b/src/backend/optimizer/util/plancat.c
@@ -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;
 
-- 
GitLab