From 2a45234fca1ba77cd0080d366fdf879ef9165d9f Mon Sep 17 00:00:00 2001
From: Jelte Fennema-Nio <postgres@jeltef.nl>
Date: Sun, 25 Jan 2026 15:29:18 +0100
Subject: [PATCH v7 2/2] fixup! Add storage I/O tracking to 'BUFFERS' option

---
 src/backend/commands/explain.c    |  6 +++---
 src/backend/commands/prepare.c    |  4 +++-
 src/backend/executor/instrument.c | 17 +++++++++++------
 3 files changed, 17 insertions(+), 10 deletions(-)

diff --git a/src/backend/commands/explain.c b/src/backend/commands/explain.c
index 7902866da7b..8f668ee46c7 100644
--- a/src/backend/commands/explain.c
+++ b/src/backend/commands/explain.c
@@ -4376,8 +4376,8 @@ show_storageio_usage(ExplainState *es, const StorageIOUsage *usage)
 
 		ExplainIndentText(es);
 		appendStringInfoString(es->str, "Storage I/O:");
-		appendStringInfo(es->str, " read=%ld times", (long) usage->inblock);
-		appendStringInfo(es->str, " write=%ld times", (long) usage->outblock);
+		appendStringInfo(es->str, " read=%ld", (long) usage->inblock);
+		appendStringInfo(es->str, " write=%ld", (long) usage->outblock);
 
 		appendStringInfoChar(es->str, '\n');
 	}
@@ -4385,7 +4385,7 @@ show_storageio_usage(ExplainState *es, const StorageIOUsage *usage)
 	{
 		ExplainPropertyInteger("Storage I/O Read", NULL,
 							   usage->inblock, es);
-		ExplainPropertyInteger("Storage I/O Read", NULL,
+		ExplainPropertyInteger("Storage I/O Write", NULL,
 							   usage->outblock, es);
 	}
 }
diff --git a/src/backend/commands/prepare.c b/src/backend/commands/prepare.c
index 08bf28d2078..7c38f1393fd 100644
--- a/src/backend/commands/prepare.c
+++ b/src/backend/commands/prepare.c
@@ -648,12 +648,14 @@ ExplainExecuteQuery(ExecuteStmt *execstmt, IntoClause *into, ExplainState *es,
 		MemoryContextMemConsumed(planner_ctx, &mem_counters);
 	}
 
-	/* calc differences of buffer counters. */
+	/* calc differences of buffer and storage I/O counters. */
 	if (es->buffers)
 	{
 		memset(&bufusage, 0, sizeof(BufferUsage));
 		BufferUsageAccumDiff(&bufusage, &pgBufferUsage, &bufusage_start);
+
 		GetStorageIOUsage(&storageio);
+		StorageIOUsageDiff(&storageio, &storageio_start);
 	}
 
 	plan_list = cplan->stmt_list;
diff --git a/src/backend/executor/instrument.c b/src/backend/executor/instrument.c
index 316671c3ced..902e7e54b57 100644
--- a/src/backend/executor/instrument.c
+++ b/src/backend/executor/instrument.c
@@ -22,8 +22,13 @@
 BufferUsage pgBufferUsage;
 static BufferUsage save_pgBufferUsage;
 
-StorageIOUsage pgStorageIOUsageParallel;	/* only count parallel workers'
-											 * usage */
+/*
+ * Accumulates the I/O usage send by parallel workers to the main
+ * process. This does not contain the I/O from the main backend process
+ * itself because the kernel tracks that instead of us.
+ */
+StorageIOUsage pgStorageIOUsageParallel;
+
 WalUsage	pgWalUsage;
 static WalUsage save_pgWalUsage;
 
@@ -224,10 +229,6 @@ InstrEndParallelQuery(BufferUsage *bufusage, StorageIOUsage *storageiousage, Wal
 
 		memset(storageiousage, 0, sizeof(StorageIOUsage));
 		StorageIOUsageAccumDiff(storageiousage, &storageiousage_end, storageiousage_start);
-
-		ereport(DEBUG1,
-				(errmsg("Parallel worker's storage I/O times: inblock:%ld outblock:%ld",
-						storageiousage->inblock, storageiousage->outblock)));
 	}
 	memset(walusage, 0, sizeof(WalUsage));
 	WalUsageAccumDiff(walusage, &pgWalUsage, &save_pgWalUsage);
@@ -331,7 +332,11 @@ GetStorageIOUsage(StorageIOUsage *usage)
 	 * I/O, don't get the I/O usage statistics when AIO worker is enabled.
 	 */
 	if (pgaio_workers_enabled())
+	{
+		usage->inblock = 0;
+		usage->outblock = 0;
 		return;
+	}
 
 	if (getrusage(RUSAGE_SELF, &rusage))
 	{
-- 
2.52.0

