From cac77be465755ff587d692c60fce6c6959d3f015 Mon Sep 17 00:00:00 2001
From: Andrey Borodin <amborodin@acm.org>
Date: Fri, 23 Jul 2021 14:04:56 +0500
Subject: [PATCH] Improve error reporting of ReadPageInternal()

Currently from time to time error "no record found" happens.
This is shouldn't happen error, yet it is observed. This commit
improves errormsg reported in this case.
---
 src/backend/access/transam/xlogreader.c | 24 ++++++++++++++++++++++++
 1 file changed, 24 insertions(+)

diff --git a/src/backend/access/transam/xlogreader.c b/src/backend/access/transam/xlogreader.c
index 42738eb940..926255f6ef 100644
--- a/src/backend/access/transam/xlogreader.c
+++ b/src/backend/access/transam/xlogreader.c
@@ -609,14 +609,22 @@ ReadPageInternal(XLogReaderState *state, XLogRecPtr pageptr, int reqLen)
 										   state->currRecPtr,
 										   state->readBuf);
 		if (readLen < 0)
+		{
+			report_invalid_record(state, "Attempt to read page of next segment failed at %X/%X",
+							  (uint32) (pageptr >> 32), (uint32) pageptr);
 			goto err;
+		}
 
 		/* we can be sure to have enough WAL available, we scrolled back */
 		Assert(readLen == XLOG_BLCKSZ);
 
 		if (!XLogReaderValidatePageHeader(state, targetSegmentPtr,
 										  state->readBuf))
+		{
+			report_invalid_record(state, "Invalid page header at %X/%X",
+							  (uint32) (pageptr >> 32), (uint32) pageptr);
 			goto err;
+		}
 	}
 
 	/*
@@ -627,13 +635,21 @@ ReadPageInternal(XLogReaderState *state, XLogRecPtr pageptr, int reqLen)
 									   state->currRecPtr,
 									   state->readBuf);
 	if (readLen < 0)
+	{
+		report_invalid_record(state, "Attempt to read page failed at %X/%X",
+							(uint32) (pageptr >> 32), (uint32) pageptr);
 		goto err;
+	}
 
 	Assert(readLen <= XLOG_BLCKSZ);
 
 	/* Do we have enough data to check the header length? */
 	if (readLen <= SizeOfXLogShortPHD)
+	{
+		report_invalid_record(state, "Unable to read short header of %d bytes at %X/%X", readLen,
+							(uint32) (pageptr >> 32), (uint32) pageptr);
 		goto err;
+	}
 
 	Assert(readLen >= reqLen);
 
@@ -646,14 +662,22 @@ ReadPageInternal(XLogReaderState *state, XLogRecPtr pageptr, int reqLen)
 										   state->currRecPtr,
 										   state->readBuf);
 		if (readLen < 0)
+		{
+			report_invalid_record(state, "Unable to read long header of %d bytes at %X/%X", readLen,
+								(uint32) (pageptr >> 32), (uint32) pageptr);
 			goto err;
+		}
 	}
 
 	/*
 	 * Now that we know we have the full header, validate it.
 	 */
 	if (!XLogReaderValidatePageHeader(state, pageptr, (char *) hdr))
+	{
+		report_invalid_record(state, "Invalid full page header at %X/%X",
+							(uint32) (pageptr >> 32), (uint32) pageptr);
 		goto err;
+	}
 
 	/* update read state information */
 	state->seg.ws_segno = targetSegNo;
-- 
2.24.3 (Apple Git-128)

