From 0bd624d63b056205fda17a2d694d91db16468e3f Mon Sep 17 00:00:00 2001
From: Heikki Linnakangas <heikki.linnakangas@iki.fi>
Date: Mon, 24 Nov 2014 10:43:32 +0200
Subject: [PATCH] Distinguish XLOG_FPI records generated for hint-bit updates.

Add a new XLOG_FPI_FOR_HINT record type, and use that for full-page images
generated for hint bit updates, when checksums are enabled. The new record
type is replayed exactly the same as XLOG_FPI, but allows them to be tallied
separately e.g. in pg_xlogdump.
---
 src/backend/access/rmgrdesc/xlogdesc.c   |  5 ++++-
 src/backend/access/transam/xlog.c        | 18 +++++++++++-------
 src/backend/access/transam/xloginsert.c  |  2 +-
 src/backend/replication/logical/decode.c |  1 +
 src/include/catalog/pg_control.h         |  3 ++-
 5 files changed, 19 insertions(+), 10 deletions(-)

diff --git a/src/backend/access/rmgrdesc/xlogdesc.c b/src/backend/access/rmgrdesc/xlogdesc.c
index 4088ba99b7f..eba046d1fa9 100644
--- a/src/backend/access/rmgrdesc/xlogdesc.c
+++ b/src/backend/access/rmgrdesc/xlogdesc.c
@@ -74,7 +74,7 @@ xlog_desc(StringInfo buf, XLogReaderState *record)
 
 		appendStringInfo(buf, "%s", xlrec->rp_name);
 	}
-	else if (info == XLOG_FPI)
+	else if (info == XLOG_FPI || info == XLOG_FPI_FOR_HINT)
 	{
 		/* no further information to print */
 	}
@@ -170,6 +170,9 @@ xlog_identify(uint8 info)
 		case XLOG_FPI:
 			id = "FPI";
 			break;
+		case XLOG_FPI_FOR_HINT:
+			id = "FPI_FOR_HINT";
+			break;
 	}
 
 	return id;
diff --git a/src/backend/access/transam/xlog.c b/src/backend/access/transam/xlog.c
index 2059bbeda4a..8e712b793f3 100644
--- a/src/backend/access/transam/xlog.c
+++ b/src/backend/access/transam/xlog.c
@@ -8545,7 +8545,8 @@ xlog_redo(XLogReaderState *record)
 	XLogRecPtr	lsn = record->EndRecPtr;
 
 	/* in XLOG rmgr, backup blocks are only used by XLOG_FPI records */
-	Assert(!XLogRecHasAnyBlockRefs(record) || info == XLOG_FPI);
+	Assert(info == XLOG_FPI || info == XLOG_FPI_FOR_HINT ||
+		   !XLogRecHasAnyBlockRefs(record));
 
 	if (info == XLOG_NEXTOID)
 	{
@@ -8730,7 +8731,7 @@ xlog_redo(XLogReaderState *record)
 	{
 		/* nothing to do here */
 	}
-	else if (info == XLOG_FPI)
+	else if (info == XLOG_FPI || info == XLOG_FPI_FOR_HINT)
 	{
 		Buffer		buffer;
 
@@ -8739,12 +8740,15 @@ xlog_redo(XLogReaderState *record)
 		 * block. The block reference must include a full-page image -
 		 * otherwise there would be no point in this record.
 		 *
-		 * Since the only change in these backup block are hint bits, there
-		 * are no recovery conflicts generated.
+		 * No recovery conflicts are generated by these generic records - if a
+		 * resource manager needs to generate conflicts, it has to define a
+		 * separate WAL record type and redo routine.
 		 *
-		 * This also means there is no corresponding API call for this, so an
-		 * smgr implementation has no need to implement anything. Which means
-		 * nothing is needed in md.c etc
+		 * XLOG_FPI_FOR_HINT records are generated when a page needs to be
+		 * WAL- logged because of a hint bit update. They are only generated
+		 * when checksums are enabled. There is no difference in handling
+		 * XLOG_FPI and XLOG_FPI_FOR_HINT records, they use a different info
+		 * code just to distinguish them for statistics purposes.
 		 */
 		if (XLogReadBufferForRedo(record, 0, &buffer) != BLK_RESTORED)
 			elog(ERROR, "unexpected XLogReadBufferForRedo result when restoring backup block");
diff --git a/src/backend/access/transam/xloginsert.c b/src/backend/access/transam/xloginsert.c
index fe204313024..34e44e4f235 100644
--- a/src/backend/access/transam/xloginsert.c
+++ b/src/backend/access/transam/xloginsert.c
@@ -786,7 +786,7 @@ XLogSaveBufferForHint(Buffer buffer, bool buffer_std)
 		BufferGetTag(buffer, &rnode, &forkno, &blkno);
 		XLogRegisterBlock(0, &rnode, forkno, blkno, copied_buffer, flags);
 
-		recptr = XLogInsert(RM_XLOG_ID, XLOG_FPI);
+		recptr = XLogInsert(RM_XLOG_ID, XLOG_FPI_FOR_HINT);
 	}
 
 	return recptr;
diff --git a/src/backend/replication/logical/decode.c b/src/backend/replication/logical/decode.c
index 1c7dac38fc9..4e81322509f 100644
--- a/src/backend/replication/logical/decode.c
+++ b/src/backend/replication/logical/decode.c
@@ -170,6 +170,7 @@ DecodeXLogOp(LogicalDecodingContext *ctx, XLogRecordBuffer *buf)
 		case XLOG_PARAMETER_CHANGE:
 		case XLOG_RESTORE_POINT:
 		case XLOG_FPW_CHANGE:
+		case XLOG_FPI_FOR_HINT:
 		case XLOG_FPI:
 			break;
 		default:
diff --git a/src/include/catalog/pg_control.h b/src/include/catalog/pg_control.h
index ba79d253ae5..15f81e4a44d 100644
--- a/src/include/catalog/pg_control.h
+++ b/src/include/catalog/pg_control.h
@@ -67,7 +67,8 @@ typedef struct CheckPoint
 #define XLOG_RESTORE_POINT				0x70
 #define XLOG_FPW_CHANGE					0x80
 #define XLOG_END_OF_RECOVERY			0x90
-#define XLOG_FPI						0xA0
+#define XLOG_FPI_FOR_HINT				0xA0
+#define XLOG_FPI						0xB0
 
 
 /*
-- 
GitLab