From 7c8a5d3e99509a1e60abd8fc3d78fdd52b8ccefa Mon Sep 17 00:00:00 2001
From: Sami Imseih <samimseih.pg@gmail.com>
Date: Fri, 25 Sep 2026 15:06:58 +0000
Subject: [PATCH v2 1/1] Propagate track_cost_delay_timing to parallel
 autovacuum workers

1ff3180ca01 introduced parallel autovacuum and made sure the cost-based
delay parameters were propagated to the workers, but this did not include
track_cost_delay_timing, which is an oversight.  Workers therefore keep
the value they inherited at parallel start, and
pg_stat_progress_vacuum.delay_time ends up counting only the leader's
naps.  Throttling itself was not affected.

Fix this by adding the parameter to PVSharedCostParams, and extend the
parallel autovacuum test to cover it.  Also report any residual worker
delay time only when a worker has accumulated delay time to flush.
---
 src/backend/commands/vacuumparallel.c               | 13 +++++++++----
 .../test_autovacuum/t/001_parallel_autovacuum.pl    |  3 ++-
 2 files changed, 11 insertions(+), 5 deletions(-)

diff --git a/src/backend/commands/vacuumparallel.c b/src/backend/commands/vacuumparallel.c
index d4572861000..f07fe9e0b87 100644
--- a/src/backend/commands/vacuumparallel.c
+++ b/src/backend/commands/vacuumparallel.c
@@ -85,6 +85,7 @@ typedef struct PVSharedCostParams
 	int			cost_page_dirty;
 	int			cost_page_hit;
 	int			cost_page_miss;
+	bool		track_cost_delay_timing;
 } PVSharedCostParams;
 
 /*
@@ -643,6 +644,7 @@ parallel_vacuum_set_cost_parameters(PVSharedCostParams *params)
 	params->cost_page_dirty = VacuumCostPageDirty;
 	params->cost_page_hit = VacuumCostPageHit;
 	params->cost_page_miss = VacuumCostPageMiss;
+	params->track_cost_delay_timing = track_cost_delay_timing;
 }
 
 /*
@@ -675,6 +677,7 @@ parallel_vacuum_update_shared_delay_params(void)
 	VacuumCostPageDirty = pv_shared_cost_params->cost_page_dirty;
 	VacuumCostPageHit = pv_shared_cost_params->cost_page_hit;
 	VacuumCostPageMiss = pv_shared_cost_params->cost_page_miss;
+	track_cost_delay_timing = pv_shared_cost_params->track_cost_delay_timing;
 	SpinLockRelease(&pv_shared_cost_params->mutex);
 
 	VacuumUpdateCosts();
@@ -682,12 +685,13 @@ parallel_vacuum_update_shared_delay_params(void)
 	shared_params_generation_local = params_generation;
 
 	elog(DEBUG2,
-		 "parallel autovacuum worker updated cost params: cost_limit=%d, cost_delay=%g, cost_page_miss=%d, cost_page_dirty=%d, cost_page_hit=%d",
+		 "parallel autovacuum worker updated 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);
+		 VacuumCostPageHit,
+		 track_cost_delay_timing ? "on" : "off");
 }
 
 /*
@@ -714,7 +718,8 @@ parallel_vacuum_propagate_shared_delay_params(void)
 		vacuum_cost_limit == pv_shared_cost_params->cost_limit &&
 		VacuumCostPageDirty == pv_shared_cost_params->cost_page_dirty &&
 		VacuumCostPageHit == pv_shared_cost_params->cost_page_hit &&
-		VacuumCostPageMiss == pv_shared_cost_params->cost_page_miss)
+		VacuumCostPageMiss == pv_shared_cost_params->cost_page_miss &&
+		track_cost_delay_timing == pv_shared_cost_params->track_cost_delay_timing)
 		return;
 
 	/* Update the shared delay parameters */
@@ -1330,7 +1335,7 @@ parallel_vacuum_main(dsm_segment *seg, shm_toc *toc)
 						  &wal_usage[ParallelWorkerNumber]);
 
 	/* Report any remaining cost-based vacuum delay time */
-	if (track_cost_delay_timing)
+	if (parallel_vacuum_worker_delay_ns > 0)
 		pgstat_progress_parallel_incr_param(PROGRESS_VACUUM_DELAY_TIME,
 											parallel_vacuum_worker_delay_ns);
 
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 33c86bbdc94..3c54e2cad14 100644
--- a/src/test/modules/test_autovacuum/t/001_parallel_autovacuum.pl
+++ b/src/test/modules/test_autovacuum/t/001_parallel_autovacuum.pl
@@ -149,6 +149,7 @@ $node->safe_psql(
 	ALTER SYSTEM SET vacuum_cost_page_miss = 10;
 	ALTER SYSTEM SET vacuum_cost_page_dirty = 10;
 	ALTER SYSTEM SET vacuum_cost_page_hit = 10;
+	ALTER SYSTEM SET track_cost_delay_timing = on;
 	SELECT pg_reload_conf();
 });
 
@@ -163,7 +164,7 @@ $node->safe_psql(
 # Check whether parallel worker successfully updated all parameters during
 # index processing.
 $node->wait_for_log(
-	qr/parallel autovacuum worker updated cost params: cost_limit=500, cost_delay=5, cost_page_miss=10, cost_page_dirty=10, cost_page_hit=10/,
+	qr/parallel autovacuum worker updated cost params: cost_limit=500, cost_delay=5, cost_page_miss=10, cost_page_dirty=10, cost_page_hit=10, track_cost_delay_timing=on/,
 	$log_offset);
 
 # Cleanup
-- 
2.50.1

