diff --git a/src/backend/commands/vacuumparallel.c b/src/backend/commands/vacuumparallel.c
index 70364c0292e..8e33e9d8cbb 100644
--- a/src/backend/commands/vacuumparallel.c
+++ b/src/backend/commands/vacuumparallel.c
@@ -734,6 +734,12 @@ parallel_vacuum_propagate_shared_delay_params(void)
 	 * know that they should re-read shared cost params.
 	 */
 	pg_atomic_fetch_add_u32(&pv_shared_cost_params->generation, 1);
+
+	elog(DEBUG2,
+		 "parallel autovacuum leader propagated cost params: cost_limit=%d, cost_delay=%g, cost_page_miss=%d, cost_page_dirty=%d, cost_page_hit=%d, track_cost_delay_timing=%s",
+		 vacuum_cost_limit, vacuum_cost_delay,
+		 VacuumCostPageMiss, VacuumCostPageDirty, VacuumCostPageHit,
+		 track_cost_delay_timing ? "yes" : "no");
 }
 
 /*
@@ -768,8 +774,6 @@ parallel_vacuum_refresh_cost_params(void)
 	}
 
 	parallel_vacuum_propagate_shared_delay_params();
-
-	INJECTION_POINT("parallel-autovacuum-leader-cost-updated", NULL);
 }
 
 /*
@@ -860,7 +864,6 @@ parallel_vacuum_process_all_indexes(ParallelVacuumState *pvs, int num_index_scan
 {
 	int			nworkers;
 	PVIndVacStatus new_status;
-	bool		leader_participates = true;
 
 	Assert(!IsParallelWorker());
 
@@ -974,17 +977,6 @@ parallel_vacuum_process_all_indexes(ParallelVacuumState *pvs, int num_index_scan
 							pvs->pcxt->nworkers_launched, nworkers)));
 	}
 
-#ifdef USE_INJECTION_POINTS
-
-	/*
-	 * Used by tests to leave all parallel-safe indexes to the parallel
-	 * workers, so that the leader waits for them to finish.
-	 */
-	if (nworkers > 0 && pvs->pcxt->nworkers_launched > 0 &&
-		IS_INJECTION_POINT_ATTACHED("parallel-vacuum-leader-skip-safe-indexes"))
-		leader_participates = false;
-#endif
-
 	/* Vacuum the indexes that can be processed by only leader process */
 	parallel_vacuum_process_unsafe_indexes(pvs);
 
@@ -992,8 +984,7 @@ parallel_vacuum_process_all_indexes(ParallelVacuumState *pvs, int num_index_scan
 	 * Join as a parallel worker.  The leader vacuums alone processes all
 	 * parallel-safe indexes in the case where no workers are launched.
 	 */
-	if (leader_participates)
-		parallel_vacuum_process_safe_indexes(pvs);
+	parallel_vacuum_process_safe_indexes(pvs);
 
 	/*
 	 * Next, accumulate buffer and WAL usage.  (This must wait for the workers
@@ -1070,11 +1061,6 @@ parallel_vacuum_process_safe_indexes(ParallelVacuumState *pvs)
 		if (!indstats->parallel_workers_can_process)
 			continue;
 
-#ifdef USE_INJECTION_POINTS
-		if (IsParallelWorker())
-			INJECTION_POINT("parallel-vacuum-worker-before-index", NULL);
-#endif
-
 		/* Do vacuum or cleanup of the index */
 		parallel_vacuum_process_one_index(pvs, pvs->indrels[idx], indstats);
 	}
@@ -1310,6 +1296,8 @@ parallel_vacuum_main(dsm_segment *seg, shm_toc *toc)
 
 	elog(DEBUG1, "starting parallel vacuum worker");
 
+	INJECTION_POINT("parallel-vacuum-worker-start", NULL);
+
 	shared = (PVShared *) shm_toc_lookup(toc, PARALLEL_VACUUM_KEY_SHARED, false);
 
 	/* Set debug_query_string for individual workers */
