From adc40191fb39bea3ae4d02d5573f50144844e94d Mon Sep 17 00:00:00 2001
From: Lakshmi N <lakshmin.jhs@gmail.com>
Date: Tue, 24 Mar 2026 01:23:24 -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 | 19 +++++++++++++++++++
 src/backend/access/transam/xlogrecovery.c   |  2 ++
 src/include/access/xlogprefetcher.h         |  2 ++
 3 files changed, 23 insertions(+)

diff --git a/src/backend/access/transam/xlogprefetcher.c b/src/backend/access/transam/xlogprefetcher.c
index c235eca7c51..49acb36af1c 100644
--- a/src/backend/access/transam/xlogprefetcher.c
+++ b/src/backend/access/transam/xlogprefetcher.c
@@ -335,6 +335,25 @@ 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: prefetch=%lu, hit=%lu, skip_init=%lu, skip_new=%lu, skip_fpw=%lu, skip_rep=%lu",
+		 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..742cb90da9b 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..a862924c895 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);
@@ -52,4 +53,5 @@ extern XLogRecord *XLogPrefetcherReadRecord(XLogPrefetcher *prefetcher,
 
 extern void XLogPrefetcherComputeStats(XLogPrefetcher *prefetcher);
 
+
 #endif
-- 
2.43.0

