diff --git a/contrib/amcheck/t/004_verify_nbtree_unique.pl b/contrib/amcheck/t/004_verify_nbtree_unique.pl
index 4b704e68151..3b22d561828 100644
--- a/contrib/amcheck/t/004_verify_nbtree_unique.pl
+++ b/contrib/amcheck/t/004_verify_nbtree_unique.pl
@@ -20,11 +20,8 @@ $node->safe_psql(
 	'postgres', q(
 	CREATE EXTENSION amcheck;
 
-	CREATE SCHEMA test_amcheck;
-	SET search_path = test_amcheck;
-
 	CREATE FUNCTION ok_cmp (int4, int4)
-	RETURNS int LANGUAGE sql SET search_path = test_amcheck AS
+	RETURNS int LANGUAGE sql AS
 	$$
 		SELECT
 			CASE WHEN $1 < $2 THEN -1
@@ -37,21 +34,21 @@ $node->safe_psql(
 	--- Check 1: uniqueness violation.
 	---
 	CREATE FUNCTION ok_cmp1 (int4, int4)
-	RETURNS int LANGUAGE sql SET search_path = test_amcheck AS
+	RETURNS int LANGUAGE sql AS
 	$$
-		SELECT ok_cmp($1, $2);
+		SELECT public.ok_cmp($1, $2);
 	$$;
 
 	---
 	--- Make values 768 and 769 look equal.
 	---
 	CREATE FUNCTION bad_cmp1 (int4, int4)
-	RETURNS int LANGUAGE sql SET search_path = test_amcheck AS
+	RETURNS int LANGUAGE sql AS
 	$$
 		SELECT
 			CASE WHEN ($1 = 768 AND $2 = 769) OR
 					  ($1 = 769 AND $2 = 768) THEN 0
-				 ELSE ok_cmp($1, $2)
+				 ELSE public.ok_cmp($1, $2)
 			END;
 	$$;
 
@@ -59,17 +56,17 @@ $node->safe_psql(
 	--- Check 2: uniqueness violation without deduplication.
 	---
 	CREATE FUNCTION ok_cmp2 (int4, int4)
-	RETURNS int LANGUAGE sql SET search_path = test_amcheck AS
+	RETURNS int LANGUAGE sql AS
 	$$
-		SELECT ok_cmp($1, $2);
+		SELECT public.ok_cmp($1, $2);
 	$$;
 
 	CREATE FUNCTION bad_cmp2 (int4, int4)
-	RETURNS int LANGUAGE sql SET search_path = test_amcheck AS
+	RETURNS int LANGUAGE sql AS
 	$$
 		SELECT
 			CASE WHEN $1 = $2 AND $1 = 400 THEN -1
-			ELSE ok_cmp($1, $2)
+			ELSE public.ok_cmp($1, $2)
 		END;
 	$$;
 
@@ -77,15 +74,15 @@ $node->safe_psql(
 	--- Check 3: uniqueness violation with deduplication.
 	---
 	CREATE FUNCTION ok_cmp3 (int4, int4)
-	RETURNS int LANGUAGE sql SET search_path = test_amcheck AS
+	RETURNS int LANGUAGE sql AS
 	$$
-		SELECT ok_cmp($1, $2);
+		SELECT public.ok_cmp($1, $2);
 	$$;
 
 	CREATE FUNCTION bad_cmp3 (int4, int4)
-	RETURNS int LANGUAGE sql SET search_path = test_amcheck AS
+	RETURNS int LANGUAGE sql AS
 	$$
-		SELECT bad_cmp2($1, $2);
+		SELECT public.bad_cmp2($1, $2);
 	$$;
 
 	---
@@ -145,7 +142,7 @@ my ($result, $stdout, $stderr);
 # We have not yet broken the index, so we should get no corruption
 $result = $node->safe_psql(
 	'postgres', q(
-	SELECT bt_index_check('test_amcheck.bttest_unique_idx1', true, true);
+	SELECT bt_index_check('bttest_unique_idx1', true, true);
 ));
 is($result, '', 'run amcheck on non-broken bttest_unique_idx1');
 
@@ -153,7 +150,6 @@ is($result, '', 'run amcheck on non-broken bttest_unique_idx1');
 # values to be equal.
 $node->safe_psql(
 	'postgres', q(
-	SET search_path = test_amcheck;
 	UPDATE pg_catalog.pg_amproc SET
 		   amproc = 'bad_cmp1'::regproc
 	WHERE amproc = 'ok_cmp1'::regproc;
@@ -161,7 +157,7 @@ $node->safe_psql(
 
 ($result, $stdout, $stderr) = $node->psql(
 	'postgres', q(
-	SELECT bt_index_check('test_amcheck.bttest_unique_idx1', true, true);
+	SELECT bt_index_check('bttest_unique_idx1', true, true);
 ));
 ok( $stderr =~ /index uniqueness is violated for index "bttest_unique_idx1"/,
 	'detected uniqueness violation for index "bttest_unique_idx1"');
@@ -179,14 +175,13 @@ ok( $stderr =~ /index uniqueness is violated for index "bttest_unique_idx1"/,
 # but no uniqueness violation.
 ($result, $stdout, $stderr) = $node->psql(
 	'postgres', q(
-	SELECT bt_index_check('test_amcheck.bttest_unique_idx2', true, true);
+	SELECT bt_index_check('bttest_unique_idx2', true, true);
 ));
 ok( $stderr =~ /item order invariant violated for index "bttest_unique_idx2"/,
 	'detected item order invariant violation for index "bttest_unique_idx2"');
 
 $node->safe_psql(
 	'postgres', q(
-	SET search_path = test_amcheck;
 	UPDATE pg_catalog.pg_amproc SET
 		   amproc = 'ok_cmp2'::regproc
 	WHERE amproc = 'bad_cmp2'::regproc;
@@ -194,7 +189,7 @@ $node->safe_psql(
 
 ($result, $stdout, $stderr) = $node->psql(
 	'postgres', q(
-	SELECT bt_index_check('test_amcheck.bttest_unique_idx2', true, true);
+	SELECT bt_index_check('bttest_unique_idx2', true, true);
 ));
 ok( $stderr =~ /index uniqueness is violated for index "bttest_unique_idx2"/,
 	'detected uniqueness violation for index "bttest_unique_idx2"');
@@ -211,7 +206,7 @@ ok( $stderr =~ /index uniqueness is violated for index "bttest_unique_idx2"/,
 # but no uniqueness violation.
 ($result, $stdout, $stderr) = $node->psql(
 	'postgres', q(
-	SELECT bt_index_check('test_amcheck.bttest_unique_idx3', true, true);
+	SELECT bt_index_check('bttest_unique_idx3', true, true);
 ));
 ok( $stderr =~ /item order invariant violated for index "bttest_unique_idx3"/,
 	'detected item order invariant violation for index "bttest_unique_idx3"');
@@ -220,7 +215,6 @@ ok( $stderr =~ /item order invariant violated for index "bttest_unique_idx3"/,
 # with different visibility.
 $node->safe_psql(
 	'postgres', q(
-	SET search_path = test_amcheck;
 	DELETE FROM bttest_unique3 WHERE 380 <= i AND i <= 420;
 	INSERT INTO bttest_unique3 (SELECT * FROM generate_series(380, 420));
 	INSERT INTO bttest_unique3 VALUES (400);
@@ -234,7 +228,6 @@ $node->safe_psql(
 
 $node->safe_psql(
 	'postgres', q(
-	SET search_path = test_amcheck;
 	UPDATE pg_catalog.pg_amproc SET
 		   amproc = 'ok_cmp3'::regproc
 	WHERE amproc = 'bad_cmp3'::regproc;
@@ -242,7 +235,7 @@ $node->safe_psql(
 
 ($result, $stdout, $stderr) = $node->psql(
 	'postgres', q(
-	SELECT bt_index_check('test_amcheck.bttest_unique_idx3', true, true);
+	SELECT bt_index_check('bttest_unique_idx3', true, true);
 ));
 ok( $stderr =~ /index uniqueness is violated for index "bttest_unique_idx3"/,
 	'detected uniqueness violation for index "bttest_unique_idx3"');
diff --git a/contrib/amcheck/verify_nbtree.c b/contrib/amcheck/verify_nbtree.c
index bff8c61262c..1ef4cff88e8 100644
--- a/contrib/amcheck/verify_nbtree.c
+++ b/contrib/amcheck/verify_nbtree.c
@@ -313,8 +313,7 @@ bt_index_check_internal(Oid indrelid, bool parentcheck, bool heapallindexed,
 		SetUserIdAndSecContext(heaprel->rd_rel->relowner,
 							   save_sec_context | SECURITY_RESTRICTED_OPERATION);
 		save_nestlevel = NewGUCNestLevel();
-		SetConfigOption("search_path", GUC_SAFE_SEARCH_PATH, PGC_USERSET,
-						PGC_S_SESSION);
+		RestrictSearchPath();
 	}
 	else
 	{
diff --git a/src/backend/access/brin/brin.c b/src/backend/access/brin/brin.c
index 9ea6f37f2be..041415a40e7 100644
--- a/src/backend/access/brin/brin.c
+++ b/src/backend/access/brin/brin.c
@@ -1412,8 +1412,7 @@ brin_summarize_range(PG_FUNCTION_ARGS)
 		SetUserIdAndSecContext(heapRel->rd_rel->relowner,
 							   save_sec_context | SECURITY_RESTRICTED_OPERATION);
 		save_nestlevel = NewGUCNestLevel();
-		SetConfigOption("search_path", GUC_SAFE_SEARCH_PATH, PGC_USERSET,
-						PGC_S_SESSION);
+		RestrictSearchPath();
 	}
 	else
 	{
diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c
index 1813b73a4fa..e6140853c05 100644
--- a/src/backend/catalog/index.c
+++ b/src/backend/catalog/index.c
@@ -1464,8 +1464,7 @@ index_concurrently_build(Oid heapRelationId,
 	SetUserIdAndSecContext(heapRel->rd_rel->relowner,
 						   save_sec_context | SECURITY_RESTRICTED_OPERATION);
 	save_nestlevel = NewGUCNestLevel();
-	SetConfigOption("search_path", GUC_SAFE_SEARCH_PATH, PGC_USERSET,
-					PGC_S_SESSION);
+	RestrictSearchPath();
 
 	indexRelation = index_open(indexRelationId, RowExclusiveLock);
 
@@ -3018,9 +3017,7 @@ index_build(Relation heapRelation,
 	SetUserIdAndSecContext(heapRelation->rd_rel->relowner,
 						   save_sec_context | SECURITY_RESTRICTED_OPERATION);
 	save_nestlevel = NewGUCNestLevel();
-	if (!IsBootstrapProcessingMode())
-		SetConfigOption("search_path", GUC_SAFE_SEARCH_PATH, PGC_USERSET,
-						PGC_S_SESSION);
+	RestrictSearchPath();
 
 	/* Set up initial progress report status */
 	{
@@ -3356,8 +3353,7 @@ validate_index(Oid heapId, Oid indexId, Snapshot snapshot)
 	SetUserIdAndSecContext(heapRelation->rd_rel->relowner,
 						   save_sec_context | SECURITY_RESTRICTED_OPERATION);
 	save_nestlevel = NewGUCNestLevel();
-	SetConfigOption("search_path", GUC_SAFE_SEARCH_PATH, PGC_USERSET,
-					PGC_S_SESSION);
+	RestrictSearchPath();
 
 	indexRelation = index_open(indexId, RowExclusiveLock);
 
@@ -3619,8 +3615,7 @@ reindex_index(const ReindexStmt *stmt, Oid indexId,
 	SetUserIdAndSecContext(heapRelation->rd_rel->relowner,
 						   save_sec_context | SECURITY_RESTRICTED_OPERATION);
 	save_nestlevel = NewGUCNestLevel();
-	SetConfigOption("search_path", GUC_SAFE_SEARCH_PATH, PGC_USERSET,
-					PGC_S_SESSION);
+	RestrictSearchPath();
 
 	if (progress)
 	{
diff --git a/src/backend/commands/analyze.c b/src/backend/commands/analyze.c
index b054ba18155..29b6a20f1ed 100644
--- a/src/backend/commands/analyze.c
+++ b/src/backend/commands/analyze.c
@@ -339,8 +339,7 @@ do_analyze_rel(Relation onerel, VacuumParams *params,
 	SetUserIdAndSecContext(onerel->rd_rel->relowner,
 						   save_sec_context | SECURITY_RESTRICTED_OPERATION);
 	save_nestlevel = NewGUCNestLevel();
-	SetConfigOption("search_path", GUC_SAFE_SEARCH_PATH, PGC_USERSET,
-					PGC_S_SESSION);
+	RestrictSearchPath();
 
 	/* measure elapsed time iff autovacuum logging requires it */
 	if (AmAutoVacuumWorkerProcess() && params->log_min_duration >= 0)
diff --git a/src/backend/commands/cluster.c b/src/backend/commands/cluster.c
index 2b69dc0558f..cea7c8ea368 100644
--- a/src/backend/commands/cluster.c
+++ b/src/backend/commands/cluster.c
@@ -350,8 +350,7 @@ cluster_rel(Oid tableOid, Oid indexOid, ClusterParams *params)
 	SetUserIdAndSecContext(OldHeap->rd_rel->relowner,
 						   save_sec_context | SECURITY_RESTRICTED_OPERATION);
 	save_nestlevel = NewGUCNestLevel();
-	SetConfigOption("search_path", GUC_SAFE_SEARCH_PATH, PGC_USERSET,
-					PGC_S_SESSION);
+	RestrictSearchPath();
 
 	/*
 	 * Since we may open a new transaction for each relation, we have to check
diff --git a/src/backend/commands/indexcmds.c b/src/backend/commands/indexcmds.c
index d0813278eac..943a48bfa71 100644
--- a/src/backend/commands/indexcmds.c
+++ b/src/backend/commands/indexcmds.c
@@ -585,9 +585,7 @@ DefineIndex(Oid tableId,
 
 	root_save_nestlevel = NewGUCNestLevel();
 
-	if (!IsBootstrapProcessingMode())
-		SetConfigOption("search_path", GUC_SAFE_SEARCH_PATH, PGC_USERSET,
-						PGC_S_SESSION);
+	RestrictSearchPath();
 
 	/*
 	 * Some callers need us to run with an empty default_tablespace; this is a
@@ -1344,8 +1342,7 @@ DefineIndex(Oid tableId,
 				SetUserIdAndSecContext(childrel->rd_rel->relowner,
 									   child_save_sec_context | SECURITY_RESTRICTED_OPERATION);
 				child_save_nestlevel = NewGUCNestLevel();
-				SetConfigOption("search_path", GUC_SAFE_SEARCH_PATH, PGC_USERSET,
-								PGC_S_SESSION);
+				RestrictSearchPath();
 
 				/*
 				 * Don't try to create indexes on foreign tables, though. Skip
@@ -3887,8 +3884,7 @@ ReindexRelationConcurrently(const ReindexStmt *stmt, Oid relationOid, const Rein
 		SetUserIdAndSecContext(heapRel->rd_rel->relowner,
 							   save_sec_context | SECURITY_RESTRICTED_OPERATION);
 		save_nestlevel = NewGUCNestLevel();
-		SetConfigOption("search_path", GUC_SAFE_SEARCH_PATH, PGC_USERSET,
-						PGC_S_SESSION);
+		RestrictSearchPath();
 
 		/* determine safety of this index for set_indexsafe_procflags */
 		idx->safe = (indexRel->rd_indexprs == NIL &&
diff --git a/src/backend/commands/matview.c b/src/backend/commands/matview.c
index 1887cd60ea6..03373462f0e 100644
--- a/src/backend/commands/matview.c
+++ b/src/backend/commands/matview.c
@@ -173,8 +173,7 @@ ExecRefreshMatView(RefreshMatViewStmt *stmt, const char *queryString,
 	SetUserIdAndSecContext(relowner,
 						   save_sec_context | SECURITY_RESTRICTED_OPERATION);
 	save_nestlevel = NewGUCNestLevel();
-	SetConfigOption("search_path", GUC_SAFE_SEARCH_PATH, PGC_USERSET,
-					PGC_S_SESSION);
+	RestrictSearchPath();
 
 	/* Make sure it is a materialized view. */
 	if (matviewRel->rd_rel->relkind != RELKIND_MATVIEW)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 02d0dc4aba7..25281bbed98 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -2166,8 +2166,7 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
 	SetUserIdAndSecContext(rel->rd_rel->relowner,
 						   save_sec_context | SECURITY_RESTRICTED_OPERATION);
 	save_nestlevel = NewGUCNestLevel();
-	SetConfigOption("search_path", GUC_SAFE_SEARCH_PATH, PGC_USERSET,
-					PGC_S_SESSION);
+	RestrictSearchPath();
 
 	/*
 	 * If PROCESS_MAIN is set (the default), it's time to vacuum the main
diff --git a/src/backend/utils/misc/guc.c b/src/backend/utils/misc/guc.c
index f12eef75e0c..dd5a46469a6 100644
--- a/src/backend/utils/misc/guc.c
+++ b/src/backend/utils/misc/guc.c
@@ -67,6 +67,12 @@
  */
 #define REALTYPE_PRECISION 17
 
+/*
+ * Safe search path when executing code as the table owner, such as during
+ * maintenance operations.
+ */
+#define GUC_SAFE_SEARCH_PATH "pg_catalog, pg_temp"
+
 static int	GUC_check_errcode_value;
 
 static List *reserved_class_prefix = NIL;
@@ -2234,6 +2240,19 @@ NewGUCNestLevel(void)
 	return ++GUCNestLevel;
 }
 
+/*
+ * Set search_path to a fixed value for maintenance operations. No effect
+ * during bootstrap, when the search_path is already set to a fixed value and
+ * cannot be changed.
+ */
+void
+RestrictSearchPath(void)
+{
+	if (!IsBootstrapProcessingMode())
+		set_config_option("search_path", GUC_SAFE_SEARCH_PATH, PGC_USERSET,
+						  PGC_S_SESSION, GUC_ACTION_SAVE, true, 0, false);
+}
+
 /*
  * Do GUC processing at transaction or subtransaction commit or abort, or
  * when exiting a function that has proconfig settings, or when undoing a
diff --git a/src/include/utils/guc.h b/src/include/utils/guc.h
index 391d8d02120..3712aba09b0 100644
--- a/src/include/utils/guc.h
+++ b/src/include/utils/guc.h
@@ -203,12 +203,6 @@ typedef enum
 
 #define GUC_QUALIFIER_SEPARATOR '.'
 
-/*
- * Safe search path when executing code as the table owner, such as during
- * maintenance operations.
- */
-#define GUC_SAFE_SEARCH_PATH "pg_catalog, pg_temp"
-
 /*
  * Bit values in "flags" of a GUC variable.  Note that these don't appear
  * on disk, so we can reassign their values freely.
@@ -378,6 +372,7 @@ extern bool SelectConfigFiles(const char *userDoption, const char *progname);
 extern void ResetAllOptions(void);
 extern void AtStart_GUC(void);
 extern int	NewGUCNestLevel(void);
+extern void RestrictSearchPath(void);
 extern void AtEOXact_GUC(bool isCommit, int nestLevel);
 extern void BeginReportingGUCOptions(void);
 extern void ReportChangedGUCOptions(void);