diff --git a/src/test/modules/test_autovacuum/t/001_parallel_autovacuum.pl b/src/test/modules/test_autovacuum/t/001_parallel_autovacuum.pl
index 39960f6be74..a16df331fc6 100644
--- a/src/test/modules/test_autovacuum/t/001_parallel_autovacuum.pl
+++ b/src/test/modules/test_autovacuum/t/001_parallel_autovacuum.pl
@@ -263,50 +263,9 @@ ok( $node->poll_query_until(
 	}),
 	'second autovacuum worker finished');
 
-# Start autovacuum on test_autovac with its parallel worker held before its
-# first index, and the leader leaving all indexes to the parallel worker.
-# Returns once the leader waits for the parallel worker to finish.
-sub start_leader_waiting
-{
-	my ($node) = @_;
-
-	$node->safe_psql(
-		'postgres', q{
-		SELECT injection_points_attach('parallel-vacuum-worker-before-index', 'wait');
-		SELECT injection_points_attach('parallel-vacuum-leader-skip-safe-indexes', 'notice');
-		ALTER TABLE test_autovac SET (autovacuum_enabled = true);
-	});
-	$node->wait_for_event('parallel worker',
-		'parallel-vacuum-worker-before-index');
-	ok( $node->poll_query_until(
-			'postgres', q{
-			SELECT count(*) > 0 FROM pg_stat_activity
-			WHERE backend_type = 'autovacuum worker'
-			  AND wait_event = 'ParallelFinish'
-		}),
-		'autovacuum leader waits for its parallel worker');
-}
-
-# Release the parallel worker held by start_leader_waiting().
-sub release_parallel_worker
-{
-	my ($node) = @_;
-
-	$node->safe_psql(
-		'postgres', q{
-		SELECT injection_points_detach('parallel-vacuum-leader-skip-safe-indexes');
-		SELECT injection_points_detach('parallel-vacuum-worker-before-index');
-		SELECT injection_points_wakeup('parallel-vacuum-worker-before-index');
-	});
-}
-
 # Test 4:
 # Check whether a config reload is serviced while the autovacuum leader waits
 # for its parallel worker.
