From 64c96c20bb7345aad3dc6d3a1c2e9410b47ffdee Mon Sep 17 00:00:00 2001
From: Lakshmi N <lakshmin.jhs@gmail.com>
Date: Thu, 26 Mar 2026 01:02:57 -0700
Subject: [PATCH] xlogprefetcher: Log prefetch statistics at end of recovery

Add XLogPrefetchLogStats(), which emits a LOG message summarising the
prefetch counters (prefetch, hit, skip_init, skip_new, skip_fpw,
skip_rep) accumulated during recovery. The function is called from
PerformWalRecovery() immediately after the "redo done" message, giving
operators visibility into how effective WAL prefetching was over the
course of the recovery session.

No-op when recovery_prefetch = off.
---
 src/backend/access/transam/xlogprefetcher.c | 25 +++++++++++++++++++++
 src/backend/access/transam/xlogrecovery.c   |  2 ++
 src/include/access/xlogprefetcher.h         |  1 +
 3 files changed, 28 insertions(+)

diff --git a/src/backend/access/transam/xlogprefetcher.c b/src/backend/access/transam/xlogprefetcher.c
index c235eca7c51..879e6591c20 100644
--- a/src/backend/access/transam/xlogprefetcher.c
+++ b/src/backend/access/transam/xlogprefetcher.c
@@ -335,6 +335,31 @@ XLogPrefetchShmemInit(void)
 	}
 }
 
+/*
+ * Log a summary of the XLogPrefetcher stats. Intended to be called
+ * at the end of recovery or when a standby is promoted.
+ */
+void
+XLogPrefetchLogStats(void)
+{
+	if (recovery_prefetch == RECOVERY_PREFETCH_OFF)
+		return;
+
+	elog(LOG,
+		"redo prefetch stats: prefetched %lu blocks, "
+		"skipped (%lu in the buffer pool, "
+		"%lu zero-initialized, "
+		"%lu non-existent, "
+		"%lu full page image, "
+		"%lu recently prefetched)",
+		pg_atomic_read_u64(&SharedStats->prefetch),
+		pg_atomic_read_u64(&SharedStats->hit),
+		pg_atomic_read_u64(&SharedStats->skip_init),
+		pg_atomic_read_u64(&SharedStats->skip_new),
+		pg_atomic_read_u64(&SharedStats->skip_fpw),
+		pg_atomic_read_u64(&SharedStats->skip_rep));
+}
+
 /*
  * Called when any GUC is changed that affects prefetching.
  */
diff --git a/src/backend/access/transam/xlogrecovery.c b/src/backend/access/transam/xlogrecovery.c
index 6d2c4a86b96..7e5482fd976 100644
--- a/src/backend/access/transam/xlogrecovery.c
+++ b/src/backend/access/transam/xlogrecovery.c
@@ -1845,6 +1845,8 @@ PerformWalRecovery(void)
 				errmsg("redo done at %X/%08X system usage: %s",
 					   LSN_FORMAT_ARGS(xlogreader->ReadRecPtr),
 					   pg_rusage_show(&ru0)));
+
+		XLogPrefetchLogStats();
 		xtime = GetLatestXTime();
 		if (xtime)
 			ereport(LOG,
diff --git a/src/include/access/xlogprefetcher.h b/src/include/access/xlogprefetcher.h
index 7ec40c4b78b..5f9f48980cd 100644
--- a/src/include/access/xlogprefetcher.h
+++ b/src/include/access/xlogprefetcher.h
@@ -37,6 +37,7 @@ extern void XLogPrefetchReconfigure(void);
 extern size_t XLogPrefetchShmemSize(void);
 extern void XLogPrefetchShmemInit(void);
 
+extern void XLogPrefetchLogStats(void);
 extern void XLogPrefetchResetStats(void);
 
 extern XLogPrefetcher *XLogPrefetcherAllocate(XLogReaderState *reader);
-- 
2.43.0

