From bb311fd3dd43cad99c4bd4ef4434a8f934641849 Mon Sep 17 00:00:00 2001
From: Baji Shaik <baji.pgdev@gmail.com>
Date: Mon, 22 Jun 2026 14:27:55 -0500
Subject: [PATCH] Warn when io_min_workers exceeds io_max_workers

When io_min_workers is set higher than io_max_workers, the minimum
has no effect since the pool will never grow past io_max_workers.
Previously this was silently accepted, which could confuse users
expecting at least io_min_workers workers to always be running.

Add check_io_worker_gucs() that emits a WARNING when
io_min_workers > io_max_workers. The check runs in IO worker 0
at startup and after each configuration reload.
---
 src/backend/storage/aio/method_worker.c | 24 ++++++++++++++++++++++++
 1 file changed, 24 insertions(+)

diff --git a/src/backend/storage/aio/method_worker.c b/src/backend/storage/aio/method_worker.c
index 63e34d66690..9befe8fbd40 100644
--- a/src/backend/storage/aio/method_worker.c
+++ b/src/backend/storage/aio/method_worker.c
@@ -662,6 +662,22 @@ pgaio_worker_can_timeout(void)
 	return true;
 }
 
+/*
+ * Emit a WARNING if io_min_workers > io_max_workers, since the worker
+ * pool will never exceed io_max_workers regardless of the minimum setting.
+ */
+static void
+check_io_worker_gucs(void)
+{
+	if (io_min_workers > io_max_workers)
+		ereport(WARNING,
+				(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
+				 errmsg("\"io_min_workers\" (%d) should be less than or equal to \"io_max_workers\" (%d)",
+						io_min_workers, io_max_workers),
+				 errdetail("The I/O worker pool will not exceed \"io_max_workers\" (%d) workers.",
+						   io_max_workers)));
+}
+
 void
 IoWorkerMain(const void *startup_data, size_t startup_data_len)
 {
@@ -694,6 +710,10 @@ IoWorkerMain(const void *startup_data, size_t startup_data_len)
 	/* also registers a shutdown callback to unregister */
 	pgaio_worker_register();
 
+	/* Check for contradictory min/max worker configuration at startup. */
+	if (MyIoWorkerId == 0)
+		check_io_worker_gucs();
+
 	sprintf(cmd, "%d", MyIoWorkerId);
 	set_ps_display(cmd);
 
@@ -1014,6 +1034,10 @@ IoWorkerMain(const void *startup_data, size_t startup_data_len)
 			ConfigReloadPending = false;
 			ProcessConfigFile(PGC_SIGHUP);
 
+			/* Re-check after reload in case settings changed. */
+			if (MyIoWorkerId == 0)
+				check_io_worker_gucs();
+
 			/* If io_max_workers has been decreased, exit highest first. */
 			if (MyIoWorkerId >= io_max_workers)
 				break;
-- 
2.50.1 (Apple Git-155)