-my $postgresoid = $node->safe_psql('postgres',
-	"SELECT oid FROM pg_database WHERE datname = 'postgres'");
-my $testautovacid =
-  $node->safe_psql('postgres', "SELECT 'test_autovac'::regclass::oid");
 
 $node->safe_psql(
 	'postgres', qq{
@@ -319,8 +278,19 @@ $node->safe_psql(
 prepare_for_next_test($node, 4);
 $log_offset = -s $node->logfile;
 
-start_leader_waiting($node);
+# Let an autovacuum worker process test_autovac with its parallel worker held
+# before the parallel worker reads the cost-based delay parameters.  The
+# leader then processes all indexes by itself and waits for the parallel
+# worker to finish.  Change the parameters only once the leader is waiting,
+# or it would pick up the change before reaching the code path under test.
+$node->safe_psql(
+	'postgres', q{
+SELECT injection_points_attach('parallel-vacuum-worker-start', 'wait');
+ALTER TABLE test_autovac SET (autovacuum_enabled = true);
+});
+$node->wait_for_event('autovacuum worker', 'ParallelFinish');
 
+# Update cost-based delay parameters.
 $node->safe_psql(
 	'postgres', qq{
 	ALTER SYSTEM SET autovacuum_vacuum_cost_limit = 800;
@@ -331,15 +301,26 @@ $node->safe_psql(
 	SELECT pg_reload_conf();
 });
 
-# The leader must process the reload before the parallel worker is released.
+# The parallel worker reads the parameters only once, when it starts, since
+# the leader has already processed all indexes.  So the leader must have
+# propagated the new parameters before the parallel worker is released.
 $node->wait_for_log(
-	qr/Autovacuum VacuumUpdateCosts\(db=$postgresoid, rel=$testautovacid, dobalance=yes, cost_limit=800, cost_delay=8 /,
+	qr/parallel autovacuum leader propagated cost params: cost_limit=800,/,
 	$log_offset);
 
-release_parallel_worker($node);
+# Release the parallel worker.  It reads the cost-based delay parameters the
+# leader has propagated as soon as it resumes.
+$node->safe_psql(
+	'postgres',
+	q{
+SELECT injection_points_detach('parallel-vacuum-worker-start');
+SELECT injection_points_wakeup('parallel-vacuum-worker-start');
+});
 $node->wait_for_log(
 	qr/parallel autovacuum worker updated cost params: cost_limit=800, cost_delay=8, cost_page_miss=11, cost_page_dirty=12, cost_page_hit=13/,
 	$log_offset);
+
+# Wait for the autovacuum on test_autovac to finish.
 $node->wait_for_log(
 	qr/automatic vacuum of table "postgres\.public\.test_autovac"/,
 	$log_offset);
@@ -363,47 +344,63 @@ $node->safe_psql('regress_db2', 'UPDATE filler SET id = id + 1');
 
 $log_offset = -s $node->logfile;
 
-start_leader_waiting($node);
+# As in Test 4, hold the parallel worker and wait for the leader to process
+# all indexes and wait for the parallel worker to finish.
+$node->safe_psql(
+	'postgres', q{
+SELECT injection_points_attach('parallel-vacuum-worker-start', 'wait');
+ALTER TABLE test_autovac SET (autovacuum_enabled = true);
+});
+$node->wait_for_event('autovacuum worker', 'ParallelFinish');
 
-# Hold the second worker, so that the balance stays at 2.  Attach the notice
-# before the rebalance, as the rebalance wakeup is the only thing that brings
-# the waiting leader to this point.
+# Hold the second worker, so that the number of autovacuum workers sharing
+# the cost limit stays at 2 until the parallel worker has read the
+# parameters.  Once the second worker finishes, the leader would propagate
+# the original cost limit again.
 $node->safe_psql(
 	'postgres', q{
-	SELECT injection_points_attach('autovacuum-worker-cost-balanced', 'wait');
-	SELECT injection_points_attach('parallel-autovacuum-leader-cost-updated', 'notice');
+   SELECT injection_points_attach('autovacuum-worker-cost-balanced', 'wait');
 });
 $node->safe_psql('regress_db2',
 	'ALTER TABLE filler SET (autovacuum_enabled = true)');
+
+# Wait for the second worker to update its cost parameters.  It has
+# recalculated the number of workers sharing the cost limit, now 2, and woken
+# up the leader.
 $node->wait_for_log(
 	qr/VacuumUpdateCosts\(db=$db2oid, rel=$filleroid, dobalance=yes, cost_limit=300,/,
 	$log_offset);
+
+# Likewise, the leader must propagate the rebalanced cost limit before the
+# parallel worker is released.
 $node->wait_for_log(
-	qr/notice triggered for injection point parallel-autovacuum-leader-cost-updated/,
+	qr/parallel autovacuum leader propagated cost params: cost_limit=300,/,
 	$log_offset);
-$node->safe_psql('postgres',
-	"SELECT injection_points_detach('parallel-autovacuum-leader-cost-updated')"
-);
 
-release_parallel_worker($node);
+# Release the parallel worker.  It reads the cost-based delay parameters the
+# leader has propagated as soon as it resumes.
+$node->safe_psql(
+	'postgres',
+	q{
+SELECT injection_points_detach('parallel-vacuum-worker-start');
+SELECT injection_points_wakeup('parallel-vacuum-worker-start');
+});
 $node->wait_for_log(
 	qr/parallel autovacuum worker updated cost params: cost_limit=300,/,
 	$log_offset);
 
+# Release the second worker.
 $node->safe_psql(
-	'postgres', q{
-	SELECT injection_points_wakeup('autovacuum-worker-cost-balanced');
-	SELECT injection_points_detach('autovacuum-worker-cost-balanced');
+	'postgres',
+	q{
+SELECT injection_points_detach('autovacuum-worker-cost-balanced');
+SELECT injection_points_wakeup('autovacuum-worker-cost-balanced');
 });
+
+# Wait for the autovacuum on test_autovac to finish.
 $node->wait_for_log(
 	qr/automatic vacuum of table "postgres\.public\.test_autovac"/,
 	$log_offset);
-ok( $node->poll_query_until(
-		'postgres', q{
-		SELECT count(*) = 0 FROM pg_stat_activity
-		WHERE backend_type = 'autovacuum worker' AND datname = 'regress_db2'
-	}),
-	'second autovacuum worker finished');
 ok(1, "cost rebalance is propagated while the leader waits for workers");
 
 $node->stop;
