From 127f6fd2b6c9a631da402531459bc06c86edad22 Mon Sep 17 00:00:00 2001
From: Alvaro Herrera <alvherre@alvh.no-ip.org>
Date: Tue, 17 Nov 2020 11:42:22 -0300
Subject: [PATCH v7 2/2] Support safe flag in REINDEX CONCURRENTLY

---
 src/backend/commands/indexcmds.c | 27 +++++++++++++++++++++++++--
 src/include/storage/proc.h       |  1 +
 2 files changed, 26 insertions(+), 2 deletions(-)

diff --git a/src/backend/commands/indexcmds.c b/src/backend/commands/indexcmds.c
index 9efb6b5420..98ea2f477e 100644
--- a/src/backend/commands/indexcmds.c
+++ b/src/backend/commands/indexcmds.c
@@ -385,7 +385,7 @@ CompareOpclassOptions(Datum *opts1, Datum *opts2, int natts)
  * lazy VACUUMs, because they won't be fazed by missing index entries
  * either.  (Manual ANALYZEs, however, can't be excluded because they
  * might be within transactions that are going to do arbitrary operations
- * later.)  Processes running CREATE INDEX CONCURRENTLY
+ * later.)  Processes running CREATE INDEX CONCURRENTLY or REINDEX CONCURRENTLY
  * on indexes that are neither expressional nor partial are also safe to
  * ignore, since we know that those processes won't examine any data
  * outside the table they're indexing.
@@ -3043,6 +3043,7 @@ ReindexRelationConcurrently(Oid relationOid, int options)
 		PROGRESS_CREATEIDX_ACCESS_METHOD_OID
 	};
 	int64		progress_vals[4];
+	bool		all_indexes_safe = true;
 
 	/*
 	 * Create a memory context that will survive forced transaction commits we
@@ -3347,6 +3348,12 @@ ReindexRelationConcurrently(Oid relationOid, int options)
 		 */
 		newIndexRel = index_open(newIndexId, ShareUpdateExclusiveLock);
 
+		/* consider safety of this index for set_indexsafe_procflags */
+		if (all_indexes_safe &&
+			(newIndexRel->rd_indexprs != NIL ||
+			 newIndexRel->rd_indpred != NIL))
+			all_indexes_safe = false;
+
 		/*
 		 * Save the list of OIDs and locks in private context
 		 */
@@ -3416,6 +3423,10 @@ ReindexRelationConcurrently(Oid relationOid, int options)
 	CommitTransactionCommand();
 	StartTransactionCommand();
 
+	/* Tell concurrent index builds to ignore us, if index qualifies */
+	if (all_indexes_safe)
+		set_indexsafe_procflags();
+
 	/*
 	 * Phase 2 of REINDEX CONCURRENTLY
 	 *
@@ -3479,6 +3490,10 @@ ReindexRelationConcurrently(Oid relationOid, int options)
 	}
 	StartTransactionCommand();
 
+	/* Tell concurrent index builds to ignore us, if index qualifies */
+	if (all_indexes_safe)
+		set_indexsafe_procflags();
+
 	/*
 	 * Phase 3 of REINDEX CONCURRENTLY
 	 *
@@ -3632,6 +3647,10 @@ ReindexRelationConcurrently(Oid relationOid, int options)
 	CommitTransactionCommand();
 	StartTransactionCommand();
 
+	/* Tell concurrent index builds to ignore us, if index qualifies */
+	if (all_indexes_safe)
+		set_indexsafe_procflags();
+
 	/*
 	 * Phase 5 of REINDEX CONCURRENTLY
 	 *
@@ -3664,6 +3683,10 @@ ReindexRelationConcurrently(Oid relationOid, int options)
 	CommitTransactionCommand();
 	StartTransactionCommand();
 
+	/* Tell concurrent index builds to ignore us, if index qualifies */
+	if (all_indexes_safe)
+		set_indexsafe_procflags();
+
 	/*
 	 * Phase 6 of REINDEX CONCURRENTLY
 	 *
@@ -3925,7 +3948,7 @@ update_relispartition(Oid relationId, bool newval)
  *
  * When doing concurrent index builds, we can set this flag
  * to tell other processes concurrently running CREATE
- * INDEX CONCURRENTLY to ignore us when
+ * INDEX CONCURRENTLY and REINDEX CONCURRENTLY to ignore us when
  * doing their waits for concurrent snapshots.  On one hand it
  * avoids pointlessly waiting for a process that's not interesting
  * anyway; but more importantly it avoids deadlocks in some cases.
diff --git a/src/include/storage/proc.h b/src/include/storage/proc.h
index e75f6e8178..532493bccc 100644
--- a/src/include/storage/proc.h
+++ b/src/include/storage/proc.h
@@ -54,6 +54,7 @@ struct XidCache
 #define		PROC_IS_AUTOVACUUM	0x01	/* is it an autovac worker? */
 #define		PROC_IN_VACUUM		0x02	/* currently running lazy vacuum */
 #define		PROC_IN_SAFE_IC		0x04	/* currently running CREATE INDEX
+										 * CONCURRENTLY or REINDEX
 										 * CONCURRENTLY on non-expressional,
 										 * non-partial index */
 #define		PROC_VACUUM_FOR_WRAPAROUND	0x08	/* set by autovac only */
-- 
2.20.1

