From 02112c6faa66ef484ed8efc5374f7a87ed27711b Mon Sep 17 00:00:00 2001
From: Maxim Orlov <orlovmg@gmail.com>
Date: Fri, 20 Feb 2026 11:22:18 +0300
Subject: [PATCH v1] Make SlruReportIOError accept 64-bit values

Expanding SLRU segment values to 64 bits requires an extended format
for an error output in SlruReportIOError. Previously, the values were
implicitly converted to 32 bits without preserving the epoch.
---
 src/backend/access/transam/slru.c | 33 ++++++++++++++++++++-----------
 src/include/access/slru.h         |  2 +-
 2 files changed, 23 insertions(+), 12 deletions(-)

diff --git a/src/backend/access/transam/slru.c b/src/backend/access/transam/slru.c
index 549c7e3e64b..ab4018384f9 100644
--- a/src/backend/access/transam/slru.c
+++ b/src/backend/access/transam/slru.c
@@ -181,7 +181,7 @@ static void SlruInternalWritePage(SlruCtl ctl, int slotno, SlruWriteAll fdata);
 static bool SlruPhysicalReadPage(SlruCtl ctl, int64 pageno, int slotno);
 static bool SlruPhysicalWritePage(SlruCtl ctl, int64 pageno, int slotno,
 								  SlruWriteAll fdata);
-static void SlruReportIOError(SlruCtl ctl, int64 pageno, TransactionId xid);
+static void SlruReportIOError(SlruCtl ctl, int64 pageno, uint64 value);
 static int	SlruSelectLRUPage(SlruCtl ctl, int64 pageno);
 
 static bool SlruScanDirCbDeleteCutoff(SlruCtl ctl, char *filename,
@@ -525,7 +525,7 @@ SimpleLruWaitIO(SlruCtl ctl, int slotno)
  */
 int
 SimpleLruReadPage(SlruCtl ctl, int64 pageno, bool write_ok,
-				  TransactionId xid)
+				  uint64 xid)
 {
 	SlruShared	shared = ctl->shared;
 	LWLock	   *banklock = SimpleLruGetBankLock(ctl, pageno);
@@ -1070,12 +1070,15 @@ SlruPhysicalWritePage(SlruCtl ctl, int64 pageno, int slotno, SlruWriteAll fdata)
  * SlruPhysicalWritePage.  Call this after cleaning up shared-memory state.
  */
 static void
-SlruReportIOError(SlruCtl ctl, int64 pageno, TransactionId xid)
+SlruReportIOError(SlruCtl ctl, int64 pageno, uint64 value)
 {
 	int64		segno = pageno / SLRU_PAGES_PER_SEGMENT;
 	int			rpageno = pageno % SLRU_PAGES_PER_SEGMENT;
 	int			offset = rpageno * BLCKSZ;
 	char		path[MAXPGPATH];
+	FullTransactionId	fxid = FullTransactionIdFromU64(value);
+	TransactionId		xid = XidFromFullTransactionId(fxid);
+	uint32				epoch = EpochFromFullTransactionId(fxid);
 
 	SlruFileName(ctl, path, segno);
 	errno = slru_errno;
@@ -1084,13 +1087,15 @@ SlruReportIOError(SlruCtl ctl, int64 pageno, TransactionId xid)
 		case SLRU_OPEN_FAILED:
 			ereport(ERROR,
 					(errcode_for_file_access(),
-					 errmsg("could not access status of transaction %u", xid),
+					 errmsg("could not access status of transaction %u:%u",
+							epoch, xid),
 					 errdetail("Could not open file \"%s\": %m.", path)));
 			break;
 		case SLRU_SEEK_FAILED:
 			ereport(ERROR,
 					(errcode_for_file_access(),
-					 errmsg("could not access status of transaction %u", xid),
+					 errmsg("could not access status of transaction %u:%u",
+							epoch, xid),
 					 errdetail("Could not seek in file \"%s\" to offset %d: %m.",
 							   path, offset)));
 			break;
@@ -1098,38 +1103,44 @@ SlruReportIOError(SlruCtl ctl, int64 pageno, TransactionId xid)
 			if (errno)
 				ereport(ERROR,
 						(errcode_for_file_access(),
-						 errmsg("could not access status of transaction %u", xid),
+						 errmsg("could not access status of transaction %u:%u",
+								epoch, xid),
 						 errdetail("Could not read from file \"%s\" at offset %d: %m.",
 								   path, offset)));
 			else
 				ereport(ERROR,
-						(errmsg("could not access status of transaction %u", xid),
+						(errmsg("could not access status of transaction %u:%u",
+								epoch, xid),
 						 errdetail("Could not read from file \"%s\" at offset %d: read too few bytes.", path, offset)));
 			break;
 		case SLRU_WRITE_FAILED:
 			if (errno)
 				ereport(ERROR,
 						(errcode_for_file_access(),
-						 errmsg("could not access status of transaction %u", xid),
+						 errmsg("could not access status of transaction %u:%u",
+								epoch, xid),
 						 errdetail("Could not write to file \"%s\" at offset %d: %m.",
 								   path, offset)));
 			else
 				ereport(ERROR,
-						(errmsg("could not access status of transaction %u", xid),
+						(errmsg("could not access status of transaction %u:%u",
+								epoch, xid),
 						 errdetail("Could not write to file \"%s\" at offset %d: wrote too few bytes.",
 								   path, offset)));
 			break;
 		case SLRU_FSYNC_FAILED:
 			ereport(data_sync_elevel(ERROR),
 					(errcode_for_file_access(),
-					 errmsg("could not access status of transaction %u", xid),
+					 errmsg("could not access status of transaction %u:%u",
+							epoch, xid),
 					 errdetail("Could not fsync file \"%s\": %m.",
 							   path)));
 			break;
 		case SLRU_CLOSE_FAILED:
 			ereport(ERROR,
 					(errcode_for_file_access(),
-					 errmsg("could not access status of transaction %u", xid),
+					 errmsg("could not access status of transaction %u:%u",
+							epoch, xid),
 					 errdetail("Could not close file \"%s\": %m.",
 							   path)));
 			break;
diff --git a/src/include/access/slru.h b/src/include/access/slru.h
index 4cb8f478fce..ec5c194e7ac 100644
--- a/src/include/access/slru.h
+++ b/src/include/access/slru.h
@@ -174,7 +174,7 @@ extern void SimpleLruInit(SlruCtl ctl, const char *name, int nslots, int nlsns,
 extern int	SimpleLruZeroPage(SlruCtl ctl, int64 pageno);
 extern void SimpleLruZeroAndWritePage(SlruCtl ctl, int64 pageno);
 extern int	SimpleLruReadPage(SlruCtl ctl, int64 pageno, bool write_ok,
-							  TransactionId xid);
+							  uint64 xid);
 extern int	SimpleLruReadPage_ReadOnly(SlruCtl ctl, int64 pageno,
 									   TransactionId xid);
 extern void SimpleLruWritePage(SlruCtl ctl, int slotno);
-- 
2.43.0

