From 12add30b7c0062a13431edbc3f676840edc442a2 Mon Sep 17 00:00:00 2001
From: Matthias van de Meent <boekewurm+postgres@gmail.com>
Date: Fri, 9 Sep 2022 15:38:55 +0200
Subject: [PATCH v2 1/2] Move rmgr-specific flags out of xl_info into new uint8
 xl_rminfo field.

This field doens't use extra data as it is located in the previously 2-byte
alignment padding in the xlog header behind xl_rmid.

The field is used to allow redo managers more bits for their own use without
growing the xlog record size.
---
 contrib/pg_walinspect/pg_walinspect.c        |  4 +-
 src/backend/access/brin/brin_pageops.c       | 16 +++---
 src/backend/access/brin/brin_xlog.c          |  8 +--
 src/backend/access/gin/ginxlog.c             |  6 +--
 src/backend/access/gist/gistxlog.c           |  6 +--
 src/backend/access/hash/hash_xlog.c          |  6 +--
 src/backend/access/heap/heapam.c             | 40 +++++++--------
 src/backend/access/nbtree/nbtinsert.c        | 18 +++----
 src/backend/access/nbtree/nbtpage.c          |  8 +--
 src/backend/access/nbtree/nbtxlog.c          | 10 ++--
 src/backend/access/rmgrdesc/brindesc.c       | 20 ++++----
 src/backend/access/rmgrdesc/clogdesc.c       | 10 ++--
 src/backend/access/rmgrdesc/committsdesc.c   | 10 ++--
 src/backend/access/rmgrdesc/dbasedesc.c      | 12 ++---
 src/backend/access/rmgrdesc/genericdesc.c    |  2 +-
 src/backend/access/rmgrdesc/gindesc.c        |  8 +--
 src/backend/access/rmgrdesc/gistdesc.c       |  8 +--
 src/backend/access/rmgrdesc/hashdesc.c       |  8 +--
 src/backend/access/rmgrdesc/heapdesc.c       | 46 ++++++++---------
 src/backend/access/rmgrdesc/logicalmsgdesc.c |  8 +--
 src/backend/access/rmgrdesc/mxactdesc.c      | 14 ++---
 src/backend/access/rmgrdesc/nbtdesc.c        |  8 +--
 src/backend/access/rmgrdesc/relmapdesc.c     |  8 +--
 src/backend/access/rmgrdesc/replorigindesc.c |  8 +--
 src/backend/access/rmgrdesc/seqdesc.c        |  8 +--
 src/backend/access/rmgrdesc/smgrdesc.c       | 10 ++--
 src/backend/access/rmgrdesc/spgdesc.c        |  8 +--
 src/backend/access/rmgrdesc/standbydesc.c    | 12 ++---
 src/backend/access/rmgrdesc/tblspcdesc.c     | 10 ++--
 src/backend/access/rmgrdesc/xactdesc.c       | 34 ++++++------
 src/backend/access/rmgrdesc/xlogdesc.c       | 28 +++++-----
 src/backend/access/spgist/spgxlog.c          |  6 +--
 src/backend/access/transam/clog.c            |  8 +--
 src/backend/access/transam/commit_ts.c       |  8 +--
 src/backend/access/transam/multixact.c       | 48 ++++++++---------
 src/backend/access/transam/twophase.c        |  2 +-
 src/backend/access/transam/xact.c            | 36 +++++++------
 src/backend/access/transam/xlog.c            | 34 ++++++------
 src/backend/access/transam/xloginsert.c      | 31 ++++++++---
 src/backend/access/transam/xlogprefetcher.c  |  2 +-
 src/backend/access/transam/xlogreader.c      |  2 +-
 src/backend/access/transam/xlogrecovery.c    | 54 ++++++++++----------
 src/backend/access/transam/xlogstats.c       |  2 +-
 src/backend/catalog/storage.c                | 15 +++---
 src/backend/commands/dbcommands.c            | 30 ++++++-----
 src/backend/commands/sequence.c              |  6 +--
 src/backend/commands/tablespace.c            |  8 +--
 src/backend/postmaster/autovacuum.c          |  4 +-
 src/backend/replication/logical/decode.c     | 38 +++++++-------
 src/backend/replication/logical/message.c    |  6 +--
 src/backend/replication/logical/origin.c     |  6 +--
 src/backend/storage/ipc/standby.c            | 10 ++--
 src/backend/utils/cache/relmapper.c          |  6 +--
 src/bin/pg_resetwal/pg_resetwal.c            |  2 +-
 src/bin/pg_rewind/parsexlog.c                | 10 ++--
 src/bin/pg_waldump/pg_waldump.c              |  6 +--
 src/include/access/brin_xlog.h               |  2 +-
 src/include/access/clog.h                    |  2 +-
 src/include/access/ginxlog.h                 |  2 +-
 src/include/access/gistxlog.h                |  2 +-
 src/include/access/hash_xlog.h               |  2 +-
 src/include/access/heapam_xlog.h             |  4 +-
 src/include/access/multixact.h               |  3 +-
 src/include/access/nbtxlog.h                 |  2 +-
 src/include/access/spgxlog.h                 |  2 +-
 src/include/access/xact.h                    |  6 +--
 src/include/access/xlog.h                    |  2 +-
 src/include/access/xloginsert.h              |  3 +-
 src/include/access/xlogreader.h              |  1 +
 src/include/access/xlogrecord.h              | 11 +---
 src/include/access/xlogstats.h               |  2 +-
 src/include/catalog/storage_xlog.h           |  2 +-
 src/include/commands/dbcommands_xlog.h       |  2 +-
 src/include/commands/sequence.h              |  2 +-
 src/include/commands/tablespace.h            |  2 +-
 src/include/replication/message.h            |  2 +-
 src/include/storage/standbydefs.h            |  2 +-
 src/include/utils/relmapper.h                |  2 +-
 78 files changed, 430 insertions(+), 412 deletions(-)

diff --git a/contrib/pg_walinspect/pg_walinspect.c b/contrib/pg_walinspect/pg_walinspect.c
index 38fb4106da..f4e3b40bed 100644
--- a/contrib/pg_walinspect/pg_walinspect.c
+++ b/contrib/pg_walinspect/pg_walinspect.c
@@ -188,10 +188,10 @@ GetWALRecordInfo(XLogReaderState *record, Datum *values,
 	int			i = 0;
 
 	desc = GetRmgr(XLogRecGetRmid(record));
-	id = desc.rm_identify(XLogRecGetInfo(record));
+	id = desc.rm_identify(XLogRecGetRmInfo(record));
 
 	if (id == NULL)
-		id = psprintf("UNKNOWN (%x)", XLogRecGetInfo(record) & ~XLR_INFO_MASK);
+		id = psprintf("UNKNOWN (%x)", XLogRecGetRmInfo(record));
 
 	initStringInfo(&rec_desc);
 	desc.rm_desc(&rec_desc, record);
diff --git a/src/backend/access/brin/brin_pageops.c b/src/backend/access/brin/brin_pageops.c
index f17aad51b6..150d6f9793 100644
--- a/src/backend/access/brin/brin_pageops.c
+++ b/src/backend/access/brin/brin_pageops.c
@@ -186,7 +186,7 @@ brin_doupdate(Relation idxrel, BlockNumber pagesPerRange,
 		{
 			xl_brin_samepage_update xlrec;
 			XLogRecPtr	recptr;
-			uint8		info = XLOG_BRIN_SAMEPAGE_UPDATE;
+			uint8		rminfo = XLOG_BRIN_SAMEPAGE_UPDATE;
 
 			xlrec.offnum = oldoff;
 
@@ -196,7 +196,7 @@ brin_doupdate(Relation idxrel, BlockNumber pagesPerRange,
 			XLogRegisterBuffer(0, oldbuf, REGBUF_STANDARD);
 			XLogRegisterBufData(0, (char *) unconstify(BrinTuple *, newtup), newsz);
 
-			recptr = XLogInsert(RM_BRIN_ID, info);
+			recptr = XLogInsert(RM_BRIN_ID, rminfo);
 
 			PageSetLSN(oldpage, recptr);
 		}
@@ -271,9 +271,9 @@ brin_doupdate(Relation idxrel, BlockNumber pagesPerRange,
 		{
 			xl_brin_update xlrec;
 			XLogRecPtr	recptr;
-			uint8		info;
+			uint8		rminfo;
 
-			info = XLOG_BRIN_UPDATE | (extended ? XLOG_BRIN_INIT_PAGE : 0);
+			rminfo = XLOG_BRIN_UPDATE | (extended ? XLOG_BRIN_INIT_PAGE : 0);
 
 			xlrec.insert.offnum = newoff;
 			xlrec.insert.heapBlk = heapBlk;
@@ -294,7 +294,7 @@ brin_doupdate(Relation idxrel, BlockNumber pagesPerRange,
 			/* old page */
 			XLogRegisterBuffer(2, oldbuf, REGBUF_STANDARD);
 
-			recptr = XLogInsert(RM_BRIN_ID, info);
+			recptr = XLogInsert(RM_BRIN_ID, rminfo);
 
 			PageSetLSN(oldpage, recptr);
 			PageSetLSN(newpage, recptr);
@@ -428,9 +428,9 @@ brin_doinsert(Relation idxrel, BlockNumber pagesPerRange,
 	{
 		xl_brin_insert xlrec;
 		XLogRecPtr	recptr;
-		uint8		info;
+		uint8		rminfo;
 
-		info = XLOG_BRIN_INSERT | (extended ? XLOG_BRIN_INIT_PAGE : 0);
+		rminfo = XLOG_BRIN_INSERT | (extended ? XLOG_BRIN_INIT_PAGE : 0);
 		xlrec.heapBlk = heapBlk;
 		xlrec.pagesPerRange = pagesPerRange;
 		xlrec.offnum = off;
@@ -443,7 +443,7 @@ brin_doinsert(Relation idxrel, BlockNumber pagesPerRange,
 
 		XLogRegisterBuffer(1, revmapbuf, 0);
 
-		recptr = XLogInsert(RM_BRIN_ID, info);
+		recptr = XLogInsert(RM_BRIN_ID, rminfo);
 
 		PageSetLSN(page, recptr);
 		PageSetLSN(BufferGetPage(revmapbuf), recptr);
diff --git a/src/backend/access/brin/brin_xlog.c b/src/backend/access/brin/brin_xlog.c
index af6949882a..c0a23bdca6 100644
--- a/src/backend/access/brin/brin_xlog.c
+++ b/src/backend/access/brin/brin_xlog.c
@@ -56,7 +56,7 @@ brin_xlog_insert_update(XLogReaderState *record,
 	 * If we inserted the first and only tuple on the page, re-initialize the
 	 * page from scratch.
 	 */
-	if (XLogRecGetInfo(record) & XLOG_BRIN_INIT_PAGE)
+	if (XLogRecGetRmInfo(record) & XLOG_BRIN_INIT_PAGE)
 	{
 		buffer = XLogInitBufferForRedo(record, 0);
 		page = BufferGetPage(buffer);
@@ -308,9 +308,9 @@ brin_xlog_desummarize_page(XLogReaderState *record)
 void
 brin_redo(XLogReaderState *record)
 {
-	uint8		info = XLogRecGetInfo(record) & ~XLR_INFO_MASK;
+	uint8		rminfo = XLogRecGetRmInfo(record);
 
-	switch (info & XLOG_BRIN_OPMASK)
+	switch (rminfo & XLOG_BRIN_OPMASK)
 	{
 		case XLOG_BRIN_CREATE_INDEX:
 			brin_xlog_createidx(record);
@@ -331,7 +331,7 @@ brin_redo(XLogReaderState *record)
 			brin_xlog_desummarize_page(record);
 			break;
 		default:
-			elog(PANIC, "brin_redo: unknown op code %u", info);
+			elog(PANIC, "brin_redo: unknown op code %u", rminfo);
 	}
 }
 
diff --git a/src/backend/access/gin/ginxlog.c b/src/backend/access/gin/ginxlog.c
index 41b92115bf..e6a28ef6ce 100644
--- a/src/backend/access/gin/ginxlog.c
+++ b/src/backend/access/gin/ginxlog.c
@@ -725,7 +725,7 @@ ginRedoDeleteListPages(XLogReaderState *record)
 void
 gin_redo(XLogReaderState *record)
 {
-	uint8		info = XLogRecGetInfo(record) & ~XLR_INFO_MASK;
+	uint8		rminfo = XLogRecGetRmInfo(record);
 	MemoryContext oldCtx;
 
 	/*
@@ -735,7 +735,7 @@ gin_redo(XLogReaderState *record)
 	 */
 
 	oldCtx = MemoryContextSwitchTo(opCtx);
-	switch (info)
+	switch (rminfo)
 	{
 		case XLOG_GIN_CREATE_PTREE:
 			ginRedoCreatePTree(record);
@@ -765,7 +765,7 @@ gin_redo(XLogReaderState *record)
 			ginRedoDeleteListPages(record);
 			break;
 		default:
-			elog(PANIC, "gin_redo: unknown op code %u", info);
+			elog(PANIC, "gin_redo: unknown op code %u", rminfo);
 	}
 	MemoryContextSwitchTo(oldCtx);
 	MemoryContextReset(opCtx);
diff --git a/src/backend/access/gist/gistxlog.c b/src/backend/access/gist/gistxlog.c
index 998befd2cb..940d9cd90e 100644
--- a/src/backend/access/gist/gistxlog.c
+++ b/src/backend/access/gist/gistxlog.c
@@ -402,7 +402,7 @@ gistRedoPageReuse(XLogReaderState *record)
 void
 gist_redo(XLogReaderState *record)
 {
-	uint8		info = XLogRecGetInfo(record) & ~XLR_INFO_MASK;
+	uint8		rminfo = XLogRecGetRmInfo(record);
 	MemoryContext oldCxt;
 
 	/*
@@ -412,7 +412,7 @@ gist_redo(XLogReaderState *record)
 	 */
 
 	oldCxt = MemoryContextSwitchTo(opCtx);
-	switch (info)
+	switch (rminfo)
 	{
 		case XLOG_GIST_PAGE_UPDATE:
 			gistRedoPageUpdateRecord(record);
@@ -433,7 +433,7 @@ gist_redo(XLogReaderState *record)
 			/* nop. See gistGetFakeLSN(). */
 			break;
 		default:
-			elog(PANIC, "gist_redo: unknown op code %u", info);
+			elog(PANIC, "gist_redo: unknown op code %u", rminfo);
 	}
 
 	MemoryContextSwitchTo(oldCxt);
diff --git a/src/backend/access/hash/hash_xlog.c b/src/backend/access/hash/hash_xlog.c
index e88213c742..9bc8f4edd4 100644
--- a/src/backend/access/hash/hash_xlog.c
+++ b/src/backend/access/hash/hash_xlog.c
@@ -1052,9 +1052,9 @@ hash_xlog_vacuum_one_page(XLogReaderState *record)
 void
 hash_redo(XLogReaderState *record)
 {
-	uint8		info = XLogRecGetInfo(record) & ~XLR_INFO_MASK;
+	uint8		rminfo = XLogRecGetRmInfo(record);
 
-	switch (info)
+	switch (rminfo)
 	{
 		case XLOG_HASH_INIT_META_PAGE:
 			hash_xlog_init_meta_page(record);
@@ -1096,7 +1096,7 @@ hash_redo(XLogReaderState *record)
 			hash_xlog_vacuum_one_page(record);
 			break;
 		default:
-			elog(PANIC, "hash_redo: unknown op code %u", info);
+			elog(PANIC, "hash_redo: unknown op code %u", rminfo);
 	}
 }
 
diff --git a/src/backend/access/heap/heapam.c b/src/backend/access/heap/heapam.c
index eb811d751e..e65100d00f 100644
--- a/src/backend/access/heap/heapam.c
+++ b/src/backend/access/heap/heapam.c
@@ -2104,7 +2104,7 @@ heap_insert(Relation relation, HeapTuple tup, CommandId cid,
 		xl_heap_header xlhdr;
 		XLogRecPtr	recptr;
 		Page		page = BufferGetPage(buffer);
-		uint8		info = XLOG_HEAP_INSERT;
+		uint8		rminfo = XLOG_HEAP_INSERT;
 		int			bufflags = 0;
 
 		/*
@@ -2122,7 +2122,7 @@ heap_insert(Relation relation, HeapTuple tup, CommandId cid,
 		if (ItemPointerGetOffsetNumber(&(heaptup->t_self)) == FirstOffsetNumber &&
 			PageGetMaxOffsetNumber(page) == FirstOffsetNumber)
 		{
-			info |= XLOG_HEAP_INIT_PAGE;
+			rminfo |= XLOG_HEAP_INIT_PAGE;
 			bufflags |= REGBUF_WILL_INIT;
 		}
 
@@ -2171,7 +2171,7 @@ heap_insert(Relation relation, HeapTuple tup, CommandId cid,
 		/* filtering by origin on a row level is much more efficient */
 		XLogSetRecordFlags(XLOG_INCLUDE_ORIGIN);
 
-		recptr = XLogInsert(RM_HEAP_ID, info);
+		recptr = XLogInsert(RM_HEAP_ID, rminfo);
 
 		PageSetLSN(page, recptr);
 	}
@@ -2415,7 +2415,7 @@ heap_multi_insert(Relation relation, TupleTableSlot **slots, int ntuples,
 		{
 			XLogRecPtr	recptr;
 			xl_heap_multi_insert *xlrec;
-			uint8		info = XLOG_HEAP2_MULTI_INSERT;
+			uint8		rminfo = XLOG_HEAP2_MULTI_INSERT;
 			char	   *tupledata;
 			int			totaldatalen;
 			char	   *scratchptr = scratch.data;
@@ -2499,7 +2499,7 @@ heap_multi_insert(Relation relation, TupleTableSlot **slots, int ntuples,
 
 			if (init)
 			{
-				info |= XLOG_HEAP_INIT_PAGE;
+				rminfo |= XLOG_HEAP_INIT_PAGE;
 				bufflags |= REGBUF_WILL_INIT;
 			}
 
@@ -2519,7 +2519,7 @@ heap_multi_insert(Relation relation, TupleTableSlot **slots, int ntuples,
 			/* filtering by origin on a row level is much more efficient */
 			XLogSetRecordFlags(XLOG_INCLUDE_ORIGIN);
 
-			recptr = XLogInsert(RM_HEAP2_ID, info);
+			recptr = XLogInsert(RM_HEAP2_ID, rminfo);
 
 			PageSetLSN(page, recptr);
 		}
@@ -8229,7 +8229,7 @@ log_heap_update(Relation reln, Buffer oldbuf,
 	xl_heap_update xlrec;
 	xl_heap_header xlhdr;
 	xl_heap_header xlhdr_idx;
-	uint8		info;
+	uint8		rminfo;
 	uint16		prefix_suffix[2];
 	uint16		prefixlen = 0,
 				suffixlen = 0;
@@ -8245,9 +8245,9 @@ log_heap_update(Relation reln, Buffer oldbuf,
 	XLogBeginInsert();
 
 	if (HeapTupleIsHeapOnly(newtup))
-		info = XLOG_HEAP_HOT_UPDATE;
+		rminfo = XLOG_HEAP_HOT_UPDATE;
 	else
-		info = XLOG_HEAP_UPDATE;
+		rminfo = XLOG_HEAP_UPDATE;
 
 	/*
 	 * If the old and new tuple are on the same page, we only need to log the
@@ -8327,7 +8327,7 @@ log_heap_update(Relation reln, Buffer oldbuf,
 	if (ItemPointerGetOffsetNumber(&(newtup->t_self)) == FirstOffsetNumber &&
 		PageGetMaxOffsetNumber(page) == FirstOffsetNumber)
 	{
-		info |= XLOG_HEAP_INIT_PAGE;
+		rminfo |= XLOG_HEAP_INIT_PAGE;
 		init = true;
 	}
 	else
@@ -8431,7 +8431,7 @@ log_heap_update(Relation reln, Buffer oldbuf,
 	/* filtering by origin on a row level is much more efficient */
 	XLogSetRecordFlags(XLOG_INCLUDE_ORIGIN);
 
-	recptr = XLogInsert(RM_HEAP_ID, info);
+	recptr = XLogInsert(RM_HEAP_ID, rminfo);
 
 	return recptr;
 }
@@ -9114,7 +9114,7 @@ heap_xlog_insert(XLogReaderState *record)
 	 * If we inserted the first and only tuple on the page, re-initialize the
 	 * page from scratch.
 	 */
-	if (XLogRecGetInfo(record) & XLOG_HEAP_INIT_PAGE)
+	if (XLogRecGetRmInfo(record) & XLOG_HEAP_INIT_PAGE)
 	{
 		buffer = XLogInitBufferForRedo(record, 0);
 		page = BufferGetPage(buffer);
@@ -9208,7 +9208,7 @@ heap_xlog_multi_insert(XLogReaderState *record)
 	uint32		newlen;
 	Size		freespace = 0;
 	int			i;
-	bool		isinit = (XLogRecGetInfo(record) & XLOG_HEAP_INIT_PAGE) != 0;
+	bool		isinit = (XLogRecGetRmInfo(record) & XLOG_HEAP_INIT_PAGE) != 0;
 	XLogRedoAction action;
 
 	/*
@@ -9456,7 +9456,7 @@ heap_xlog_update(XLogReaderState *record, bool hot_update)
 		nbuffer = obuffer;
 		newaction = oldaction;
 	}
-	else if (XLogRecGetInfo(record) & XLOG_HEAP_INIT_PAGE)
+	else if (XLogRecGetRmInfo(record) & XLOG_HEAP_INIT_PAGE)
 	{
 		nbuffer = XLogInitBufferForRedo(record, 0);
 		page = (Page) BufferGetPage(nbuffer);
@@ -9820,14 +9820,14 @@ heap_xlog_inplace(XLogReaderState *record)
 void
 heap_redo(XLogReaderState *record)
 {
-	uint8		info = XLogRecGetInfo(record) & ~XLR_INFO_MASK;
+	uint8		rminfo = XLogRecGetRmInfo(record);
 
 	/*
 	 * These operations don't overwrite MVCC data so no conflict processing is
 	 * required. The ones in heap2 rmgr do.
 	 */
 
-	switch (info & XLOG_HEAP_OPMASK)
+	switch (rminfo & XLOG_HEAP_OPMASK)
 	{
 		case XLOG_HEAP_INSERT:
 			heap_xlog_insert(record);
@@ -9859,16 +9859,16 @@ heap_redo(XLogReaderState *record)
 			heap_xlog_inplace(record);
 			break;
 		default:
-			elog(PANIC, "heap_redo: unknown op code %u", info);
+			elog(PANIC, "heap_redo: unknown op code %u", rminfo);
 	}
 }
 
 void
 heap2_redo(XLogReaderState *record)
 {
-	uint8		info = XLogRecGetInfo(record) & ~XLR_INFO_MASK;
+	uint8		rminfo = XLogRecGetRmInfo(record);
 
-	switch (info & XLOG_HEAP_OPMASK)
+	switch (rminfo & XLOG_HEAP_OPMASK)
 	{
 		case XLOG_HEAP2_PRUNE:
 			heap_xlog_prune(record);
@@ -9899,7 +9899,7 @@ heap2_redo(XLogReaderState *record)
 			heap_xlog_logical_rewrite(record);
 			break;
 		default:
-			elog(PANIC, "heap2_redo: unknown op code %u", info);
+			elog(PANIC, "heap2_redo: unknown op code %u", rminfo);
 	}
 }
 
diff --git a/src/backend/access/nbtree/nbtinsert.c b/src/backend/access/nbtree/nbtinsert.c
index f6f4af8bfe..90948bf819 100644
--- a/src/backend/access/nbtree/nbtinsert.c
+++ b/src/backend/access/nbtree/nbtinsert.c
@@ -1308,7 +1308,7 @@ _bt_insertonpg(Relation rel,
 		{
 			xl_btree_insert xlrec;
 			xl_btree_metadata xlmeta;
-			uint8		xlinfo;
+			uint8		xlrminfo;
 			XLogRecPtr	recptr;
 			uint16		upostingoff;
 
@@ -1320,7 +1320,7 @@ _bt_insertonpg(Relation rel,
 			if (isleaf && postingoff == 0)
 			{
 				/* Simple leaf insert */
-				xlinfo = XLOG_BTREE_INSERT_LEAF;
+				xlrminfo = XLOG_BTREE_INSERT_LEAF;
 			}
 			else if (postingoff != 0)
 			{
@@ -1329,18 +1329,18 @@ _bt_insertonpg(Relation rel,
 				 * postingoff field before newitem/orignewitem.
 				 */
 				Assert(isleaf);
-				xlinfo = XLOG_BTREE_INSERT_POST;
+				xlrminfo = XLOG_BTREE_INSERT_POST;
 			}
 			else
 			{
 				/* Internal page insert, which finishes a split on cbuf */
-				xlinfo = XLOG_BTREE_INSERT_UPPER;
+				xlrminfo = XLOG_BTREE_INSERT_UPPER;
 				XLogRegisterBuffer(1, cbuf, REGBUF_STANDARD);
 
 				if (BufferIsValid(metabuf))
 				{
 					/* Actually, it's an internal page insert + meta update */
-					xlinfo = XLOG_BTREE_INSERT_META;
+					xlrminfo = XLOG_BTREE_INSERT_META;
 
 					Assert(metad->btm_version >= BTREE_NOVAC_VERSION);
 					xlmeta.version = metad->btm_version;
@@ -1381,7 +1381,7 @@ _bt_insertonpg(Relation rel,
 									IndexTupleSize(origitup));
 			}
 
-			recptr = XLogInsert(RM_BTREE_ID, xlinfo);
+			recptr = XLogInsert(RM_BTREE_ID, xlrminfo);
 
 			if (BufferIsValid(metabuf))
 				PageSetLSN(metapg, recptr);
@@ -1962,7 +1962,7 @@ _bt_split(Relation rel, BTScanInsert itup_key, Buffer buf, Buffer cbuf,
 	if (RelationNeedsWAL(rel))
 	{
 		xl_btree_split xlrec;
-		uint8		xlinfo;
+		uint8		xlrminfo;
 		XLogRecPtr	recptr;
 
 		xlrec.level = ropaque->btpo_level;
@@ -2045,8 +2045,8 @@ _bt_split(Relation rel, BTScanInsert itup_key, Buffer buf, Buffer cbuf,
 							(char *) rightpage + ((PageHeader) rightpage)->pd_upper,
 							((PageHeader) rightpage)->pd_special - ((PageHeader) rightpage)->pd_upper);
 
-		xlinfo = newitemonleft ? XLOG_BTREE_SPLIT_L : XLOG_BTREE_SPLIT_R;
-		recptr = XLogInsert(RM_BTREE_ID, xlinfo);
+		xlrminfo = newitemonleft ? XLOG_BTREE_SPLIT_L : XLOG_BTREE_SPLIT_R;
+		recptr = XLogInsert(RM_BTREE_ID, xlrminfo);
 
 		PageSetLSN(origpage, recptr);
 		PageSetLSN(rightpage, recptr);
diff --git a/src/backend/access/nbtree/nbtpage.c b/src/backend/access/nbtree/nbtpage.c
index 8b96708b3e..e802b71704 100644
--- a/src/backend/access/nbtree/nbtpage.c
+++ b/src/backend/access/nbtree/nbtpage.c
@@ -2634,7 +2634,7 @@ _bt_unlink_halfdead_page(Relation rel, Buffer leafbuf, BlockNumber scanblkno,
 	{
 		xl_btree_unlink_page xlrec;
 		xl_btree_metadata xlmeta;
-		uint8		xlinfo;
+		uint8		xlrminfo;
 		XLogRecPtr	recptr;
 
 		XLogBeginInsert();
@@ -2673,12 +2673,12 @@ _bt_unlink_halfdead_page(Relation rel, Buffer leafbuf, BlockNumber scanblkno,
 			xlmeta.allequalimage = metad->btm_allequalimage;
 
 			XLogRegisterBufData(4, (char *) &xlmeta, sizeof(xl_btree_metadata));
-			xlinfo = XLOG_BTREE_UNLINK_PAGE_META;
+			xlrminfo = XLOG_BTREE_UNLINK_PAGE_META;
 		}
 		else
-			xlinfo = XLOG_BTREE_UNLINK_PAGE;
+			xlrminfo = XLOG_BTREE_UNLINK_PAGE;
 
-		recptr = XLogInsert(RM_BTREE_ID, xlinfo);
+		recptr = XLogInsert(RM_BTREE_ID, xlrminfo);
 
 		if (BufferIsValid(metabuf))
 		{
diff --git a/src/backend/access/nbtree/nbtxlog.c b/src/backend/access/nbtree/nbtxlog.c
index ad489e33b3..6c085fd43e 100644
--- a/src/backend/access/nbtree/nbtxlog.c
+++ b/src/backend/access/nbtree/nbtxlog.c
@@ -1012,11 +1012,11 @@ btree_xlog_reuse_page(XLogReaderState *record)
 void
 btree_redo(XLogReaderState *record)
 {
-	uint8		info = XLogRecGetInfo(record) & ~XLR_INFO_MASK;
+	uint8		rminfo = XLogRecGetRmInfo(record);
 	MemoryContext oldCtx;
 
 	oldCtx = MemoryContextSwitchTo(opCtx);
-	switch (info)
+	switch (rminfo)
 	{
 		case XLOG_BTREE_INSERT_LEAF:
 			btree_xlog_insert(true, false, false, record);
@@ -1046,11 +1046,11 @@ btree_redo(XLogReaderState *record)
 			btree_xlog_delete(record);
 			break;
 		case XLOG_BTREE_MARK_PAGE_HALFDEAD:
-			btree_xlog_mark_page_halfdead(info, record);
+			btree_xlog_mark_page_halfdead(rminfo, record);
 			break;
 		case XLOG_BTREE_UNLINK_PAGE:
 		case XLOG_BTREE_UNLINK_PAGE_META:
-			btree_xlog_unlink_page(info, record);
+			btree_xlog_unlink_page(rminfo, record);
 			break;
 		case XLOG_BTREE_NEWROOT:
 			btree_xlog_newroot(record);
@@ -1062,7 +1062,7 @@ btree_redo(XLogReaderState *record)
 			_bt_restore_meta(record, 0);
 			break;
 		default:
-			elog(PANIC, "btree_redo: unknown op code %u", info);
+			elog(PANIC, "btree_redo: unknown op code %u", rminfo);
 	}
 	MemoryContextSwitchTo(oldCtx);
 	MemoryContextReset(opCtx);
diff --git a/src/backend/access/rmgrdesc/brindesc.c b/src/backend/access/rmgrdesc/brindesc.c
index f05607e6c3..44395dd9a5 100644
--- a/src/backend/access/rmgrdesc/brindesc.c
+++ b/src/backend/access/rmgrdesc/brindesc.c
@@ -20,17 +20,17 @@ void
 brin_desc(StringInfo buf, XLogReaderState *record)
 {
 	char	   *rec = XLogRecGetData(record);
-	uint8		info = XLogRecGetInfo(record) & ~XLR_INFO_MASK;
+	uint8		rminfo = XLogRecGetRmInfo(record);
 
-	info &= XLOG_BRIN_OPMASK;
-	if (info == XLOG_BRIN_CREATE_INDEX)
+	rminfo &= XLOG_BRIN_OPMASK;
+	if (rminfo == XLOG_BRIN_CREATE_INDEX)
 	{
 		xl_brin_createidx *xlrec = (xl_brin_createidx *) rec;
 
 		appendStringInfo(buf, "v%d pagesPerRange %u",
 						 xlrec->version, xlrec->pagesPerRange);
 	}
-	else if (info == XLOG_BRIN_INSERT)
+	else if (rminfo == XLOG_BRIN_INSERT)
 	{
 		xl_brin_insert *xlrec = (xl_brin_insert *) rec;
 
@@ -39,7 +39,7 @@ brin_desc(StringInfo buf, XLogReaderState *record)
 						 xlrec->pagesPerRange,
 						 xlrec->offnum);
 	}
-	else if (info == XLOG_BRIN_UPDATE)
+	else if (rminfo == XLOG_BRIN_UPDATE)
 	{
 		xl_brin_update *xlrec = (xl_brin_update *) rec;
 
@@ -49,19 +49,19 @@ brin_desc(StringInfo buf, XLogReaderState *record)
 						 xlrec->oldOffnum,
 						 xlrec->insert.offnum);
 	}
-	else if (info == XLOG_BRIN_SAMEPAGE_UPDATE)
+	else if (rminfo == XLOG_BRIN_SAMEPAGE_UPDATE)
 	{
 		xl_brin_samepage_update *xlrec = (xl_brin_samepage_update *) rec;
 
 		appendStringInfo(buf, "offnum %u", xlrec->offnum);
 	}
-	else if (info == XLOG_BRIN_REVMAP_EXTEND)
+	else if (rminfo == XLOG_BRIN_REVMAP_EXTEND)
 	{
 		xl_brin_revmap_extend *xlrec = (xl_brin_revmap_extend *) rec;
 
 		appendStringInfo(buf, "targetBlk %u", xlrec->targetBlk);
 	}
-	else if (info == XLOG_BRIN_DESUMMARIZE)
+	else if (rminfo == XLOG_BRIN_DESUMMARIZE)
 	{
 		xl_brin_desummarize *xlrec = (xl_brin_desummarize *) rec;
 
@@ -71,11 +71,11 @@ brin_desc(StringInfo buf, XLogReaderState *record)
 }
 
 const char *
-brin_identify(uint8 info)
+brin_identify(uint8 rminfo)
 {
 	const char *id = NULL;
 
-	switch (info & ~XLR_INFO_MASK)
+	switch (rminfo)
 	{
 		case XLOG_BRIN_CREATE_INDEX:
 			id = "CREATE_INDEX";
diff --git a/src/backend/access/rmgrdesc/clogdesc.c b/src/backend/access/rmgrdesc/clogdesc.c
index 87513732be..1b0cd7ddbf 100644
--- a/src/backend/access/rmgrdesc/clogdesc.c
+++ b/src/backend/access/rmgrdesc/clogdesc.c
@@ -21,16 +21,16 @@ void
 clog_desc(StringInfo buf, XLogReaderState *record)
 {
 	char	   *rec = XLogRecGetData(record);
-	uint8		info = XLogRecGetInfo(record) & ~XLR_INFO_MASK;
+	uint8		rminfo = XLogRecGetRmInfo(record);
 
-	if (info == CLOG_ZEROPAGE)
+	if (rminfo == CLOG_ZEROPAGE)
 	{
 		int			pageno;
 
 		memcpy(&pageno, rec, sizeof(int));
 		appendStringInfo(buf, "page %d", pageno);
 	}
-	else if (info == CLOG_TRUNCATE)
+	else if (rminfo == CLOG_TRUNCATE)
 	{
 		xl_clog_truncate xlrec;
 
@@ -41,11 +41,11 @@ clog_desc(StringInfo buf, XLogReaderState *record)
 }
 
 const char *
-clog_identify(uint8 info)
+clog_identify(uint8 rminfo)
 {
 	const char *id = NULL;
 
-	switch (info & ~XLR_INFO_MASK)
+	switch (rminfo)
 	{
 		case CLOG_ZEROPAGE:
 			id = "ZEROPAGE";
diff --git a/src/backend/access/rmgrdesc/committsdesc.c b/src/backend/access/rmgrdesc/committsdesc.c
index 3a65538bb0..120562222f 100644
--- a/src/backend/access/rmgrdesc/committsdesc.c
+++ b/src/backend/access/rmgrdesc/committsdesc.c
@@ -22,16 +22,16 @@ void
 commit_ts_desc(StringInfo buf, XLogReaderState *record)
 {
 	char	   *rec = XLogRecGetData(record);
-	uint8		info = XLogRecGetInfo(record) & ~XLR_INFO_MASK;
+	uint8		rminfo = XLogRecGetRmInfo(record);
 
-	if (info == COMMIT_TS_ZEROPAGE)
+	if (rminfo == COMMIT_TS_ZEROPAGE)
 	{
 		int			pageno;
 
 		memcpy(&pageno, rec, sizeof(int));
 		appendStringInfo(buf, "%d", pageno);
 	}
-	else if (info == COMMIT_TS_TRUNCATE)
+	else if (rminfo == COMMIT_TS_TRUNCATE)
 	{
 		xl_commit_ts_truncate *trunc = (xl_commit_ts_truncate *) rec;
 
@@ -41,9 +41,9 @@ commit_ts_desc(StringInfo buf, XLogReaderState *record)
 }
 
 const char *
-commit_ts_identify(uint8 info)
+commit_ts_identify(uint8 rminfo)
 {
-	switch (info)
+	switch (rminfo)
 	{
 		case COMMIT_TS_ZEROPAGE:
 			return "ZEROPAGE";
diff --git a/src/backend/access/rmgrdesc/dbasedesc.c b/src/backend/access/rmgrdesc/dbasedesc.c
index 523d0b3c1d..f184fbb2ab 100644
--- a/src/backend/access/rmgrdesc/dbasedesc.c
+++ b/src/backend/access/rmgrdesc/dbasedesc.c
@@ -22,9 +22,9 @@ void
 dbase_desc(StringInfo buf, XLogReaderState *record)
 {
 	char	   *rec = XLogRecGetData(record);
-	uint8		info = XLogRecGetInfo(record) & ~XLR_INFO_MASK;
+	uint8		rminfo = XLogRecGetRmInfo(record);
 
-	if (info == XLOG_DBASE_CREATE_FILE_COPY)
+	if (rminfo == XLOG_DBASE_CREATE_FILE_COPY)
 	{
 		xl_dbase_create_file_copy_rec *xlrec =
 		(xl_dbase_create_file_copy_rec *) rec;
@@ -33,7 +33,7 @@ dbase_desc(StringInfo buf, XLogReaderState *record)
 						 xlrec->src_tablespace_id, xlrec->src_db_id,
 						 xlrec->tablespace_id, xlrec->db_id);
 	}
-	else if (info == XLOG_DBASE_CREATE_WAL_LOG)
+	else if (rminfo == XLOG_DBASE_CREATE_WAL_LOG)
 	{
 		xl_dbase_create_wal_log_rec *xlrec =
 		(xl_dbase_create_wal_log_rec *) rec;
@@ -41,7 +41,7 @@ dbase_desc(StringInfo buf, XLogReaderState *record)
 		appendStringInfo(buf, "create dir %u/%u",
 						 xlrec->tablespace_id, xlrec->db_id);
 	}
-	else if (info == XLOG_DBASE_DROP)
+	else if (rminfo == XLOG_DBASE_DROP)
 	{
 		xl_dbase_drop_rec *xlrec = (xl_dbase_drop_rec *) rec;
 		int			i;
@@ -54,11 +54,11 @@ dbase_desc(StringInfo buf, XLogReaderState *record)
 }
 
 const char *
-dbase_identify(uint8 info)
+dbase_identify(uint8 rminfo)
 {
 	const char *id = NULL;
 
-	switch (info & ~XLR_INFO_MASK)
+	switch (rminfo)
 	{
 		case XLOG_DBASE_CREATE_FILE_COPY:
 			id = "CREATE_FILE_COPY";
diff --git a/src/backend/access/rmgrdesc/genericdesc.c b/src/backend/access/rmgrdesc/genericdesc.c
index d8509b884b..e1aa356686 100644
--- a/src/backend/access/rmgrdesc/genericdesc.c
+++ b/src/backend/access/rmgrdesc/genericdesc.c
@@ -50,7 +50,7 @@ generic_desc(StringInfo buf, XLogReaderState *record)
  * inside generic xlog records.
  */
 const char *
-generic_identify(uint8 info)
+generic_identify(uint8 rminfo)
 {
 	return "Generic";
 }
diff --git a/src/backend/access/rmgrdesc/gindesc.c b/src/backend/access/rmgrdesc/gindesc.c
index 7d147cea97..76505f5f14 100644
--- a/src/backend/access/rmgrdesc/gindesc.c
+++ b/src/backend/access/rmgrdesc/gindesc.c
@@ -74,9 +74,9 @@ void
 gin_desc(StringInfo buf, XLogReaderState *record)
 {
 	char	   *rec = XLogRecGetData(record);
-	uint8		info = XLogRecGetInfo(record) & ~XLR_INFO_MASK;
+	uint8		rminfo = XLogRecGetRmInfo(record);
 
-	switch (info)
+	switch (rminfo)
 	{
 		case XLOG_GIN_CREATE_PTREE:
 			/* no further information */
@@ -179,11 +179,11 @@ gin_desc(StringInfo buf, XLogReaderState *record)
 }
 
 const char *
-gin_identify(uint8 info)
+gin_identify(uint8 rminfo)
 {
 	const char *id = NULL;
 
-	switch (info & ~XLR_INFO_MASK)
+	switch (rminfo)
 	{
 		case XLOG_GIN_CREATE_PTREE:
 			id = "CREATE_PTREE";
diff --git a/src/backend/access/rmgrdesc/gistdesc.c b/src/backend/access/rmgrdesc/gistdesc.c
index 7dd3c1d500..d6b6404213 100644
--- a/src/backend/access/rmgrdesc/gistdesc.c
+++ b/src/backend/access/rmgrdesc/gistdesc.c
@@ -60,9 +60,9 @@ void
 gist_desc(StringInfo buf, XLogReaderState *record)
 {
 	char	   *rec = XLogRecGetData(record);
-	uint8		info = XLogRecGetInfo(record) & ~XLR_INFO_MASK;
+	uint8		rminfo = XLogRecGetRmInfo(record);
 
-	switch (info)
+	switch (rminfo)
 	{
 		case XLOG_GIST_PAGE_UPDATE:
 			out_gistxlogPageUpdate(buf, (gistxlogPageUpdate *) rec);
@@ -86,11 +86,11 @@ gist_desc(StringInfo buf, XLogReaderState *record)
 }
 
 const char *
-gist_identify(uint8 info)
+gist_identify(uint8 rminfo)
 {
 	const char *id = NULL;
 
-	switch (info & ~XLR_INFO_MASK)
+	switch (rminfo)
 	{
 		case XLOG_GIST_PAGE_UPDATE:
 			id = "PAGE_UPDATE";
diff --git a/src/backend/access/rmgrdesc/hashdesc.c b/src/backend/access/rmgrdesc/hashdesc.c
index ef443bdb16..8ebfc7d16b 100644
--- a/src/backend/access/rmgrdesc/hashdesc.c
+++ b/src/backend/access/rmgrdesc/hashdesc.c
@@ -20,9 +20,9 @@ void
 hash_desc(StringInfo buf, XLogReaderState *record)
 {
 	char	   *rec = XLogRecGetData(record);
-	uint8		info = XLogRecGetInfo(record) & ~XLR_INFO_MASK;
+	uint8		rminfo = XLogRecGetRmInfo(record);
 
-	switch (info)
+	switch (rminfo)
 	{
 		case XLOG_HASH_INIT_META_PAGE:
 			{
@@ -122,11 +122,11 @@ hash_desc(StringInfo buf, XLogReaderState *record)
 }
 
 const char *
-hash_identify(uint8 info)
+hash_identify(uint8 rminfo)
 {
 	const char *id = NULL;
 
-	switch (info & ~XLR_INFO_MASK)
+	switch (rminfo)
 	{
 		case XLOG_HASH_INIT_META_PAGE:
 			id = "INIT_META_PAGE";
diff --git a/src/backend/access/rmgrdesc/heapdesc.c b/src/backend/access/rmgrdesc/heapdesc.c
index 923d3bc43d..c07f237365 100644
--- a/src/backend/access/rmgrdesc/heapdesc.c
+++ b/src/backend/access/rmgrdesc/heapdesc.c
@@ -35,17 +35,17 @@ void
 heap_desc(StringInfo buf, XLogReaderState *record)
 {
 	char	   *rec = XLogRecGetData(record);
-	uint8		info = XLogRecGetInfo(record) & ~XLR_INFO_MASK;
+	uint8		rminfo = XLogRecGetRmInfo(record);
 
-	info &= XLOG_HEAP_OPMASK;
-	if (info == XLOG_HEAP_INSERT)
+	rminfo &= XLOG_HEAP_OPMASK;
+	if (rminfo == XLOG_HEAP_INSERT)
 	{
 		xl_heap_insert *xlrec = (xl_heap_insert *) rec;
 
 		appendStringInfo(buf, "off %u flags 0x%02X", xlrec->offnum,
 						 xlrec->flags);
 	}
-	else if (info == XLOG_HEAP_DELETE)
+	else if (rminfo == XLOG_HEAP_DELETE)
 	{
 		xl_heap_delete *xlrec = (xl_heap_delete *) rec;
 
@@ -54,7 +54,7 @@ heap_desc(StringInfo buf, XLogReaderState *record)
 						 xlrec->flags);
 		out_infobits(buf, xlrec->infobits_set);
 	}
-	else if (info == XLOG_HEAP_UPDATE)
+	else if (rminfo == XLOG_HEAP_UPDATE)
 	{
 		xl_heap_update *xlrec = (xl_heap_update *) rec;
 
@@ -67,7 +67,7 @@ heap_desc(StringInfo buf, XLogReaderState *record)
 						 xlrec->new_offnum,
 						 xlrec->new_xmax);
 	}
-	else if (info == XLOG_HEAP_HOT_UPDATE)
+	else if (rminfo == XLOG_HEAP_HOT_UPDATE)
 	{
 		xl_heap_update *xlrec = (xl_heap_update *) rec;
 
@@ -80,7 +80,7 @@ heap_desc(StringInfo buf, XLogReaderState *record)
 						 xlrec->new_offnum,
 						 xlrec->new_xmax);
 	}
-	else if (info == XLOG_HEAP_TRUNCATE)
+	else if (rminfo == XLOG_HEAP_TRUNCATE)
 	{
 		xl_heap_truncate *xlrec = (xl_heap_truncate *) rec;
 		int			i;
@@ -93,13 +93,13 @@ heap_desc(StringInfo buf, XLogReaderState *record)
 		for (i = 0; i < xlrec->nrelids; i++)
 			appendStringInfo(buf, " %u", xlrec->relids[i]);
 	}
-	else if (info == XLOG_HEAP_CONFIRM)
+	else if (rminfo == XLOG_HEAP_CONFIRM)
 	{
 		xl_heap_confirm *xlrec = (xl_heap_confirm *) rec;
 
 		appendStringInfo(buf, "off %u", xlrec->offnum);
 	}
-	else if (info == XLOG_HEAP_LOCK)
+	else if (rminfo == XLOG_HEAP_LOCK)
 	{
 		xl_heap_lock *xlrec = (xl_heap_lock *) rec;
 
@@ -107,7 +107,7 @@ heap_desc(StringInfo buf, XLogReaderState *record)
 						 xlrec->offnum, xlrec->locking_xid, xlrec->flags);
 		out_infobits(buf, xlrec->infobits_set);
 	}
-	else if (info == XLOG_HEAP_INPLACE)
+	else if (rminfo == XLOG_HEAP_INPLACE)
 	{
 		xl_heap_inplace *xlrec = (xl_heap_inplace *) rec;
 
@@ -118,10 +118,10 @@ void
 heap2_desc(StringInfo buf, XLogReaderState *record)
 {
 	char	   *rec = XLogRecGetData(record);
-	uint8		info = XLogRecGetInfo(record) & ~XLR_INFO_MASK;
+	uint8		rminfo = XLogRecGetRmInfo(record);
 
-	info &= XLOG_HEAP_OPMASK;
-	if (info == XLOG_HEAP2_PRUNE)
+	rminfo &= XLOG_HEAP_OPMASK;
+	if (rminfo == XLOG_HEAP2_PRUNE)
 	{
 		xl_heap_prune *xlrec = (xl_heap_prune *) rec;
 
@@ -130,34 +130,34 @@ heap2_desc(StringInfo buf, XLogReaderState *record)
 						 xlrec->nredirected,
 						 xlrec->ndead);
 	}
-	else if (info == XLOG_HEAP2_VACUUM)
+	else if (rminfo == XLOG_HEAP2_VACUUM)
 	{
 		xl_heap_vacuum *xlrec = (xl_heap_vacuum *) rec;
 
 		appendStringInfo(buf, "nunused %u", xlrec->nunused);
 	}
-	else if (info == XLOG_HEAP2_FREEZE_PAGE)
+	else if (rminfo == XLOG_HEAP2_FREEZE_PAGE)
 	{
 		xl_heap_freeze_page *xlrec = (xl_heap_freeze_page *) rec;
 
 		appendStringInfo(buf, "cutoff xid %u ntuples %u",
 						 xlrec->cutoff_xid, xlrec->ntuples);
 	}
-	else if (info == XLOG_HEAP2_VISIBLE)
+	else if (rminfo == XLOG_HEAP2_VISIBLE)
 	{
 		xl_heap_visible *xlrec = (xl_heap_visible *) rec;
 
 		appendStringInfo(buf, "cutoff xid %u flags 0x%02X",
 						 xlrec->cutoff_xid, xlrec->flags);
 	}
-	else if (info == XLOG_HEAP2_MULTI_INSERT)
+	else if (rminfo == XLOG_HEAP2_MULTI_INSERT)
 	{
 		xl_heap_multi_insert *xlrec = (xl_heap_multi_insert *) rec;
 
 		appendStringInfo(buf, "%d tuples flags 0x%02X", xlrec->ntuples,
 						 xlrec->flags);
 	}
-	else if (info == XLOG_HEAP2_LOCK_UPDATED)
+	else if (rminfo == XLOG_HEAP2_LOCK_UPDATED)
 	{
 		xl_heap_lock_updated *xlrec = (xl_heap_lock_updated *) rec;
 
@@ -165,7 +165,7 @@ heap2_desc(StringInfo buf, XLogReaderState *record)
 						 xlrec->offnum, xlrec->xmax, xlrec->flags);
 		out_infobits(buf, xlrec->infobits_set);
 	}
-	else if (info == XLOG_HEAP2_NEW_CID)
+	else if (rminfo == XLOG_HEAP2_NEW_CID)
 	{
 		xl_heap_new_cid *xlrec = (xl_heap_new_cid *) rec;
 
@@ -181,11 +181,11 @@ heap2_desc(StringInfo buf, XLogReaderState *record)
 }
 
 const char *
-heap_identify(uint8 info)
+heap_identify(uint8 rminfo)
 {
 	const char *id = NULL;
 
-	switch (info & ~XLR_INFO_MASK)
+	switch (rminfo)
 	{
 		case XLOG_HEAP_INSERT:
 			id = "INSERT";
@@ -226,11 +226,11 @@ heap_identify(uint8 info)
 }
 
 const char *
-heap2_identify(uint8 info)
+heap2_identify(uint8 rminfo)
 {
 	const char *id = NULL;
 
-	switch (info & ~XLR_INFO_MASK)
+	switch (rminfo)
 	{
 		case XLOG_HEAP2_PRUNE:
 			id = "PRUNE";
diff --git a/src/backend/access/rmgrdesc/logicalmsgdesc.c b/src/backend/access/rmgrdesc/logicalmsgdesc.c
index 08e03aa30d..03e653c0e8 100644
--- a/src/backend/access/rmgrdesc/logicalmsgdesc.c
+++ b/src/backend/access/rmgrdesc/logicalmsgdesc.c
@@ -19,9 +19,9 @@ void
 logicalmsg_desc(StringInfo buf, XLogReaderState *record)
 {
 	char	   *rec = XLogRecGetData(record);
-	uint8		info = XLogRecGetInfo(record) & ~XLR_INFO_MASK;
+	uint8		rminfo = XLogRecGetRmInfo(record);
 
-	if (info == XLOG_LOGICAL_MESSAGE)
+	if (rminfo == XLOG_LOGICAL_MESSAGE)
 	{
 		xl_logical_message *xlrec = (xl_logical_message *) rec;
 		char	   *prefix = xlrec->message;
@@ -43,9 +43,9 @@ logicalmsg_desc(StringInfo buf, XLogReaderState *record)
 }
 
 const char *
-logicalmsg_identify(uint8 info)
+logicalmsg_identify(uint8 rminfo)
 {
-	if ((info & ~XLR_INFO_MASK) == XLOG_LOGICAL_MESSAGE)
+	if ((rminfo) == XLOG_LOGICAL_MESSAGE)
 		return "MESSAGE";
 
 	return NULL;
diff --git a/src/backend/access/rmgrdesc/mxactdesc.c b/src/backend/access/rmgrdesc/mxactdesc.c
index 7076be2b3f..6e5a411d16 100644
--- a/src/backend/access/rmgrdesc/mxactdesc.c
+++ b/src/backend/access/rmgrdesc/mxactdesc.c
@@ -50,17 +50,17 @@ void
 multixact_desc(StringInfo buf, XLogReaderState *record)
 {
 	char	   *rec = XLogRecGetData(record);
-	uint8		info = XLogRecGetInfo(record) & ~XLR_INFO_MASK;
+	uint8		rminfo = XLogRecGetRmInfo(record);
 
-	if (info == XLOG_MULTIXACT_ZERO_OFF_PAGE ||
-		info == XLOG_MULTIXACT_ZERO_MEM_PAGE)
+	if (rminfo == XLOG_MULTIXACT_ZERO_OFF_PAGE ||
+		rminfo == XLOG_MULTIXACT_ZERO_MEM_PAGE)
 	{
 		int			pageno;
 
 		memcpy(&pageno, rec, sizeof(int));
 		appendStringInfo(buf, "%d", pageno);
 	}
-	else if (info == XLOG_MULTIXACT_CREATE_ID)
+	else if (rminfo == XLOG_MULTIXACT_CREATE_ID)
 	{
 		xl_multixact_create *xlrec = (xl_multixact_create *) rec;
 		int			i;
@@ -70,7 +70,7 @@ multixact_desc(StringInfo buf, XLogReaderState *record)
 		for (i = 0; i < xlrec->nmembers; i++)
 			out_member(buf, &xlrec->members[i]);
 	}
-	else if (info == XLOG_MULTIXACT_TRUNCATE_ID)
+	else if (rminfo == XLOG_MULTIXACT_TRUNCATE_ID)
 	{
 		xl_multixact_truncate *xlrec = (xl_multixact_truncate *) rec;
 
@@ -81,11 +81,11 @@ multixact_desc(StringInfo buf, XLogReaderState *record)
 }
 
 const char *
-multixact_identify(uint8 info)
+multixact_identify(uint8 rminfo)
 {
 	const char *id = NULL;
 
-	switch (info & ~XLR_INFO_MASK)
+	switch (rminfo)
 	{
 		case XLOG_MULTIXACT_ZERO_OFF_PAGE:
 			id = "ZERO_OFF_PAGE";
diff --git a/src/backend/access/rmgrdesc/nbtdesc.c b/src/backend/access/rmgrdesc/nbtdesc.c
index 4843cd530d..c5e92e9e6b 100644
--- a/src/backend/access/rmgrdesc/nbtdesc.c
+++ b/src/backend/access/rmgrdesc/nbtdesc.c
@@ -20,9 +20,9 @@ void
 btree_desc(StringInfo buf, XLogReaderState *record)
 {
 	char	   *rec = XLogRecGetData(record);
-	uint8		info = XLogRecGetInfo(record) & ~XLR_INFO_MASK;
+	uint8		rminfo = XLogRecGetRmInfo(record);
 
-	switch (info)
+	switch (rminfo)
 	{
 		case XLOG_BTREE_INSERT_LEAF:
 		case XLOG_BTREE_INSERT_UPPER:
@@ -121,11 +121,11 @@ btree_desc(StringInfo buf, XLogReaderState *record)
 }
 
 const char *
-btree_identify(uint8 info)
+btree_identify(uint8 rminfo)
 {
 	const char *id = NULL;
 
-	switch (info & ~XLR_INFO_MASK)
+	switch (rminfo)
 	{
 		case XLOG_BTREE_INSERT_LEAF:
 			id = "INSERT_LEAF";
diff --git a/src/backend/access/rmgrdesc/relmapdesc.c b/src/backend/access/rmgrdesc/relmapdesc.c
index 43d63eb9a4..0f2d0d80fb 100644
--- a/src/backend/access/rmgrdesc/relmapdesc.c
+++ b/src/backend/access/rmgrdesc/relmapdesc.c
@@ -20,9 +20,9 @@ void
 relmap_desc(StringInfo buf, XLogReaderState *record)
 {
 	char	   *rec = XLogRecGetData(record);
-	uint8		info = XLogRecGetInfo(record) & ~XLR_INFO_MASK;
+	uint8		rminfo = XLogRecGetRmInfo(record);
 
-	if (info == XLOG_RELMAP_UPDATE)
+	if (rminfo == XLOG_RELMAP_UPDATE)
 	{
 		xl_relmap_update *xlrec = (xl_relmap_update *) rec;
 
@@ -32,11 +32,11 @@ relmap_desc(StringInfo buf, XLogReaderState *record)
 }
 
 const char *
-relmap_identify(uint8 info)
+relmap_identify(uint8 rminfo)
 {
 	const char *id = NULL;
 
-	switch (info & ~XLR_INFO_MASK)
+	switch (rminfo)
 	{
 		case XLOG_RELMAP_UPDATE:
 			id = "UPDATE";
diff --git a/src/backend/access/rmgrdesc/replorigindesc.c b/src/backend/access/rmgrdesc/replorigindesc.c
index e3213b1016..3bf3fde05f 100644
--- a/src/backend/access/rmgrdesc/replorigindesc.c
+++ b/src/backend/access/rmgrdesc/replorigindesc.c
@@ -19,9 +19,9 @@ void
 replorigin_desc(StringInfo buf, XLogReaderState *record)
 {
 	char	   *rec = XLogRecGetData(record);
-	uint8		info = XLogRecGetInfo(record) & ~XLR_INFO_MASK;
+	uint8		rminfo = XLogRecGetRmInfo(record);
 
-	switch (info)
+	switch (rminfo)
 	{
 		case XLOG_REPLORIGIN_SET:
 			{
@@ -48,9 +48,9 @@ replorigin_desc(StringInfo buf, XLogReaderState *record)
 }
 
 const char *
-replorigin_identify(uint8 info)
+replorigin_identify(uint8 rminfo)
 {
-	switch (info)
+	switch (rminfo)
 	{
 		case XLOG_REPLORIGIN_SET:
 			return "SET";
diff --git a/src/backend/access/rmgrdesc/seqdesc.c b/src/backend/access/rmgrdesc/seqdesc.c
index b3845f93bf..2a4b8367ec 100644
--- a/src/backend/access/rmgrdesc/seqdesc.c
+++ b/src/backend/access/rmgrdesc/seqdesc.c
@@ -21,21 +21,21 @@ void
 seq_desc(StringInfo buf, XLogReaderState *record)
 {
 	char	   *rec = XLogRecGetData(record);
-	uint8		info = XLogRecGetInfo(record) & ~XLR_INFO_MASK;
+	uint8		rminfo = XLogRecGetRmInfo(record);
 	xl_seq_rec *xlrec = (xl_seq_rec *) rec;
 
-	if (info == XLOG_SEQ_LOG)
+	if (rminfo == XLOG_SEQ_LOG)
 		appendStringInfo(buf, "rel %u/%u/%u",
 						 xlrec->locator.spcOid, xlrec->locator.dbOid,
 						 xlrec->locator.relNumber);
 }
 
 const char *
-seq_identify(uint8 info)
+seq_identify(uint8 rminfo)
 {
 	const char *id = NULL;
 
-	switch (info & ~XLR_INFO_MASK)
+	switch (rminfo)
 	{
 		case XLOG_SEQ_LOG:
 			id = "LOG";
diff --git a/src/backend/access/rmgrdesc/smgrdesc.c b/src/backend/access/rmgrdesc/smgrdesc.c
index e0ee8a078a..944f3650cf 100644
--- a/src/backend/access/rmgrdesc/smgrdesc.c
+++ b/src/backend/access/rmgrdesc/smgrdesc.c
@@ -21,9 +21,9 @@ void
 smgr_desc(StringInfo buf, XLogReaderState *record)
 {
 	char	   *rec = XLogRecGetData(record);
-	uint8		info = XLogRecGetInfo(record) & ~XLR_INFO_MASK;
+	uint8		rminfo = XLogRecGetRmInfo(record);
 
-	if (info == XLOG_SMGR_CREATE)
+	if (rminfo == XLOG_SMGR_CREATE)
 	{
 		xl_smgr_create *xlrec = (xl_smgr_create *) rec;
 		char	   *path = relpathperm(xlrec->rlocator, xlrec->forkNum);
@@ -31,7 +31,7 @@ smgr_desc(StringInfo buf, XLogReaderState *record)
 		appendStringInfoString(buf, path);
 		pfree(path);
 	}
-	else if (info == XLOG_SMGR_TRUNCATE)
+	else if (rminfo == XLOG_SMGR_TRUNCATE)
 	{
 		xl_smgr_truncate *xlrec = (xl_smgr_truncate *) rec;
 		char	   *path = relpathperm(xlrec->rlocator, MAIN_FORKNUM);
@@ -43,11 +43,11 @@ smgr_desc(StringInfo buf, XLogReaderState *record)
 }
 
 const char *
-smgr_identify(uint8 info)
+smgr_identify(uint8 rminfo)
 {
 	const char *id = NULL;
 
-	switch (info & ~XLR_INFO_MASK)
+	switch (rminfo)
 	{
 		case XLOG_SMGR_CREATE:
 			id = "CREATE";
diff --git a/src/backend/access/rmgrdesc/spgdesc.c b/src/backend/access/rmgrdesc/spgdesc.c
index d5d921a42a..2afb827de4 100644
--- a/src/backend/access/rmgrdesc/spgdesc.c
+++ b/src/backend/access/rmgrdesc/spgdesc.c
@@ -20,9 +20,9 @@ void
 spg_desc(StringInfo buf, XLogReaderState *record)
 {
 	char	   *rec = XLogRecGetData(record);
-	uint8		info = XLogRecGetInfo(record) & ~XLR_INFO_MASK;
+	uint8		rminfo = XLogRecGetRmInfo(record);
 
-	switch (info)
+	switch (rminfo)
 	{
 		case XLOG_SPGIST_ADD_LEAF:
 			{
@@ -128,11 +128,11 @@ spg_desc(StringInfo buf, XLogReaderState *record)
 }
 
 const char *
-spg_identify(uint8 info)
+spg_identify(uint8 rminfo)
 {
 	const char *id = NULL;
 
-	switch (info & ~XLR_INFO_MASK)
+	switch (rminfo)
 	{
 		case XLOG_SPGIST_ADD_LEAF:
 			id = "ADD_LEAF";
diff --git a/src/backend/access/rmgrdesc/standbydesc.c b/src/backend/access/rmgrdesc/standbydesc.c
index 2dba39e349..5a2e6a323c 100644
--- a/src/backend/access/rmgrdesc/standbydesc.c
+++ b/src/backend/access/rmgrdesc/standbydesc.c
@@ -40,9 +40,9 @@ void
 standby_desc(StringInfo buf, XLogReaderState *record)
 {
 	char	   *rec = XLogRecGetData(record);
-	uint8		info = XLogRecGetInfo(record) & ~XLR_INFO_MASK;
+	uint8		rminfo = XLogRecGetRmInfo(record);
 
-	if (info == XLOG_STANDBY_LOCK)
+	if (rminfo == XLOG_STANDBY_LOCK)
 	{
 		xl_standby_locks *xlrec = (xl_standby_locks *) rec;
 		int			i;
@@ -52,13 +52,13 @@ standby_desc(StringInfo buf, XLogReaderState *record)
 							 xlrec->locks[i].xid, xlrec->locks[i].dbOid,
 							 xlrec->locks[i].relOid);
 	}
-	else if (info == XLOG_RUNNING_XACTS)
+	else if (rminfo == XLOG_RUNNING_XACTS)
 	{
 		xl_running_xacts *xlrec = (xl_running_xacts *) rec;
 
 		standby_desc_running_xacts(buf, xlrec);
 	}
-	else if (info == XLOG_INVALIDATIONS)
+	else if (rminfo == XLOG_INVALIDATIONS)
 	{
 		xl_invalidations *xlrec = (xl_invalidations *) rec;
 
@@ -69,11 +69,11 @@ standby_desc(StringInfo buf, XLogReaderState *record)
 }
 
 const char *
-standby_identify(uint8 info)
+standby_identify(uint8 rminfo)
 {
 	const char *id = NULL;
 
-	switch (info & ~XLR_INFO_MASK)
+	switch (rminfo)
 	{
 		case XLOG_STANDBY_LOCK:
 			id = "LOCK";
diff --git a/src/backend/access/rmgrdesc/tblspcdesc.c b/src/backend/access/rmgrdesc/tblspcdesc.c
index ed94b6e2dd..b8c050fcba 100644
--- a/src/backend/access/rmgrdesc/tblspcdesc.c
+++ b/src/backend/access/rmgrdesc/tblspcdesc.c
@@ -21,15 +21,15 @@ void
 tblspc_desc(StringInfo buf, XLogReaderState *record)
 {
 	char	   *rec = XLogRecGetData(record);
-	uint8		info = XLogRecGetInfo(record) & ~XLR_INFO_MASK;
+	uint8		rminfo = XLogRecGetRmInfo(record);
 
-	if (info == XLOG_TBLSPC_CREATE)
+	if (rminfo == XLOG_TBLSPC_CREATE)
 	{
 		xl_tblspc_create_rec *xlrec = (xl_tblspc_create_rec *) rec;
 
 		appendStringInfo(buf, "%u \"%s\"", xlrec->ts_id, xlrec->ts_path);
 	}
-	else if (info == XLOG_TBLSPC_DROP)
+	else if (rminfo == XLOG_TBLSPC_DROP)
 	{
 		xl_tblspc_drop_rec *xlrec = (xl_tblspc_drop_rec *) rec;
 
@@ -38,11 +38,11 @@ tblspc_desc(StringInfo buf, XLogReaderState *record)
 }
 
 const char *
-tblspc_identify(uint8 info)
+tblspc_identify(uint8 rminfo)
 {
 	const char *id = NULL;
 
-	switch (info & ~XLR_INFO_MASK)
+	switch (rminfo)
 	{
 		case XLOG_TBLSPC_CREATE:
 			id = "CREATE";
diff --git a/src/backend/access/rmgrdesc/xactdesc.c b/src/backend/access/rmgrdesc/xactdesc.c
index 39752cf349..93a653c75a 100644
--- a/src/backend/access/rmgrdesc/xactdesc.c
+++ b/src/backend/access/rmgrdesc/xactdesc.c
@@ -32,7 +32,7 @@
  */
 
 void
-ParseCommitRecord(uint8 info, xl_xact_commit *xlrec, xl_xact_parsed_commit *parsed)
+ParseCommitRecord(uint8 rminfo, xl_xact_commit *xlrec, xl_xact_parsed_commit *parsed)
 {
 	char	   *data = ((char *) xlrec) + MinSizeOfXactCommit;
 
@@ -43,7 +43,7 @@ ParseCommitRecord(uint8 info, xl_xact_commit *xlrec, xl_xact_parsed_commit *pars
 
 	parsed->xact_time = xlrec->xact_time;
 
-	if (info & XLOG_XACT_HAS_INFO)
+	if (rminfo & XLOG_XACT_HAS_INFO)
 	{
 		xl_xact_xinfo *xl_xinfo = (xl_xact_xinfo *) data;
 
@@ -138,7 +138,7 @@ ParseCommitRecord(uint8 info, xl_xact_commit *xlrec, xl_xact_parsed_commit *pars
 }
 
 void
-ParseAbortRecord(uint8 info, xl_xact_abort *xlrec, xl_xact_parsed_abort *parsed)
+ParseAbortRecord(uint8 rminfo, xl_xact_abort *xlrec, xl_xact_parsed_abort *parsed)
 {
 	char	   *data = ((char *) xlrec) + MinSizeOfXactAbort;
 
@@ -149,7 +149,7 @@ ParseAbortRecord(uint8 info, xl_xact_abort *xlrec, xl_xact_parsed_abort *parsed)
 
 	parsed->xact_time = xlrec->xact_time;
 
-	if (info & XLOG_XACT_HAS_INFO)
+	if (rminfo & XLOG_XACT_HAS_INFO)
 	{
 		xl_xact_xinfo *xl_xinfo = (xl_xact_xinfo *) data;
 
@@ -236,7 +236,7 @@ ParseAbortRecord(uint8 info, xl_xact_abort *xlrec, xl_xact_parsed_abort *parsed)
  * ParsePrepareRecord
  */
 void
-ParsePrepareRecord(uint8 info, xl_xact_prepare *xlrec, xl_xact_parsed_prepare *parsed)
+ParsePrepareRecord(uint8 rminfo, xl_xact_prepare *xlrec, xl_xact_parsed_prepare *parsed)
 {
 	char	   *bufptr;
 
@@ -328,11 +328,11 @@ xact_desc_stats(StringInfo buf, const char *label,
 }
 
 static void
-xact_desc_commit(StringInfo buf, uint8 info, xl_xact_commit *xlrec, RepOriginId origin_id)
+xact_desc_commit(StringInfo buf, uint8 rminfo, xl_xact_commit *xlrec, RepOriginId origin_id)
 {
 	xl_xact_parsed_commit parsed;
 
-	ParseCommitRecord(info, xlrec, &parsed);
+	ParseCommitRecord(rminfo, xlrec, &parsed);
 
 	/* If this is a prepared xact, show the xid of the original xact */
 	if (TransactionIdIsValid(parsed.twophase_xid))
@@ -364,11 +364,11 @@ xact_desc_commit(StringInfo buf, uint8 info, xl_xact_commit *xlrec, RepOriginId
 }
 
 static void
-xact_desc_abort(StringInfo buf, uint8 info, xl_xact_abort *xlrec, RepOriginId origin_id)
+xact_desc_abort(StringInfo buf, uint8 rminfo, xl_xact_abort *xlrec, RepOriginId origin_id)
 {
 	xl_xact_parsed_abort parsed;
 
-	ParseAbortRecord(info, xlrec, &parsed);
+	ParseAbortRecord(rminfo, xlrec, &parsed);
 
 	/* If this is a prepared xact, show the xid of the original xact */
 	if (TransactionIdIsValid(parsed.twophase_xid))
@@ -391,11 +391,11 @@ xact_desc_abort(StringInfo buf, uint8 info, xl_xact_abort *xlrec, RepOriginId or
 }
 
 static void
-xact_desc_prepare(StringInfo buf, uint8 info, xl_xact_prepare *xlrec, RepOriginId origin_id)
+xact_desc_prepare(StringInfo buf, uint8 rminfo, xl_xact_prepare *xlrec, RepOriginId origin_id)
 {
 	xl_xact_parsed_prepare parsed;
 
-	ParsePrepareRecord(info, xlrec, &parsed);
+	ParsePrepareRecord(rminfo, xlrec, &parsed);
 
 	appendStringInfo(buf, "gid %s: ", parsed.twophase_gid);
 	appendStringInfoString(buf, timestamptz_to_str(parsed.xact_time));
@@ -436,27 +436,27 @@ void
 xact_desc(StringInfo buf, XLogReaderState *record)
 {
 	char	   *rec = XLogRecGetData(record);
-	uint8		info = XLogRecGetInfo(record) & XLOG_XACT_OPMASK;
+	uint8		info = XLogRecGetRmInfo(record) & XLOG_XACT_OPMASK;
 
 	if (info == XLOG_XACT_COMMIT || info == XLOG_XACT_COMMIT_PREPARED)
 	{
 		xl_xact_commit *xlrec = (xl_xact_commit *) rec;
 
-		xact_desc_commit(buf, XLogRecGetInfo(record), xlrec,
+		xact_desc_commit(buf, XLogRecGetRmInfo(record), xlrec,
 						 XLogRecGetOrigin(record));
 	}
 	else if (info == XLOG_XACT_ABORT || info == XLOG_XACT_ABORT_PREPARED)
 	{
 		xl_xact_abort *xlrec = (xl_xact_abort *) rec;
 
-		xact_desc_abort(buf, XLogRecGetInfo(record), xlrec,
+		xact_desc_abort(buf, XLogRecGetRmInfo(record), xlrec,
 						XLogRecGetOrigin(record));
 	}
 	else if (info == XLOG_XACT_PREPARE)
 	{
 		xl_xact_prepare *xlrec = (xl_xact_prepare *) rec;
 
-		xact_desc_prepare(buf, XLogRecGetInfo(record), xlrec,
+		xact_desc_prepare(buf, XLogRecGetRmInfo(record), xlrec,
 						  XLogRecGetOrigin(record));
 	}
 	else if (info == XLOG_XACT_ASSIGNMENT)
@@ -481,11 +481,11 @@ xact_desc(StringInfo buf, XLogReaderState *record)
 }
 
 const char *
-xact_identify(uint8 info)
+xact_identify(uint8 rminfo)
 {
 	const char *id = NULL;
 
-	switch (info & XLOG_XACT_OPMASK)
+	switch (rminfo & XLOG_XACT_OPMASK)
 	{
 		case XLOG_XACT_COMMIT:
 			id = "COMMIT";
diff --git a/src/backend/access/rmgrdesc/xlogdesc.c b/src/backend/access/rmgrdesc/xlogdesc.c
index 3fd7185f21..65ac642908 100644
--- a/src/backend/access/rmgrdesc/xlogdesc.c
+++ b/src/backend/access/rmgrdesc/xlogdesc.c
@@ -37,10 +37,10 @@ void
 xlog_desc(StringInfo buf, XLogReaderState *record)
 {
 	char	   *rec = XLogRecGetData(record);
-	uint8		info = XLogRecGetInfo(record) & ~XLR_INFO_MASK;
+	uint8		rminfo = XLogRecGetRmInfo(record);
 
-	if (info == XLOG_CHECKPOINT_SHUTDOWN ||
-		info == XLOG_CHECKPOINT_ONLINE)
+	if (rminfo == XLOG_CHECKPOINT_SHUTDOWN ||
+		rminfo == XLOG_CHECKPOINT_ONLINE)
 	{
 		CheckPoint *checkpoint = (CheckPoint *) rec;
 
@@ -65,33 +65,33 @@ xlog_desc(StringInfo buf, XLogReaderState *record)
 						 checkpoint->oldestCommitTsXid,
 						 checkpoint->newestCommitTsXid,
 						 checkpoint->oldestActiveXid,
-						 (info == XLOG_CHECKPOINT_SHUTDOWN) ? "shutdown" : "online");
+						 (rminfo == XLOG_CHECKPOINT_SHUTDOWN) ? "shutdown" : "online");
 	}
-	else if (info == XLOG_NEXTOID)
+	else if (rminfo == XLOG_NEXTOID)
 	{
 		Oid			nextOid;
 
 		memcpy(&nextOid, rec, sizeof(Oid));
 		appendStringInfo(buf, "%u", nextOid);
 	}
-	else if (info == XLOG_RESTORE_POINT)
+	else if (rminfo == XLOG_RESTORE_POINT)
 	{
 		xl_restore_point *xlrec = (xl_restore_point *) rec;
 
 		appendStringInfoString(buf, xlrec->rp_name);
 	}
-	else if (info == XLOG_FPI || info == XLOG_FPI_FOR_HINT)
+	else if (rminfo == XLOG_FPI || rminfo == XLOG_FPI_FOR_HINT)
 	{
 		/* no further information to print */
 	}
-	else if (info == XLOG_BACKUP_END)
+	else if (rminfo == XLOG_BACKUP_END)
 	{
 		XLogRecPtr	startpoint;
 
 		memcpy(&startpoint, rec, sizeof(XLogRecPtr));
 		appendStringInfo(buf, "%X/%X", LSN_FORMAT_ARGS(startpoint));
 	}
-	else if (info == XLOG_PARAMETER_CHANGE)
+	else if (rminfo == XLOG_PARAMETER_CHANGE)
 	{
 		xl_parameter_change xlrec;
 		const char *wal_level_str;
@@ -123,14 +123,14 @@ xlog_desc(StringInfo buf, XLogReaderState *record)
 						 xlrec.wal_log_hints ? "on" : "off",
 						 xlrec.track_commit_timestamp ? "on" : "off");
 	}
-	else if (info == XLOG_FPW_CHANGE)
+	else if (rminfo == XLOG_FPW_CHANGE)
 	{
 		bool		fpw;
 
 		memcpy(&fpw, rec, sizeof(bool));
 		appendStringInfoString(buf, fpw ? "true" : "false");
 	}
-	else if (info == XLOG_END_OF_RECOVERY)
+	else if (rminfo == XLOG_END_OF_RECOVERY)
 	{
 		xl_end_of_recovery xlrec;
 
@@ -139,7 +139,7 @@ xlog_desc(StringInfo buf, XLogReaderState *record)
 						 xlrec.ThisTimeLineID, xlrec.PrevTimeLineID,
 						 timestamptz_to_str(xlrec.end_time));
 	}
-	else if (info == XLOG_OVERWRITE_CONTRECORD)
+	else if (rminfo == XLOG_OVERWRITE_CONTRECORD)
 	{
 		xl_overwrite_contrecord xlrec;
 
@@ -151,11 +151,11 @@ xlog_desc(StringInfo buf, XLogReaderState *record)
 }
 
 const char *
-xlog_identify(uint8 info)
+xlog_identify(uint8 rminfo)
 {
 	const char *id = NULL;
 
-	switch (info & ~XLR_INFO_MASK)
+	switch (rminfo)
 	{
 		case XLOG_CHECKPOINT_SHUTDOWN:
 			id = "CHECKPOINT_SHUTDOWN";
diff --git a/src/backend/access/spgist/spgxlog.c b/src/backend/access/spgist/spgxlog.c
index 4c9f4020ff..cb3b864227 100644
--- a/src/backend/access/spgist/spgxlog.c
+++ b/src/backend/access/spgist/spgxlog.c
@@ -938,11 +938,11 @@ spgRedoVacuumRedirect(XLogReaderState *record)
 void
 spg_redo(XLogReaderState *record)
 {
-	uint8		info = XLogRecGetInfo(record) & ~XLR_INFO_MASK;
+	uint8		rminfo = XLogRecGetRmInfo(record);
 	MemoryContext oldCxt;
 
 	oldCxt = MemoryContextSwitchTo(opCtx);
-	switch (info)
+	switch (rminfo)
 	{
 		case XLOG_SPGIST_ADD_LEAF:
 			spgRedoAddLeaf(record);
@@ -969,7 +969,7 @@ spg_redo(XLogReaderState *record)
 			spgRedoVacuumRedirect(record);
 			break;
 		default:
-			elog(PANIC, "spg_redo: unknown op code %u", info);
+			elog(PANIC, "spg_redo: unknown op code %u", rminfo);
 	}
 
 	MemoryContextSwitchTo(oldCxt);
diff --git a/src/backend/access/transam/clog.c b/src/backend/access/transam/clog.c
index 3d9088a704..1376688408 100644
--- a/src/backend/access/transam/clog.c
+++ b/src/backend/access/transam/clog.c
@@ -986,12 +986,12 @@ WriteTruncateXlogRec(int pageno, TransactionId oldestXact, Oid oldestXactDb)
 void
 clog_redo(XLogReaderState *record)
 {
-	uint8		info = XLogRecGetInfo(record) & ~XLR_INFO_MASK;
+	uint8		rminfo = XLogRecGetRmInfo(record);
 
 	/* Backup blocks are not used in clog records */
 	Assert(!XLogRecHasAnyBlockRefs(record));
 
-	if (info == CLOG_ZEROPAGE)
+	if (rminfo == CLOG_ZEROPAGE)
 	{
 		int			pageno;
 		int			slotno;
@@ -1006,7 +1006,7 @@ clog_redo(XLogReaderState *record)
 
 		LWLockRelease(XactSLRULock);
 	}
-	else if (info == CLOG_TRUNCATE)
+	else if (rminfo == CLOG_TRUNCATE)
 	{
 		xl_clog_truncate xlrec;
 
@@ -1017,7 +1017,7 @@ clog_redo(XLogReaderState *record)
 		SimpleLruTruncate(XactCtl, xlrec.pageno);
 	}
 	else
-		elog(PANIC, "clog_redo: unknown op code %u", info);
+		elog(PANIC, "clog_redo: unknown op code %u", rminfo);
 }
 
 /*
diff --git a/src/backend/access/transam/commit_ts.c b/src/backend/access/transam/commit_ts.c
index 9aa4675cb7..43129c7a6f 100644
--- a/src/backend/access/transam/commit_ts.c
+++ b/src/backend/access/transam/commit_ts.c
@@ -984,12 +984,12 @@ WriteTruncateXlogRec(int pageno, TransactionId oldestXid)
 void
 commit_ts_redo(XLogReaderState *record)
 {
-	uint8		info = XLogRecGetInfo(record) & ~XLR_INFO_MASK;
+	uint8		rminfo = XLogRecGetRmInfo(record);
 
 	/* Backup blocks are not used in commit_ts records */
 	Assert(!XLogRecHasAnyBlockRefs(record));
 
-	if (info == COMMIT_TS_ZEROPAGE)
+	if (rminfo == COMMIT_TS_ZEROPAGE)
 	{
 		int			pageno;
 		int			slotno;
@@ -1004,7 +1004,7 @@ commit_ts_redo(XLogReaderState *record)
 
 		LWLockRelease(CommitTsSLRULock);
 	}
-	else if (info == COMMIT_TS_TRUNCATE)
+	else if (rminfo == COMMIT_TS_TRUNCATE)
 	{
 		xl_commit_ts_truncate *trunc = (xl_commit_ts_truncate *) XLogRecGetData(record);
 
@@ -1019,7 +1019,7 @@ commit_ts_redo(XLogReaderState *record)
 		SimpleLruTruncate(CommitTsCtl, trunc->pageno);
 	}
 	else
-		elog(PANIC, "commit_ts_redo: unknown op code %u", info);
+		elog(PANIC, "commit_ts_redo: unknown op code %u", rminfo);
 }
 
 /*
diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c
index a7383f553b..c0e1e4ae49 100644
--- a/src/backend/access/transam/multixact.c
+++ b/src/backend/access/transam/multixact.c
@@ -365,7 +365,7 @@ static bool MultiXactOffsetWouldWrap(MultiXactOffset boundary,
 									 MultiXactOffset start, uint32 distance);
 static bool SetOffsetVacuumLimit(bool is_startup);
 static bool find_multixact_start(MultiXactId multi, MultiXactOffset *result);
-static void WriteMZeroPageXlogRec(int pageno, uint8 info);
+static void WriteMZeroPageXlogRec(int pageno, uint8 rminfo);
 static void WriteMTruncateXlogRec(Oid oldestMultiDB,
 								  MultiXactId startTruncOff,
 								  MultiXactId endTruncOff,
@@ -650,7 +650,7 @@ MultiXactIdSetOldestMember(void)
 		 * must be sure to store a valid value in our array entry.
 		 */
 		nextMXact = MultiXactState->nextMXact;
-		if (nextMXact < FirstMultiXactId)
+		if (!MultiXactIdIsNormal(nextMXact))
 			nextMXact = FirstMultiXactId;
 
 		OldestMemberMXactId[MyBackendId] = nextMXact;
@@ -694,7 +694,7 @@ MultiXactIdSetOldestVisible(void)
 		 * must be sure to store a valid value in our array entry.
 		 */
 		oldestMXact = MultiXactState->nextMXact;
-		if (oldestMXact < FirstMultiXactId)
+		if (!MultiXactIdIsNormal(oldestMXact))
 			oldestMXact = FirstMultiXactId;
 
 		for (i = 1; i <= MaxOldestSlot; i++)
@@ -729,7 +729,7 @@ ReadNextMultiXactId(void)
 	mxid = MultiXactState->nextMXact;
 	LWLockRelease(MultiXactGenLock);
 
-	if (mxid < FirstMultiXactId)
+	if (!MultiXactIdIsNormal(mxid))
 		mxid = FirstMultiXactId;
 
 	return mxid;
@@ -747,9 +747,9 @@ ReadMultiXactIdRange(MultiXactId *oldest, MultiXactId *next)
 	*next = MultiXactState->nextMXact;
 	LWLockRelease(MultiXactGenLock);
 
-	if (*oldest < FirstMultiXactId)
+	if (!MultiXactIdIsNormal(*oldest))
 		*oldest = FirstMultiXactId;
-	if (*next < FirstMultiXactId)
+	if (!MultiXactIdIsNormal(*next))
 		*next = FirstMultiXactId;
 }
 
@@ -967,7 +967,7 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset)
 	LWLockAcquire(MultiXactGenLock, LW_EXCLUSIVE);
 
 	/* Handle wraparound of the nextMXact counter */
-	if (MultiXactState->nextMXact < FirstMultiXactId)
+	if (!MultiXactIdIsNormal(MultiXactState->nextMXact))
 		MultiXactState->nextMXact = FirstMultiXactId;
 
 	/* Assign the MXID */
@@ -1067,7 +1067,7 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset)
 		/* Re-acquire lock and start over */
 		LWLockAcquire(MultiXactGenLock, LW_EXCLUSIVE);
 		result = MultiXactState->nextMXact;
-		if (result < FirstMultiXactId)
+		if (!MultiXactIdIsNormal(result))
 			result = FirstMultiXactId;
 	}
 
@@ -1368,7 +1368,7 @@ retry:
 		MultiXactOffset nextMXOffset;
 
 		/* handle wraparound if needed */
-		if (tmpMXact < FirstMultiXactId)
+		if (!MultiXactIdIsNormal(tmpMXact))
 			tmpMXact = FirstMultiXactId;
 
 		prev_pageno = pageno;
@@ -2229,7 +2229,7 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid,
 	 * wrap.  Limits for that are set in SetOffsetVacuumLimit, not here.
 	 */
 	multiWrapLimit = oldest_datminmxid + (MaxMultiXactId >> 1);
-	if (multiWrapLimit < FirstMultiXactId)
+	if (!MultiXactIdIsNormal(multiWrapLimit))
 		multiWrapLimit += FirstMultiXactId;
 
 	/*
@@ -2237,7 +2237,7 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid,
 	 * multi of data loss.  See SetTransactionIdLimit.
 	 */
 	multiStopLimit = multiWrapLimit - 3000000;
-	if (multiStopLimit < FirstMultiXactId)
+	if (!MultiXactIdIsNormal(multiStopLimit))
 		multiStopLimit -= FirstMultiXactId;
 
 	/*
@@ -2251,7 +2251,7 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid,
 	 * not get in this kind of trouble in the first place.)
 	 */
 	multiWarnLimit = multiWrapLimit - 40000000;
-	if (multiWarnLimit < FirstMultiXactId)
+	if (!MultiXactIdIsNormal(multiWarnLimit))
 		multiWarnLimit -= FirstMultiXactId;
 
 	/*
@@ -2263,7 +2263,7 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid,
 	 * its value.  See SetTransactionIdLimit.
 	 */
 	multiVacLimit = oldest_datminmxid + autovacuum_multixact_freeze_max_age;
-	if (multiVacLimit < FirstMultiXactId)
+	if (!MultiXactIdIsNormal(multiVacLimit))
 		multiVacLimit += FirstMultiXactId;
 
 	/* Grab lock for just long enough to set the new limit values */
@@ -2520,7 +2520,7 @@ GetOldestMultiXactId(void)
 	 * must be sure to use a valid value in our calculation.
 	 */
 	nextMXact = MultiXactState->nextMXact;
-	if (nextMXact < FirstMultiXactId)
+	if (!MultiXactIdIsNormal(nextMXact))
 		nextMXact = FirstMultiXactId;
 
 	oldestMXact = nextMXact;
@@ -3000,7 +3000,7 @@ TruncateMultiXact(MultiXactId newOldestMulti, Oid newOldestMultiDB)
 	trunc.earliestExistingPage = -1;
 	SlruScanDirectory(MultiXactOffsetCtl, SlruScanDirCbFindEarliest, &trunc);
 	earliest = trunc.earliestExistingPage * MULTIXACT_OFFSETS_PER_PAGE;
-	if (earliest < FirstMultiXactId)
+	if (!MultiXactIdIsNormal(earliest))
 		earliest = FirstMultiXactId;
 
 	/* If there's nothing to remove, we can bail out early. */
@@ -3193,11 +3193,11 @@ MultiXactOffsetPrecedes(MultiXactOffset offset1, MultiXactOffset offset2)
  * OFFSETs page (info shows which)
  */
 static void
-WriteMZeroPageXlogRec(int pageno, uint8 info)
+WriteMZeroPageXlogRec(int pageno, uint8 rminfo)
 {
 	XLogBeginInsert();
 	XLogRegisterData((char *) (&pageno), sizeof(int));
-	(void) XLogInsert(RM_MULTIXACT_ID, info);
+	(void) XLogInsert(RM_MULTIXACT_ID, rminfo);
 }
 
 /*
@@ -3234,12 +3234,12 @@ WriteMTruncateXlogRec(Oid oldestMultiDB,
 void
 multixact_redo(XLogReaderState *record)
 {
-	uint8		info = XLogRecGetInfo(record) & ~XLR_INFO_MASK;
+	uint8		rminfo = XLogRecGetRmInfo(record);
 
 	/* Backup blocks are not used in multixact records */
 	Assert(!XLogRecHasAnyBlockRefs(record));
 
-	if (info == XLOG_MULTIXACT_ZERO_OFF_PAGE)
+	if (rminfo == XLOG_MULTIXACT_ZERO_OFF_PAGE)
 	{
 		int			pageno;
 		int			slotno;
@@ -3254,7 +3254,7 @@ multixact_redo(XLogReaderState *record)
 
 		LWLockRelease(MultiXactOffsetSLRULock);
 	}
-	else if (info == XLOG_MULTIXACT_ZERO_MEM_PAGE)
+	else if (rminfo == XLOG_MULTIXACT_ZERO_MEM_PAGE)
 	{
 		int			pageno;
 		int			slotno;
@@ -3269,7 +3269,7 @@ multixact_redo(XLogReaderState *record)
 
 		LWLockRelease(MultiXactMemberSLRULock);
 	}
-	else if (info == XLOG_MULTIXACT_CREATE_ID)
+	else if (rminfo == XLOG_MULTIXACT_CREATE_ID)
 	{
 		xl_multixact_create *xlrec =
 		(xl_multixact_create *) XLogRecGetData(record);
@@ -3298,7 +3298,7 @@ multixact_redo(XLogReaderState *record)
 
 		AdvanceNextFullTransactionIdPastXid(max_xid);
 	}
-	else if (info == XLOG_MULTIXACT_TRUNCATE_ID)
+	else if (rminfo == XLOG_MULTIXACT_TRUNCATE_ID)
 	{
 		xl_multixact_truncate xlrec;
 		int			pageno;
@@ -3339,7 +3339,7 @@ multixact_redo(XLogReaderState *record)
 		LWLockRelease(MultiXactTruncationLock);
 	}
 	else
-		elog(PANIC, "multixact_redo: unknown op code %u", info);
+		elog(PANIC, "multixact_redo: unknown op code %u", rminfo);
 }
 
 Datum
@@ -3355,7 +3355,7 @@ pg_get_multixact_members(PG_FUNCTION_ARGS)
 	mxact	   *multi;
 	FuncCallContext *funccxt;
 
-	if (mxid < FirstMultiXactId)
+	if (!MultiXactIdIsValid(mxid))
 		ereport(ERROR,
 				(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
 				 errmsg("invalid MultiXactId: %u", mxid)));
diff --git a/src/backend/access/transam/twophase.c b/src/backend/access/transam/twophase.c
index 803d169f57..98c1ef7ec5 100644
--- a/src/backend/access/transam/twophase.c
+++ b/src/backend/access/transam/twophase.c
@@ -1429,7 +1429,7 @@ XlogReadTwoPhaseData(XLogRecPtr lsn, char **buf, int *len)
 	}
 
 	if (XLogRecGetRmid(xlogreader) != RM_XACT_ID ||
-		(XLogRecGetInfo(xlogreader) & XLOG_XACT_OPMASK) != XLOG_XACT_PREPARE)
+		(XLogRecGetRmInfo(xlogreader) & XLOG_XACT_OPMASK) != XLOG_XACT_PREPARE)
 		ereport(ERROR,
 				(errcode_for_file_access(),
 				 errmsg("expected two-phase state data is not present in WAL at %X/%X",
diff --git a/src/backend/access/transam/xact.c b/src/backend/access/transam/xact.c
index 2bb975943c..931343715e 100644
--- a/src/backend/access/transam/xact.c
+++ b/src/backend/access/transam/xact.c
@@ -5614,7 +5614,8 @@ XactLogCommitRecord(TimestampTz commit_time,
 	xl_xact_invals xl_invals;
 	xl_xact_twophase xl_twophase;
 	xl_xact_origin xl_origin;
-	uint8		info;
+	uint8		rminfo;
+	uint8		info = 0;
 
 	Assert(CritSectionCount > 0);
 
@@ -5622,9 +5623,9 @@ XactLogCommitRecord(TimestampTz commit_time,
 
 	/* decide between a plain and 2pc commit */
 	if (!TransactionIdIsValid(twophase_xid))
-		info = XLOG_XACT_COMMIT;
+		rminfo = XLOG_XACT_COMMIT;
 	else
-		info = XLOG_XACT_COMMIT_PREPARED;
+		rminfo = XLOG_XACT_COMMIT_PREPARED;
 
 	/* First figure out and collect all the information needed */
 
@@ -5665,7 +5666,7 @@ XactLogCommitRecord(TimestampTz commit_time,
 	{
 		xl_xinfo.xinfo |= XACT_XINFO_HAS_RELFILELOCATORS;
 		xl_relfilelocators.nrels = nrels;
-		info |= XLR_SPECIAL_REL_UPDATE;
+		info = XLR_SPECIAL_REL_UPDATE;
 	}
 
 	if (ndroppedstats > 0)
@@ -5700,7 +5701,7 @@ XactLogCommitRecord(TimestampTz commit_time,
 	}
 
 	if (xl_xinfo.xinfo != 0)
-		info |= XLOG_XACT_HAS_INFO;
+		rminfo |= XLOG_XACT_HAS_INFO;
 
 	/* Then include all the collected data into the commit record. */
 
@@ -5758,7 +5759,7 @@ XactLogCommitRecord(TimestampTz commit_time,
 	/* we allow filtering by xacts */
 	XLogSetRecordFlags(XLOG_INCLUDE_ORIGIN);
 
-	return XLogInsert(RM_XACT_ID, info);
+	return XLogInsertExtended(RM_XACT_ID, info, rminfo);
 }
 
 /*
@@ -5784,7 +5785,8 @@ XactLogAbortRecord(TimestampTz abort_time,
 	xl_xact_dbinfo xl_dbinfo;
 	xl_xact_origin xl_origin;
 
-	uint8		info;
+	uint8		rminfo;
+	uint8		info = 0;
 
 	Assert(CritSectionCount > 0);
 
@@ -5792,9 +5794,9 @@ XactLogAbortRecord(TimestampTz abort_time,
 
 	/* decide between a plain and 2pc abort */
 	if (!TransactionIdIsValid(twophase_xid))
-		info = XLOG_XACT_ABORT;
+		rminfo = XLOG_XACT_ABORT;
 	else
-		info = XLOG_XACT_ABORT_PREPARED;
+		rminfo = XLOG_XACT_ABORT_PREPARED;
 
 
 	/* First figure out and collect all the information needed */
@@ -5814,7 +5816,7 @@ XactLogAbortRecord(TimestampTz abort_time,
 	{
 		xl_xinfo.xinfo |= XACT_XINFO_HAS_RELFILELOCATORS;
 		xl_relfilelocators.nrels = nrels;
-		info |= XLR_SPECIAL_REL_UPDATE;
+		info = XLR_SPECIAL_REL_UPDATE;
 	}
 
 	if (ndroppedstats > 0)
@@ -5854,7 +5856,7 @@ XactLogAbortRecord(TimestampTz abort_time,
 	}
 
 	if (xl_xinfo.xinfo != 0)
-		info |= XLOG_XACT_HAS_INFO;
+		rminfo |= XLOG_XACT_HAS_INFO;
 
 	/* Then include all the collected data into the abort record. */
 
@@ -5905,7 +5907,7 @@ XactLogAbortRecord(TimestampTz abort_time,
 	if (TransactionIdIsValid(twophase_xid))
 		XLogSetRecordFlags(XLOG_INCLUDE_ORIGIN);
 
-	return XLogInsert(RM_XACT_ID, info);
+	return XLogInsertExtended(RM_XACT_ID, info, rminfo);
 }
 
 /*
@@ -6148,7 +6150,7 @@ xact_redo_abort(xl_xact_parsed_abort *parsed, TransactionId xid,
 void
 xact_redo(XLogReaderState *record)
 {
-	uint8		info = XLogRecGetInfo(record) & XLOG_XACT_OPMASK;
+	uint8		info = XLogRecGetRmInfo(record) & XLOG_XACT_OPMASK;
 
 	/* Backup blocks are not used in xact records */
 	Assert(!XLogRecHasAnyBlockRefs(record));
@@ -6158,7 +6160,7 @@ xact_redo(XLogReaderState *record)
 		xl_xact_commit *xlrec = (xl_xact_commit *) XLogRecGetData(record);
 		xl_xact_parsed_commit parsed;
 
-		ParseCommitRecord(XLogRecGetInfo(record), xlrec, &parsed);
+		ParseCommitRecord(XLogRecGetRmInfo(record), xlrec, &parsed);
 		xact_redo_commit(&parsed, XLogRecGetXid(record),
 						 record->EndRecPtr, XLogRecGetOrigin(record));
 	}
@@ -6167,7 +6169,7 @@ xact_redo(XLogReaderState *record)
 		xl_xact_commit *xlrec = (xl_xact_commit *) XLogRecGetData(record);
 		xl_xact_parsed_commit parsed;
 
-		ParseCommitRecord(XLogRecGetInfo(record), xlrec, &parsed);
+		ParseCommitRecord(XLogRecGetRmInfo(record), xlrec, &parsed);
 		xact_redo_commit(&parsed, parsed.twophase_xid,
 						 record->EndRecPtr, XLogRecGetOrigin(record));
 
@@ -6181,7 +6183,7 @@ xact_redo(XLogReaderState *record)
 		xl_xact_abort *xlrec = (xl_xact_abort *) XLogRecGetData(record);
 		xl_xact_parsed_abort parsed;
 
-		ParseAbortRecord(XLogRecGetInfo(record), xlrec, &parsed);
+		ParseAbortRecord(XLogRecGetRmInfo(record), xlrec, &parsed);
 		xact_redo_abort(&parsed, XLogRecGetXid(record),
 						record->EndRecPtr, XLogRecGetOrigin(record));
 	}
@@ -6190,7 +6192,7 @@ xact_redo(XLogReaderState *record)
 		xl_xact_abort *xlrec = (xl_xact_abort *) XLogRecGetData(record);
 		xl_xact_parsed_abort parsed;
 
-		ParseAbortRecord(XLogRecGetInfo(record), xlrec, &parsed);
+		ParseAbortRecord(XLogRecGetRmInfo(record), xlrec, &parsed);
 		xact_redo_abort(&parsed, parsed.twophase_xid,
 						record->EndRecPtr, XLogRecGetOrigin(record));
 
diff --git a/src/backend/access/transam/xlog.c b/src/backend/access/transam/xlog.c
index f32b2124e6..9c76b3cdd1 100644
--- a/src/backend/access/transam/xlog.c
+++ b/src/backend/access/transam/xlog.c
@@ -742,9 +742,9 @@ XLogInsertRecord(XLogRecData *rdata,
 	pg_crc32c	rdata_crc;
 	bool		inserted;
 	XLogRecord *rechdr = (XLogRecord *) rdata->data;
-	uint8		info = rechdr->xl_info & ~XLR_INFO_MASK;
+	uint8		rminfo = rechdr->xl_rminfo;
 	bool		isLogSwitch = (rechdr->xl_rmid == RM_XLOG_ID &&
-							   info == XLOG_SWITCH);
+							   rminfo == XLOG_SWITCH);
 	XLogRecPtr	StartPos;
 	XLogRecPtr	EndPos;
 	bool		prevDoPageWrites = doPageWrites;
@@ -7728,17 +7728,17 @@ UpdateFullPageWrites(void)
 void
 xlog_redo(XLogReaderState *record)
 {
-	uint8		info = XLogRecGetInfo(record) & ~XLR_INFO_MASK;
+	uint8		rminfo = XLogRecGetRmInfo(record);
 	XLogRecPtr	lsn = record->EndRecPtr;
 
 	/*
 	 * In XLOG rmgr, backup blocks are only used by XLOG_FPI and
 	 * XLOG_FPI_FOR_HINT records.
 	 */
-	Assert(info == XLOG_FPI || info == XLOG_FPI_FOR_HINT ||
+	Assert(rminfo == XLOG_FPI || rminfo == XLOG_FPI_FOR_HINT ||
 		   !XLogRecHasAnyBlockRefs(record));
 
-	if (info == XLOG_NEXTOID)
+	if (rminfo == XLOG_NEXTOID)
 	{
 		Oid			nextOid;
 
@@ -7755,7 +7755,7 @@ xlog_redo(XLogReaderState *record)
 		ShmemVariableCache->oidCount = 0;
 		LWLockRelease(OidGenLock);
 	}
-	else if (info == XLOG_CHECKPOINT_SHUTDOWN)
+	else if (rminfo == XLOG_CHECKPOINT_SHUTDOWN)
 	{
 		CheckPoint	checkPoint;
 		TimeLineID	replayTLI;
@@ -7852,7 +7852,7 @@ xlog_redo(XLogReaderState *record)
 
 		RecoveryRestartPoint(&checkPoint, record);
 	}
-	else if (info == XLOG_CHECKPOINT_ONLINE)
+	else if (rminfo == XLOG_CHECKPOINT_ONLINE)
 	{
 		CheckPoint	checkPoint;
 		TimeLineID	replayTLI;
@@ -7910,11 +7910,11 @@ xlog_redo(XLogReaderState *record)
 
 		RecoveryRestartPoint(&checkPoint, record);
 	}
-	else if (info == XLOG_OVERWRITE_CONTRECORD)
+	else if (rminfo == XLOG_OVERWRITE_CONTRECORD)
 	{
 		/* nothing to do here, handled in xlogrecovery_redo() */
 	}
-	else if (info == XLOG_END_OF_RECOVERY)
+	else if (rminfo == XLOG_END_OF_RECOVERY)
 	{
 		xl_end_of_recovery xlrec;
 		TimeLineID	replayTLI;
@@ -7937,19 +7937,19 @@ xlog_redo(XLogReaderState *record)
 					(errmsg("unexpected timeline ID %u (should be %u) in end-of-recovery record",
 							xlrec.ThisTimeLineID, replayTLI)));
 	}
-	else if (info == XLOG_NOOP)
+	else if (rminfo == XLOG_NOOP)
 	{
 		/* nothing to do here */
 	}
-	else if (info == XLOG_SWITCH)
+	else if (rminfo == XLOG_SWITCH)
 	{
 		/* nothing to do here */
 	}
-	else if (info == XLOG_RESTORE_POINT)
+	else if (rminfo == XLOG_RESTORE_POINT)
 	{
 		/* nothing to do here, handled in xlogrecovery.c */
 	}
-	else if (info == XLOG_FPI || info == XLOG_FPI_FOR_HINT)
+	else if (rminfo == XLOG_FPI || rminfo == XLOG_FPI_FOR_HINT)
 	{
 		/*
 		 * XLOG_FPI records contain nothing else but one or more block
@@ -7973,7 +7973,7 @@ xlog_redo(XLogReaderState *record)
 
 			if (!XLogRecHasBlockImage(record, block_id))
 			{
-				if (info == XLOG_FPI)
+				if (rminfo == XLOG_FPI)
 					elog(ERROR, "XLOG_FPI record did not contain a full-page image");
 				continue;
 			}
@@ -7983,11 +7983,11 @@ xlog_redo(XLogReaderState *record)
 			UnlockReleaseBuffer(buffer);
 		}
 	}
-	else if (info == XLOG_BACKUP_END)
+	else if (rminfo == XLOG_BACKUP_END)
 	{
 		/* nothing to do here, handled in xlogrecovery_redo() */
 	}
-	else if (info == XLOG_PARAMETER_CHANGE)
+	else if (rminfo == XLOG_PARAMETER_CHANGE)
 	{
 		xl_parameter_change xlrec;
 
@@ -8035,7 +8035,7 @@ xlog_redo(XLogReaderState *record)
 		/* Check to see if any parameter change gives a problem on recovery */
 		CheckRequiredParameterValues();
 	}
-	else if (info == XLOG_FPW_CHANGE)
+	else if (rminfo == XLOG_FPW_CHANGE)
 	{
 		bool		fpw;
 
diff --git a/src/backend/access/transam/xloginsert.c b/src/backend/access/transam/xloginsert.c
index 5ca15ebbf2..cc4a262d8e 100644
--- a/src/backend/access/transam/xloginsert.c
+++ b/src/backend/access/transam/xloginsert.c
@@ -135,7 +135,7 @@ static bool begininsert_called = false;
 /* Memory context to hold the registered buffer and data references. */
 static MemoryContext xloginsert_cxt;
 
-static XLogRecData *XLogRecordAssemble(RmgrId rmid, uint8 info,
+static XLogRecData *XLogRecordAssemble(RmgrId rmid, uint8 info, uint8 rminfo,
 									   XLogRecPtr RedoRecPtr, bool doPageWrites,
 									   XLogRecPtr *fpw_lsn, int *num_fpi,
 									   bool *topxid_included);
@@ -436,8 +436,9 @@ XLogSetRecordFlags(uint8 flags)
 	curinsert_flags |= flags;
 }
 
+
 /*
- * Insert an XLOG record having the specified RMID and info bytes, with the
+ * Insert an XLOG record having the specified RMID and rminfo bytes, with the
  * body of the record being the data and buffer references registered earlier
  * with XLogRegister* calls.
  *
@@ -448,7 +449,21 @@ XLogSetRecordFlags(uint8 flags)
  * WAL rule "write the log before the data".)
  */
 XLogRecPtr
-XLogInsert(RmgrId rmid, uint8 info)
+XLogInsert(RmgrId rmid, uint8 rminfo)
+{
+	return XLogInsertExtended(rmid, 0, rminfo);
+}
+
+
+/*
+ * Insert an XLOG record having the specified RMID, info and rminfo bytes,
+ * with the body of the record being the data and buffer references
+ * registered earlier with XLogRegister* calls.
+ *
+ * See also XLogInsert above.
+ */
+XLogRecPtr
+XLogInsertExtended(RmgrId rmid, uint8 info, uint8 rminfo)
 {
 	XLogRecPtr	EndPos;
 
@@ -457,11 +472,10 @@ XLogInsert(RmgrId rmid, uint8 info)
 		elog(ERROR, "XLogBeginInsert was not called");
 
 	/*
-	 * The caller can set rmgr bits, XLR_SPECIAL_REL_UPDATE and
+	 * The caller can set XLR_SPECIAL_REL_UPDATE and
 	 * XLR_CHECK_CONSISTENCY; the rest are reserved for use by me.
 	 */
-	if ((info & ~(XLR_RMGR_INFO_MASK |
-				  XLR_SPECIAL_REL_UPDATE |
+	if ((info & ~(XLR_SPECIAL_REL_UPDATE |
 				  XLR_CHECK_CONSISTENCY)) != 0)
 		elog(PANIC, "invalid xlog info mask %02X", info);
 
@@ -494,7 +508,7 @@ XLogInsert(RmgrId rmid, uint8 info)
 		 */
 		GetFullPageWriteInfo(&RedoRecPtr, &doPageWrites);
 
-		rdt = XLogRecordAssemble(rmid, info, RedoRecPtr, doPageWrites,
+		rdt = XLogRecordAssemble(rmid, info, rminfo, RedoRecPtr, doPageWrites,
 								 &fpw_lsn, &num_fpi, &topxid_included);
 
 		EndPos = XLogInsertRecord(rdt, fpw_lsn, curinsert_flags, num_fpi,
@@ -522,7 +536,7 @@ XLogInsert(RmgrId rmid, uint8 info)
  * current subtransaction.
  */
 static XLogRecData *
-XLogRecordAssemble(RmgrId rmid, uint8 info,
+XLogRecordAssemble(RmgrId rmid, uint8 info, uint8 rminfo,
 				   XLogRecPtr RedoRecPtr, bool doPageWrites,
 				   XLogRecPtr *fpw_lsn, int *num_fpi, bool *topxid_included)
 {
@@ -881,6 +895,7 @@ XLogRecordAssemble(RmgrId rmid, uint8 info,
 	rechdr->xl_tot_len = total_len;
 	rechdr->xl_info = info;
 	rechdr->xl_rmid = rmid;
+	rechdr->xl_rminfo = rminfo;
 	rechdr->xl_prev = InvalidXLogRecPtr;
 	rechdr->xl_crc = rdata_crc;
 
diff --git a/src/backend/access/transam/xlogprefetcher.c b/src/backend/access/transam/xlogprefetcher.c
index 342960263c..a085b70c05 100644
--- a/src/backend/access/transam/xlogprefetcher.c
+++ b/src/backend/access/transam/xlogprefetcher.c
@@ -536,7 +536,7 @@ XLogPrefetcherNextBlock(uintptr_t pgsr_private, XLogRecPtr *lsn)
 		if (replaying_lsn < record->lsn)
 		{
 			uint8		rmid = record->header.xl_rmid;
-			uint8		record_type = record->header.xl_info & ~XLR_INFO_MASK;
+			uint8		record_type = record->header.xl_rminfo;
 
 			if (rmid == RM_XLOG_ID)
 			{
diff --git a/src/backend/access/transam/xlogreader.c b/src/backend/access/transam/xlogreader.c
index c1c9f1995b..3a23d21004 100644
--- a/src/backend/access/transam/xlogreader.c
+++ b/src/backend/access/transam/xlogreader.c
@@ -859,7 +859,7 @@ restart:
 	 * Special processing if it's an XLOG SWITCH record
 	 */
 	if (record->xl_rmid == RM_XLOG_ID &&
-		(record->xl_info & ~XLR_INFO_MASK) == XLOG_SWITCH)
+		record->xl_rminfo == XLOG_SWITCH)
 	{
 		/* Pretend it extends to end of segment */
 		state->NextRecPtr += state->segcxt.ws_segsize - 1;
diff --git a/src/backend/access/transam/xlogrecovery.c b/src/backend/access/transam/xlogrecovery.c
index b41e682664..d83c9c9d97 100644
--- a/src/backend/access/transam/xlogrecovery.c
+++ b/src/backend/access/transam/xlogrecovery.c
@@ -614,7 +614,7 @@ InitWalRecovery(ControlFileData *ControlFile, bool *wasShutdown_ptr,
 		if (record != NULL)
 		{
 			memcpy(&checkPoint, XLogRecGetData(xlogreader), sizeof(CheckPoint));
-			wasShutdown = ((record->xl_info & ~XLR_INFO_MASK) == XLOG_CHECKPOINT_SHUTDOWN);
+			wasShutdown = (record->xl_rminfo == XLOG_CHECKPOINT_SHUTDOWN);
 			ereport(DEBUG1,
 					(errmsg_internal("checkpoint record is at %X/%X",
 									 LSN_FORMAT_ARGS(CheckPointLoc))));
@@ -768,7 +768,7 @@ InitWalRecovery(ControlFileData *ControlFile, bool *wasShutdown_ptr,
 					(errmsg("could not locate a valid checkpoint record")));
 		}
 		memcpy(&checkPoint, XLogRecGetData(xlogreader), sizeof(CheckPoint));
-		wasShutdown = ((record->xl_info & ~XLR_INFO_MASK) == XLOG_CHECKPOINT_SHUTDOWN);
+		wasShutdown = (record->xl_rminfo == XLOG_CHECKPOINT_SHUTDOWN);
 	}
 
 	/*
@@ -1839,9 +1839,9 @@ ApplyWalRecord(XLogReaderState *xlogreader, XLogRecord *record, TimeLineID *repl
 	{
 		TimeLineID	newReplayTLI = *replayTLI;
 		TimeLineID	prevReplayTLI = *replayTLI;
-		uint8		info = record->xl_info & ~XLR_INFO_MASK;
+		uint8		rminfo = record->xl_rminfo;
 
-		if (info == XLOG_CHECKPOINT_SHUTDOWN)
+		if (rminfo == XLOG_CHECKPOINT_SHUTDOWN)
 		{
 			CheckPoint	checkPoint;
 
@@ -1849,7 +1849,7 @@ ApplyWalRecord(XLogReaderState *xlogreader, XLogRecord *record, TimeLineID *repl
 			newReplayTLI = checkPoint.ThisTimeLineID;
 			prevReplayTLI = checkPoint.PrevTimeLineID;
 		}
-		else if (info == XLOG_END_OF_RECOVERY)
+		else if (rminfo == XLOG_END_OF_RECOVERY)
 		{
 			xl_end_of_recovery xlrec;
 
@@ -1958,12 +1958,12 @@ ApplyWalRecord(XLogReaderState *xlogreader, XLogRecord *record, TimeLineID *repl
 static void
 xlogrecovery_redo(XLogReaderState *record, TimeLineID replayTLI)
 {
-	uint8		info = XLogRecGetInfo(record) & ~XLR_INFO_MASK;
+	uint8		rminfo = XLogRecGetRmInfo(record);
 	XLogRecPtr	lsn = record->EndRecPtr;
 
 	Assert(XLogRecGetRmid(record) == RM_XLOG_ID);
 
-	if (info == XLOG_OVERWRITE_CONTRECORD)
+	if (rminfo == XLOG_OVERWRITE_CONTRECORD)
 	{
 		/* Verify the payload of a XLOG_OVERWRITE_CONTRECORD record. */
 		xl_overwrite_contrecord xlrec;
@@ -1986,7 +1986,7 @@ xlogrecovery_redo(XLogReaderState *record, TimeLineID replayTLI)
 		/* Verifying the record should only happen once */
 		record->overwrittenRecPtr = InvalidXLogRecPtr;
 	}
-	else if (info == XLOG_BACKUP_END)
+	else if (rminfo == XLOG_BACKUP_END)
 	{
 		XLogRecPtr	startpoint;
 
@@ -2176,15 +2176,15 @@ void
 xlog_outdesc(StringInfo buf, XLogReaderState *record)
 {
 	RmgrData	rmgr = GetRmgr(XLogRecGetRmid(record));
-	uint8		info = XLogRecGetInfo(record);
+	uint8		rminfo = XLogRecGetRmInfo(record);
 	const char *id;
 
 	appendStringInfoString(buf, rmgr.rm_name);
 	appendStringInfoChar(buf, '/');
 
-	id = rmgr.rm_identify(info);
+	id = rmgr.rm_identify(rminfo);
 	if (id == NULL)
-		appendStringInfo(buf, "UNKNOWN (%X): ", info & ~XLR_INFO_MASK);
+		appendStringInfo(buf, "UNKNOWN (%X): ", rminfo);
 	else
 		appendStringInfo(buf, "%s: ", id);
 
@@ -2304,11 +2304,11 @@ checkTimeLineSwitch(XLogRecPtr lsn, TimeLineID newTLI, TimeLineID prevTLI,
 static bool
 getRecordTimestamp(XLogReaderState *record, TimestampTz *recordXtime)
 {
-	uint8		info = XLogRecGetInfo(record) & ~XLR_INFO_MASK;
-	uint8		xact_info = info & XLOG_XACT_OPMASK;
+	uint8		rminfo = XLogRecGetRmInfo(record);
+	uint8		xact_info = rminfo & XLOG_XACT_OPMASK;
 	uint8		rmid = XLogRecGetRmid(record);
 
-	if (rmid == RM_XLOG_ID && info == XLOG_RESTORE_POINT)
+	if (rmid == RM_XLOG_ID && rminfo == XLOG_RESTORE_POINT)
 	{
 		*recordXtime = ((xl_restore_point *) XLogRecGetData(record))->rp_time;
 		return true;
@@ -2498,7 +2498,7 @@ recoveryStopsBefore(XLogReaderState *record)
 	if (XLogRecGetRmid(record) != RM_XACT_ID)
 		return false;
 
-	xact_info = XLogRecGetInfo(record) & XLOG_XACT_OPMASK;
+	xact_info = XLogRecGetRmInfo(record) & XLOG_XACT_OPMASK;
 
 	if (xact_info == XLOG_XACT_COMMIT)
 	{
@@ -2511,7 +2511,7 @@ recoveryStopsBefore(XLogReaderState *record)
 		xl_xact_parsed_commit parsed;
 
 		isCommit = true;
-		ParseCommitRecord(XLogRecGetInfo(record),
+		ParseCommitRecord(XLogRecGetRmInfo(record),
 						  xlrec,
 						  &parsed);
 		recordXid = parsed.twophase_xid;
@@ -2527,7 +2527,7 @@ recoveryStopsBefore(XLogReaderState *record)
 		xl_xact_parsed_abort parsed;
 
 		isCommit = false;
-		ParseAbortRecord(XLogRecGetInfo(record),
+		ParseAbortRecord(XLogRecGetRmInfo(record),
 						 xlrec,
 						 &parsed);
 		recordXid = parsed.twophase_xid;
@@ -2599,7 +2599,7 @@ recoveryStopsBefore(XLogReaderState *record)
 static bool
 recoveryStopsAfter(XLogReaderState *record)
 {
-	uint8		info;
+	uint8		rminfo;
 	uint8		xact_info;
 	uint8		rmid;
 	TimestampTz recordXtime;
@@ -2611,7 +2611,7 @@ recoveryStopsAfter(XLogReaderState *record)
 	if (!ArchiveRecoveryRequested)
 		return false;
 
-	info = XLogRecGetInfo(record) & ~XLR_INFO_MASK;
+	rminfo = XLogRecGetRmInfo(record);
 	rmid = XLogRecGetRmid(record);
 
 	/*
@@ -2619,7 +2619,7 @@ recoveryStopsAfter(XLogReaderState *record)
 	 * the first one.
 	 */
 	if (recoveryTarget == RECOVERY_TARGET_NAME &&
-		rmid == RM_XLOG_ID && info == XLOG_RESTORE_POINT)
+		rmid == RM_XLOG_ID && rminfo == XLOG_RESTORE_POINT)
 	{
 		xl_restore_point *recordRestorePointData;
 
@@ -2660,7 +2660,7 @@ recoveryStopsAfter(XLogReaderState *record)
 	if (rmid != RM_XACT_ID)
 		return false;
 
-	xact_info = info & XLOG_XACT_OPMASK;
+	xact_info = rminfo & XLOG_XACT_OPMASK;
 
 	if (xact_info == XLOG_XACT_COMMIT ||
 		xact_info == XLOG_XACT_COMMIT_PREPARED ||
@@ -2689,7 +2689,7 @@ recoveryStopsAfter(XLogReaderState *record)
 			xl_xact_abort *xlrec = (xl_xact_abort *) XLogRecGetData(record);
 			xl_xact_parsed_abort parsed;
 
-			ParseAbortRecord(XLogRecGetInfo(record),
+			ParseAbortRecord(XLogRecGetRmInfo(record),
 							 xlrec,
 							 &parsed);
 			recordXid = parsed.twophase_xid;
@@ -2883,7 +2883,7 @@ recoveryApplyDelay(XLogReaderState *record)
 	if (XLogRecGetRmid(record) != RM_XACT_ID)
 		return false;
 
-	xact_info = XLogRecGetInfo(record) & XLOG_XACT_OPMASK;
+	xact_info = XLogRecGetRmInfo(record) & XLOG_XACT_OPMASK;
 
 	if (xact_info != XLOG_XACT_COMMIT &&
 		xact_info != XLOG_XACT_COMMIT_PREPARED)
@@ -3917,7 +3917,7 @@ ReadCheckpointRecord(XLogPrefetcher *xlogprefetcher, XLogRecPtr RecPtr,
 					 TimeLineID replayTLI)
 {
 	XLogRecord *record;
-	uint8		info;
+	uint8		rminfo;
 
 	Assert(xlogreader != NULL);
 
@@ -3943,9 +3943,9 @@ ReadCheckpointRecord(XLogPrefetcher *xlogprefetcher, XLogRecPtr RecPtr,
 				(errmsg("invalid resource manager ID in checkpoint record")));
 		return NULL;
 	}
-	info = record->xl_info & ~XLR_INFO_MASK;
-	if (info != XLOG_CHECKPOINT_SHUTDOWN &&
-		info != XLOG_CHECKPOINT_ONLINE)
+	rminfo = record->xl_rminfo;
+	if (rminfo != XLOG_CHECKPOINT_SHUTDOWN &&
+		rminfo != XLOG_CHECKPOINT_ONLINE)
 	{
 		ereport(LOG,
 				(errmsg("invalid xl_info in checkpoint record")));
diff --git a/src/backend/access/transam/xlogstats.c b/src/backend/access/transam/xlogstats.c
index 514181792d..5ff1a58134 100644
--- a/src/backend/access/transam/xlogstats.c
+++ b/src/backend/access/transam/xlogstats.c
@@ -79,7 +79,7 @@ XLogRecStoreStats(XLogStats *stats, XLogReaderState *record)
 	 * RmgrId).
 	 */
 
-	recid = XLogRecGetInfo(record) >> 4;
+	recid = XLogRecGetRmInfo(record);
 
 	/*
 	 * XACT records need to be handled differently. Those records use the
diff --git a/src/backend/catalog/storage.c b/src/backend/catalog/storage.c
index d708af19ed..4ef46a1855 100644
--- a/src/backend/catalog/storage.c
+++ b/src/backend/catalog/storage.c
@@ -194,7 +194,7 @@ log_smgrcreate(const RelFileLocator *rlocator, ForkNumber forkNum)
 
 	XLogBeginInsert();
 	XLogRegisterData((char *) &xlrec, sizeof(xlrec));
-	XLogInsert(RM_SMGR_ID, XLOG_SMGR_CREATE | XLR_SPECIAL_REL_UPDATE);
+	XLogInsertExtended(RM_SMGR_ID, XLR_SPECIAL_REL_UPDATE, XLOG_SMGR_CREATE);
 }
 
 /*
@@ -375,8 +375,9 @@ RelationTruncate(Relation rel, BlockNumber nblocks)
 		XLogBeginInsert();
 		XLogRegisterData((char *) &xlrec, sizeof(xlrec));
 
-		lsn = XLogInsert(RM_SMGR_ID,
-						 XLOG_SMGR_TRUNCATE | XLR_SPECIAL_REL_UPDATE);
+		lsn = XLogInsertExtended(RM_SMGR_ID,
+								 XLR_SPECIAL_REL_UPDATE,
+								 XLOG_SMGR_TRUNCATE);
 
 		/*
 		 * Flush, because otherwise the truncation of the main relation might
@@ -958,12 +959,12 @@ void
 smgr_redo(XLogReaderState *record)
 {
 	XLogRecPtr	lsn = record->EndRecPtr;
-	uint8		info = XLogRecGetInfo(record) & ~XLR_INFO_MASK;
+	uint8		rminfo = XLogRecGetRmInfo(record);
 
 	/* Backup blocks are not used in smgr records */
 	Assert(!XLogRecHasAnyBlockRefs(record));
 
-	if (info == XLOG_SMGR_CREATE)
+	if (rminfo == XLOG_SMGR_CREATE)
 	{
 		xl_smgr_create *xlrec = (xl_smgr_create *) XLogRecGetData(record);
 		SMgrRelation reln;
@@ -971,7 +972,7 @@ smgr_redo(XLogReaderState *record)
 		reln = smgropen(xlrec->rlocator, InvalidBackendId);
 		smgrcreate(reln, xlrec->forkNum, true);
 	}
-	else if (info == XLOG_SMGR_TRUNCATE)
+	else if (rminfo == XLOG_SMGR_TRUNCATE)
 	{
 		xl_smgr_truncate *xlrec = (xl_smgr_truncate *) XLogRecGetData(record);
 		SMgrRelation reln;
@@ -1060,5 +1061,5 @@ smgr_redo(XLogReaderState *record)
 		FreeFakeRelcacheEntry(rel);
 	}
 	else
-		elog(PANIC, "smgr_redo: unknown op code %u", info);
+		elog(PANIC, "smgr_redo: unknown op code %u", rminfo);
 }
diff --git a/src/backend/commands/dbcommands.c b/src/backend/commands/dbcommands.c
index e0753c1bad..092a02619e 100644
--- a/src/backend/commands/dbcommands.c
+++ b/src/backend/commands/dbcommands.c
@@ -624,8 +624,9 @@ CreateDatabaseUsingFileCopy(Oid src_dboid, Oid dst_dboid, Oid src_tsid,
 			XLogRegisterData((char *) &xlrec,
 							 sizeof(xl_dbase_create_file_copy_rec));
 
-			(void) XLogInsert(RM_DBASE_ID,
-							  XLOG_DBASE_CREATE_FILE_COPY | XLR_SPECIAL_REL_UPDATE);
+			(void) XLogInsertExtended(RM_DBASE_ID,
+									  XLR_SPECIAL_REL_UPDATE,
+									  XLOG_DBASE_CREATE_FILE_COPY);
 		}
 		pfree(srcpath);
 		pfree(dstpath);
@@ -2021,8 +2022,9 @@ movedb(const char *dbname, const char *tblspcname)
 			XLogRegisterData((char *) &xlrec,
 							 sizeof(xl_dbase_create_file_copy_rec));
 
-			(void) XLogInsert(RM_DBASE_ID,
-							  XLOG_DBASE_CREATE_FILE_COPY | XLR_SPECIAL_REL_UPDATE);
+			(void) XLogInsertExtended(RM_DBASE_ID,
+									  XLR_SPECIAL_REL_UPDATE,
+									  XLOG_DBASE_CREATE_FILE_COPY);
 		}
 
 		/*
@@ -2115,8 +2117,9 @@ movedb(const char *dbname, const char *tblspcname)
 		XLogRegisterData((char *) &xlrec, sizeof(xl_dbase_drop_rec));
 		XLogRegisterData((char *) &src_tblspcoid, sizeof(Oid));
 
-		(void) XLogInsert(RM_DBASE_ID,
-						  XLOG_DBASE_DROP | XLR_SPECIAL_REL_UPDATE);
+		(void) XLogInsertExtended(RM_DBASE_ID,
+								  XLR_SPECIAL_REL_UPDATE,
+								  XLOG_DBASE_DROP);
 	}
 
 	/* Now it's safe to release the database lock */
@@ -2834,8 +2837,9 @@ remove_dbtablespaces(Oid db_id)
 		XLogRegisterData((char *) &xlrec, MinSizeOfDbaseDropRec);
 		XLogRegisterData((char *) tablespace_ids, ntblspc * sizeof(Oid));
 
-		(void) XLogInsert(RM_DBASE_ID,
-						  XLOG_DBASE_DROP | XLR_SPECIAL_REL_UPDATE);
+		(void) XLogInsertExtended(RM_DBASE_ID,
+								  XLR_SPECIAL_REL_UPDATE,
+								  XLOG_DBASE_DROP);
 	}
 
 	list_free(ltblspc);
@@ -3040,12 +3044,12 @@ recovery_create_dbdir(char *path, bool only_tblspc)
 void
 dbase_redo(XLogReaderState *record)
 {
-	uint8		info = XLogRecGetInfo(record) & ~XLR_INFO_MASK;
+	uint8		rminfo = XLogRecGetRmInfo(record);
 
 	/* Backup blocks are not used in dbase records */
 	Assert(!XLogRecHasAnyBlockRefs(record));
 
-	if (info == XLOG_DBASE_CREATE_FILE_COPY)
+	if (rminfo == XLOG_DBASE_CREATE_FILE_COPY)
 	{
 		xl_dbase_create_file_copy_rec *xlrec =
 		(xl_dbase_create_file_copy_rec *) XLogRecGetData(record);
@@ -3117,7 +3121,7 @@ dbase_redo(XLogReaderState *record)
 		pfree(src_path);
 		pfree(dst_path);
 	}
-	else if (info == XLOG_DBASE_CREATE_WAL_LOG)
+	else if (rminfo == XLOG_DBASE_CREATE_WAL_LOG)
 	{
 		xl_dbase_create_wal_log_rec *xlrec =
 		(xl_dbase_create_wal_log_rec *) XLogRecGetData(record);
@@ -3136,7 +3140,7 @@ dbase_redo(XLogReaderState *record)
 								true);
 		pfree(dbpath);
 	}
-	else if (info == XLOG_DBASE_DROP)
+	else if (rminfo == XLOG_DBASE_DROP)
 	{
 		xl_dbase_drop_rec *xlrec = (xl_dbase_drop_rec *) XLogRecGetData(record);
 		char	   *dst_path;
@@ -3198,5 +3202,5 @@ dbase_redo(XLogReaderState *record)
 		}
 	}
 	else
-		elog(PANIC, "dbase_redo: unknown op code %u", info);
+		elog(PANIC, "dbase_redo: unknown op code %u", rminfo);
 }
diff --git a/src/backend/commands/sequence.c b/src/backend/commands/sequence.c
index 99c9f91cba..56221903b7 100644
--- a/src/backend/commands/sequence.c
+++ b/src/backend/commands/sequence.c
@@ -1845,7 +1845,7 @@ void
 seq_redo(XLogReaderState *record)
 {
 	XLogRecPtr	lsn = record->EndRecPtr;
-	uint8		info = XLogRecGetInfo(record) & ~XLR_INFO_MASK;
+	uint8		rminfo = XLogRecGetRmInfo(record);
 	Buffer		buffer;
 	Page		page;
 	Page		localpage;
@@ -1854,8 +1854,8 @@ seq_redo(XLogReaderState *record)
 	xl_seq_rec *xlrec = (xl_seq_rec *) XLogRecGetData(record);
 	sequence_magic *sm;
 
-	if (info != XLOG_SEQ_LOG)
-		elog(PANIC, "seq_redo: unknown op code %u", info);
+	if (rminfo != XLOG_SEQ_LOG)
+		elog(PANIC, "seq_redo: unknown op code %u", rminfo);
 
 	buffer = XLogInitBufferForRedo(record, 0);
 	page = (Page) BufferGetPage(buffer);
diff --git a/src/backend/commands/tablespace.c b/src/backend/commands/tablespace.c
index b69ff37dbb..d9c89bbbf9 100644
--- a/src/backend/commands/tablespace.c
+++ b/src/backend/commands/tablespace.c
@@ -1516,19 +1516,19 @@ get_tablespace_name(Oid spc_oid)
 void
 tblspc_redo(XLogReaderState *record)
 {
-	uint8		info = XLogRecGetInfo(record) & ~XLR_INFO_MASK;
+	uint8		rminfo = XLogRecGetRmInfo(record);
 
 	/* Backup blocks are not used in tblspc records */
 	Assert(!XLogRecHasAnyBlockRefs(record));
 
-	if (info == XLOG_TBLSPC_CREATE)
+	if (rminfo == XLOG_TBLSPC_CREATE)
 	{
 		xl_tblspc_create_rec *xlrec = (xl_tblspc_create_rec *) XLogRecGetData(record);
 		char	   *location = xlrec->ts_path;
 
 		create_tablespace_directories(location, xlrec->ts_id);
 	}
-	else if (info == XLOG_TBLSPC_DROP)
+	else if (rminfo == XLOG_TBLSPC_DROP)
 	{
 		xl_tblspc_drop_rec *xlrec = (xl_tblspc_drop_rec *) XLogRecGetData(record);
 
@@ -1571,5 +1571,5 @@ tblspc_redo(XLogReaderState *record)
 		}
 	}
 	else
-		elog(PANIC, "tblspc_redo: unknown op code %u", info);
+		elog(PANIC, "tblspc_redo: unknown op code %u", rminfo);
 }
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index 1e90b72b74..265ab9fa18 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -1195,7 +1195,7 @@ do_start_worker(void)
 	/* Also determine the oldest datminmxid we will consider. */
 	recentMulti = ReadNextMultiXactId();
 	multiForceLimit = recentMulti - MultiXactMemberFreezeThreshold();
-	if (multiForceLimit < FirstMultiXactId)
+	if (!MultiXactIdIsNormal(multiForceLimit))
 		multiForceLimit -= FirstMultiXactId;
 
 	/*
@@ -3056,7 +3056,7 @@ relation_needs_vacanalyze(Oid relid,
 	if (!force_vacuum)
 	{
 		multiForceLimit = recentMulti - multixact_freeze_max_age;
-		if (multiForceLimit < FirstMultiXactId)
+		if (!MultiXactIdIsNormal(multiForceLimit))
 			multiForceLimit -= FirstMultiXactId;
 		force_vacuum = MultiXactIdIsValid(classForm->relminmxid) &&
 			MultiXactIdPrecedes(classForm->relminmxid, multiForceLimit);
diff --git a/src/backend/replication/logical/decode.c b/src/backend/replication/logical/decode.c
index 4d0bf1930d..add4d7c7dd 100644
--- a/src/backend/replication/logical/decode.c
+++ b/src/backend/replication/logical/decode.c
@@ -132,12 +132,12 @@ void
 xlog_decode(LogicalDecodingContext *ctx, XLogRecordBuffer *buf)
 {
 	SnapBuild  *builder = ctx->snapshot_builder;
-	uint8		info = XLogRecGetInfo(buf->record) & ~XLR_INFO_MASK;
+	uint8		rminfo = XLogRecGetRmInfo(buf->record);
 
 	ReorderBufferProcessXid(ctx->reorder, XLogRecGetXid(buf->record),
 							buf->origptr);
 
-	switch (info)
+	switch (rminfo)
 	{
 			/* this is also used in END_OF_RECOVERY checkpoints */
 		case XLOG_CHECKPOINT_SHUTDOWN:
@@ -164,7 +164,7 @@ xlog_decode(LogicalDecodingContext *ctx, XLogRecordBuffer *buf)
 		case XLOG_OVERWRITE_CONTRECORD:
 			break;
 		default:
-			elog(ERROR, "unexpected RM_XLOG_ID record type: %u", info);
+			elog(ERROR, "unexpected RM_XLOG_ID record type: %u", rminfo);
 	}
 }
 
@@ -177,7 +177,7 @@ xact_decode(LogicalDecodingContext *ctx, XLogRecordBuffer *buf)
 	SnapBuild  *builder = ctx->snapshot_builder;
 	ReorderBuffer *reorder = ctx->reorder;
 	XLogReaderState *r = buf->record;
-	uint8		info = XLogRecGetInfo(r) & XLOG_XACT_OPMASK;
+	uint8		info = XLogRecGetRmInfo(r) & XLOG_XACT_OPMASK;
 
 	/*
 	 * If the snapshot isn't yet fully built, we cannot decode anything, so
@@ -197,7 +197,7 @@ xact_decode(LogicalDecodingContext *ctx, XLogRecordBuffer *buf)
 				bool		two_phase = false;
 
 				xlrec = (xl_xact_commit *) XLogRecGetData(r);
-				ParseCommitRecord(XLogRecGetInfo(buf->record), xlrec, &parsed);
+				ParseCommitRecord(XLogRecGetRmInfo(buf->record), xlrec, &parsed);
 
 				if (!TransactionIdIsValid(parsed.twophase_xid))
 					xid = XLogRecGetXid(r);
@@ -225,7 +225,7 @@ xact_decode(LogicalDecodingContext *ctx, XLogRecordBuffer *buf)
 				bool		two_phase = false;
 
 				xlrec = (xl_xact_abort *) XLogRecGetData(r);
-				ParseAbortRecord(XLogRecGetInfo(buf->record), xlrec, &parsed);
+				ParseAbortRecord(XLogRecGetRmInfo(buf->record), xlrec, &parsed);
 
 				if (!TransactionIdIsValid(parsed.twophase_xid))
 					xid = XLogRecGetXid(r);
@@ -288,7 +288,7 @@ xact_decode(LogicalDecodingContext *ctx, XLogRecordBuffer *buf)
 
 				/* ok, parse it */
 				xlrec = (xl_xact_prepare *) XLogRecGetData(r);
-				ParsePrepareRecord(XLogRecGetInfo(buf->record),
+				ParsePrepareRecord(XLogRecGetRmInfo(buf->record),
 								   xlrec, &parsed);
 
 				/*
@@ -333,11 +333,11 @@ standby_decode(LogicalDecodingContext *ctx, XLogRecordBuffer *buf)
 {
 	SnapBuild  *builder = ctx->snapshot_builder;
 	XLogReaderState *r = buf->record;
-	uint8		info = XLogRecGetInfo(r) & ~XLR_INFO_MASK;
+	uint8		rminfo = XLogRecGetRmInfo(r);
 
 	ReorderBufferProcessXid(ctx->reorder, XLogRecGetXid(r), buf->origptr);
 
-	switch (info)
+	switch (rminfo)
 	{
 		case XLOG_RUNNING_XACTS:
 			{
@@ -367,7 +367,7 @@ standby_decode(LogicalDecodingContext *ctx, XLogRecordBuffer *buf)
 			 */
 			break;
 		default:
-			elog(ERROR, "unexpected RM_STANDBY_ID record type: %u", info);
+			elog(ERROR, "unexpected RM_STANDBY_ID record type: %u", rminfo);
 	}
 }
 
@@ -377,7 +377,7 @@ standby_decode(LogicalDecodingContext *ctx, XLogRecordBuffer *buf)
 void
 heap2_decode(LogicalDecodingContext *ctx, XLogRecordBuffer *buf)
 {
-	uint8		info = XLogRecGetInfo(buf->record) & XLOG_HEAP_OPMASK;
+	uint8		rminfo = XLogRecGetRmInfo(buf->record) & XLOG_HEAP_OPMASK;
 	TransactionId xid = XLogRecGetXid(buf->record);
 	SnapBuild  *builder = ctx->snapshot_builder;
 
@@ -391,7 +391,7 @@ heap2_decode(LogicalDecodingContext *ctx, XLogRecordBuffer *buf)
 		ctx->fast_forward)
 		return;
 
-	switch (info)
+	switch (rminfo)
 	{
 		case XLOG_HEAP2_MULTI_INSERT:
 			if (!ctx->fast_forward &&
@@ -427,7 +427,7 @@ heap2_decode(LogicalDecodingContext *ctx, XLogRecordBuffer *buf)
 		case XLOG_HEAP2_LOCK_UPDATED:
 			break;
 		default:
-			elog(ERROR, "unexpected RM_HEAP2_ID record type: %u", info);
+			elog(ERROR, "unexpected RM_HEAP2_ID record type: %u", rminfo);
 	}
 }
 
@@ -437,7 +437,7 @@ heap2_decode(LogicalDecodingContext *ctx, XLogRecordBuffer *buf)
 void
 heap_decode(LogicalDecodingContext *ctx, XLogRecordBuffer *buf)
 {
-	uint8		info = XLogRecGetInfo(buf->record) & XLOG_HEAP_OPMASK;
+	uint8		rminfo = XLogRecGetRmInfo(buf->record) & XLOG_HEAP_OPMASK;
 	TransactionId xid = XLogRecGetXid(buf->record);
 	SnapBuild  *builder = ctx->snapshot_builder;
 
@@ -451,7 +451,7 @@ heap_decode(LogicalDecodingContext *ctx, XLogRecordBuffer *buf)
 		ctx->fast_forward)
 		return;
 
-	switch (info)
+	switch (rminfo)
 	{
 		case XLOG_HEAP_INSERT:
 			if (SnapBuildProcessChange(builder, xid, buf->origptr))
@@ -512,7 +512,7 @@ heap_decode(LogicalDecodingContext *ctx, XLogRecordBuffer *buf)
 			break;
 
 		default:
-			elog(ERROR, "unexpected RM_HEAP_ID record type: %u", info);
+			elog(ERROR, "unexpected RM_HEAP_ID record type: %u", rminfo);
 			break;
 	}
 }
@@ -562,13 +562,13 @@ logicalmsg_decode(LogicalDecodingContext *ctx, XLogRecordBuffer *buf)
 	SnapBuild  *builder = ctx->snapshot_builder;
 	XLogReaderState *r = buf->record;
 	TransactionId xid = XLogRecGetXid(r);
-	uint8		info = XLogRecGetInfo(r) & ~XLR_INFO_MASK;
+	uint8		rminfo = XLogRecGetRmInfo(r);
 	RepOriginId origin_id = XLogRecGetOrigin(r);
 	Snapshot	snapshot;
 	xl_logical_message *message;
 
-	if (info != XLOG_LOGICAL_MESSAGE)
-		elog(ERROR, "unexpected RM_LOGICALMSG_ID record type: %u", info);
+	if (rminfo != XLOG_LOGICAL_MESSAGE)
+		elog(ERROR, "unexpected RM_LOGICALMSG_ID record type: %u", rminfo);
 
 	ReorderBufferProcessXid(ctx->reorder, XLogRecGetXid(r), buf->origptr);
 
diff --git a/src/backend/replication/logical/message.c b/src/backend/replication/logical/message.c
index 1c34912610..564990b610 100644
--- a/src/backend/replication/logical/message.c
+++ b/src/backend/replication/logical/message.c
@@ -80,10 +80,10 @@ LogLogicalMessage(const char *prefix, const char *message, size_t size,
 void
 logicalmsg_redo(XLogReaderState *record)
 {
-	uint8		info = XLogRecGetInfo(record) & ~XLR_INFO_MASK;
+	uint8		rminfo = XLogRecGetRmInfo(record);
 
-	if (info != XLOG_LOGICAL_MESSAGE)
-		elog(PANIC, "logicalmsg_redo: unknown op code %u", info);
+	if (rminfo != XLOG_LOGICAL_MESSAGE)
+		elog(PANIC, "logicalmsg_redo: unknown op code %u", rminfo);
 
 	/* This is only interesting for logical decoding, see decode.c. */
 }
diff --git a/src/backend/replication/logical/origin.c b/src/backend/replication/logical/origin.c
index f19b72ff35..cf6be4e28d 100644
--- a/src/backend/replication/logical/origin.c
+++ b/src/backend/replication/logical/origin.c
@@ -822,9 +822,9 @@ StartupReplicationOrigin(void)
 void
 replorigin_redo(XLogReaderState *record)
 {
-	uint8		info = XLogRecGetInfo(record) & ~XLR_INFO_MASK;
+	uint8		rminfo = XLogRecGetRmInfo(record);
 
-	switch (info)
+	switch (rminfo)
 	{
 		case XLOG_REPLORIGIN_SET:
 			{
@@ -861,7 +861,7 @@ replorigin_redo(XLogReaderState *record)
 				break;
 			}
 		default:
-			elog(PANIC, "replorigin_redo: unknown op code %u", info);
+			elog(PANIC, "replorigin_redo: unknown op code %u", rminfo);
 	}
 }
 
diff --git a/src/backend/storage/ipc/standby.c b/src/backend/storage/ipc/standby.c
index 9dab931990..5f791e5c83 100644
--- a/src/backend/storage/ipc/standby.c
+++ b/src/backend/storage/ipc/standby.c
@@ -1104,7 +1104,7 @@ StandbyReleaseOldLocks(TransactionId oldxid)
 void
 standby_redo(XLogReaderState *record)
 {
-	uint8		info = XLogRecGetInfo(record) & ~XLR_INFO_MASK;
+	uint8		rminfo = XLogRecGetRmInfo(record);
 
 	/* Backup blocks are not used in standby records */
 	Assert(!XLogRecHasAnyBlockRefs(record));
@@ -1113,7 +1113,7 @@ standby_redo(XLogReaderState *record)
 	if (standbyState == STANDBY_DISABLED)
 		return;
 
-	if (info == XLOG_STANDBY_LOCK)
+	if (rminfo == XLOG_STANDBY_LOCK)
 	{
 		xl_standby_locks *xlrec = (xl_standby_locks *) XLogRecGetData(record);
 		int			i;
@@ -1123,7 +1123,7 @@ standby_redo(XLogReaderState *record)
 											  xlrec->locks[i].dbOid,
 											  xlrec->locks[i].relOid);
 	}
-	else if (info == XLOG_RUNNING_XACTS)
+	else if (rminfo == XLOG_RUNNING_XACTS)
 	{
 		xl_running_xacts *xlrec = (xl_running_xacts *) XLogRecGetData(record);
 		RunningTransactionsData running;
@@ -1138,7 +1138,7 @@ standby_redo(XLogReaderState *record)
 
 		ProcArrayApplyRecoveryInfo(&running);
 	}
-	else if (info == XLOG_INVALIDATIONS)
+	else if (rminfo == XLOG_INVALIDATIONS)
 	{
 		xl_invalidations *xlrec = (xl_invalidations *) XLogRecGetData(record);
 
@@ -1149,7 +1149,7 @@ standby_redo(XLogReaderState *record)
 											 xlrec->tsId);
 	}
 	else
-		elog(PANIC, "standby_redo: unknown op code %u", info);
+		elog(PANIC, "standby_redo: unknown op code %u", rminfo);
 }
 
 /*
diff --git a/src/backend/utils/cache/relmapper.c b/src/backend/utils/cache/relmapper.c
index 6266568605..c9bbd98598 100644
--- a/src/backend/utils/cache/relmapper.c
+++ b/src/backend/utils/cache/relmapper.c
@@ -1084,12 +1084,12 @@ perform_relmap_update(bool shared, const RelMapFile *updates)
 void
 relmap_redo(XLogReaderState *record)
 {
-	uint8		info = XLogRecGetInfo(record) & ~XLR_INFO_MASK;
+	uint8		rminfo = XLogRecGetRmInfo(record);
 
 	/* Backup blocks are not used in relmap records */
 	Assert(!XLogRecHasAnyBlockRefs(record));
 
-	if (info == XLOG_RELMAP_UPDATE)
+	if (rminfo == XLOG_RELMAP_UPDATE)
 	{
 		xl_relmap_update *xlrec = (xl_relmap_update *) XLogRecGetData(record);
 		RelMapFile	newmap;
@@ -1126,5 +1126,5 @@ relmap_redo(XLogReaderState *record)
 		pfree(dbpath);
 	}
 	else
-		elog(PANIC, "relmap_redo: unknown op code %u", info);
+		elog(PANIC, "relmap_redo: unknown op code %u", rminfo);
 }
diff --git a/src/bin/pg_resetwal/pg_resetwal.c b/src/bin/pg_resetwal/pg_resetwal.c
index d4772a2965..251bc31656 100644
--- a/src/bin/pg_resetwal/pg_resetwal.c
+++ b/src/bin/pg_resetwal/pg_resetwal.c
@@ -435,7 +435,7 @@ main(int argc, char *argv[])
 		ControlFile.checkPointCopy.nextMulti = set_mxid;
 
 		ControlFile.checkPointCopy.oldestMulti = set_oldestmxid;
-		if (ControlFile.checkPointCopy.oldestMulti < FirstMultiXactId)
+		if (!MultiXactIdIsNormal(ControlFile.checkPointCopy.oldestMulti))
 			ControlFile.checkPointCopy.oldestMulti += FirstMultiXactId;
 		ControlFile.checkPointCopy.oldestMultiDB = InvalidOid;
 	}
diff --git a/src/bin/pg_rewind/parsexlog.c b/src/bin/pg_rewind/parsexlog.c
index 53f011a2fe..132c4db65e 100644
--- a/src/bin/pg_rewind/parsexlog.c
+++ b/src/bin/pg_rewind/parsexlog.c
@@ -201,7 +201,7 @@ findLastCheckpoint(const char *datadir, XLogRecPtr forkptr, int tliIndex,
 	searchptr = forkptr;
 	for (;;)
 	{
-		uint8		info;
+		uint8		rminfo;
 
 		XLogBeginRead(xlogreader, searchptr);
 		record = XLogReadRecord(xlogreader, &errormsg);
@@ -222,11 +222,11 @@ findLastCheckpoint(const char *datadir, XLogRecPtr forkptr, int tliIndex,
 		 * be the latest checkpoint before WAL forked and not the checkpoint
 		 * where the primary has been stopped to be rewound.
 		 */
-		info = XLogRecGetInfo(xlogreader) & ~XLR_INFO_MASK;
+		rminfo = XLogRecGetRmInfo(xlogreader);
 		if (searchptr < forkptr &&
 			XLogRecGetRmid(xlogreader) == RM_XLOG_ID &&
-			(info == XLOG_CHECKPOINT_SHUTDOWN ||
-			 info == XLOG_CHECKPOINT_ONLINE))
+			(rminfo == XLOG_CHECKPOINT_SHUTDOWN ||
+			 rminfo == XLOG_CHECKPOINT_ONLINE))
 		{
 			CheckPoint	checkPoint;
 
@@ -370,7 +370,7 @@ extractPageInfo(XLogReaderState *record)
 	int			block_id;
 	RmgrId		rmid = XLogRecGetRmid(record);
 	uint8		info = XLogRecGetInfo(record);
-	uint8		rminfo = info & ~XLR_INFO_MASK;
+	uint8		rminfo = XLogRecGetRmInfo(record);
 
 	/* Is this a special record type that I recognize? */
 
diff --git a/src/bin/pg_waldump/pg_waldump.c b/src/bin/pg_waldump/pg_waldump.c
index 9993378ca5..70886beedd 100644
--- a/src/bin/pg_waldump/pg_waldump.c
+++ b/src/bin/pg_waldump/pg_waldump.c
@@ -449,7 +449,7 @@ XLogDumpDisplayRecord(XLogDumpConfig *config, XLogReaderState *record)
 	const RmgrDescData *desc = GetRmgrDesc(XLogRecGetRmid(record));
 	uint32		rec_len;
 	uint32		fpi_len;
-	uint8		info = XLogRecGetInfo(record);
+	uint8		rminfo = XLogRecGetRmInfo(record);
 	XLogRecPtr	xl_prev = XLogRecGetPrev(record);
 	StringInfoData s;
 
@@ -462,9 +462,9 @@ XLogDumpDisplayRecord(XLogDumpConfig *config, XLogReaderState *record)
 		   LSN_FORMAT_ARGS(record->ReadRecPtr),
 		   LSN_FORMAT_ARGS(xl_prev));
 
-	id = desc->rm_identify(info);
+	id = desc->rm_identify(rminfo);
 	if (id == NULL)
-		printf("desc: UNKNOWN (%x) ", info & ~XLR_INFO_MASK);
+		printf("desc: UNKNOWN (%x) ", rminfo);
 	else
 		printf("desc: %s ", id);
 
diff --git a/src/include/access/brin_xlog.h b/src/include/access/brin_xlog.h
index 012a9afdf4..9a4445c122 100644
--- a/src/include/access/brin_xlog.h
+++ b/src/include/access/brin_xlog.h
@@ -145,7 +145,7 @@ typedef struct xl_brin_desummarize
 
 extern void brin_redo(XLogReaderState *record);
 extern void brin_desc(StringInfo buf, XLogReaderState *record);
-extern const char *brin_identify(uint8 info);
+extern const char *brin_identify(uint8 rminfo);
 extern void brin_mask(char *pagedata, BlockNumber blkno);
 
 #endif							/* BRIN_XLOG_H */
diff --git a/src/include/access/clog.h b/src/include/access/clog.h
index 543f2e2643..c8aa16da93 100644
--- a/src/include/access/clog.h
+++ b/src/include/access/clog.h
@@ -58,6 +58,6 @@ extern int	clogsyncfiletag(const FileTag *ftag, char *path);
 
 extern void clog_redo(XLogReaderState *record);
 extern void clog_desc(StringInfo buf, XLogReaderState *record);
-extern const char *clog_identify(uint8 info);
+extern const char *clog_identify(uint8 rminfo);
 
 #endif							/* CLOG_H */
diff --git a/src/include/access/ginxlog.h b/src/include/access/ginxlog.h
index 7f985039bb..7b79f18ad7 100644
--- a/src/include/access/ginxlog.h
+++ b/src/include/access/ginxlog.h
@@ -208,7 +208,7 @@ typedef struct ginxlogDeleteListPages
 
 extern void gin_redo(XLogReaderState *record);
 extern void gin_desc(StringInfo buf, XLogReaderState *record);
-extern const char *gin_identify(uint8 info);
+extern const char *gin_identify(uint8 rminfo);
 extern void gin_xlog_startup(void);
 extern void gin_xlog_cleanup(void);
 extern void gin_mask(char *pagedata, BlockNumber blkno);
diff --git a/src/include/access/gistxlog.h b/src/include/access/gistxlog.h
index 9bbe4c2622..9bb848a207 100644
--- a/src/include/access/gistxlog.h
+++ b/src/include/access/gistxlog.h
@@ -106,7 +106,7 @@ typedef struct gistxlogPageReuse
 
 extern void gist_redo(XLogReaderState *record);
 extern void gist_desc(StringInfo buf, XLogReaderState *record);
-extern const char *gist_identify(uint8 info);
+extern const char *gist_identify(uint8 rminfo);
 extern void gist_xlog_startup(void);
 extern void gist_xlog_cleanup(void);
 extern void gist_mask(char *pagedata, BlockNumber blkno);
diff --git a/src/include/access/hash_xlog.h b/src/include/access/hash_xlog.h
index 59230706bb..e3200fa11c 100644
--- a/src/include/access/hash_xlog.h
+++ b/src/include/access/hash_xlog.h
@@ -261,7 +261,7 @@ typedef struct xl_hash_vacuum_one_page
 
 extern void hash_redo(XLogReaderState *record);
 extern void hash_desc(StringInfo buf, XLogReaderState *record);
-extern const char *hash_identify(uint8 info);
+extern const char *hash_identify(uint8 rminfo);
 extern void hash_mask(char *pagedata, BlockNumber blkno);
 
 #endif							/* HASH_XLOG_H */
diff --git a/src/include/access/heapam_xlog.h b/src/include/access/heapam_xlog.h
index 34220d93cf..306cc568eb 100644
--- a/src/include/access/heapam_xlog.h
+++ b/src/include/access/heapam_xlog.h
@@ -394,11 +394,11 @@ extern void HeapTupleHeaderAdvanceLatestRemovedXid(HeapTupleHeader tuple,
 
 extern void heap_redo(XLogReaderState *record);
 extern void heap_desc(StringInfo buf, XLogReaderState *record);
-extern const char *heap_identify(uint8 info);
+extern const char *heap_identify(uint8 rminfo);
 extern void heap_mask(char *pagedata, BlockNumber blkno);
 extern void heap2_redo(XLogReaderState *record);
 extern void heap2_desc(StringInfo buf, XLogReaderState *record);
-extern const char *heap2_identify(uint8 info);
+extern const char *heap2_identify(uint8 rminfo);
 extern void heap_xlog_logical_rewrite(XLogReaderState *r);
 
 extern XLogRecPtr log_heap_freeze(Relation reln, Buffer buffer,
diff --git a/src/include/access/multixact.h b/src/include/access/multixact.h
index 4cbe17de7b..c6021b06ea 100644
--- a/src/include/access/multixact.h
+++ b/src/include/access/multixact.h
@@ -26,6 +26,7 @@
 #define MaxMultiXactId		((MultiXactId) 0xFFFFFFFF)
 
 #define MultiXactIdIsValid(multi) ((multi) != InvalidMultiXactId)
+#define MultiXactIdIsNormal(multi) ((multi) >= FirstMultiXactId)
 
 #define MaxMultiXactOffset	((MultiXactOffset) 0xFFFFFFFF)
 
@@ -158,7 +159,7 @@ extern void multixact_twophase_postabort(TransactionId xid, uint16 info,
 
 extern void multixact_redo(XLogReaderState *record);
 extern void multixact_desc(StringInfo buf, XLogReaderState *record);
-extern const char *multixact_identify(uint8 info);
+extern const char *multixact_identify(uint8 rminfo);
 extern char *mxid_to_string(MultiXactId multi, int nmembers,
 							MultiXactMember *members);
 
diff --git a/src/include/access/nbtxlog.h b/src/include/access/nbtxlog.h
index dd504d1885..0adecc3c05 100644
--- a/src/include/access/nbtxlog.h
+++ b/src/include/access/nbtxlog.h
@@ -350,6 +350,6 @@ extern void btree_mask(char *pagedata, BlockNumber blkno);
  * prototypes for functions in nbtdesc.c
  */
 extern void btree_desc(StringInfo buf, XLogReaderState *record);
-extern const char *btree_identify(uint8 info);
+extern const char *btree_identify(uint8 rminfo);
 
 #endif							/* NBTXLOG_H */
diff --git a/src/include/access/spgxlog.h b/src/include/access/spgxlog.h
index 930ffdd4f7..06a4a4e074 100644
--- a/src/include/access/spgxlog.h
+++ b/src/include/access/spgxlog.h
@@ -249,7 +249,7 @@ typedef struct spgxlogVacuumRedirect
 
 extern void spg_redo(XLogReaderState *record);
 extern void spg_desc(StringInfo buf, XLogReaderState *record);
-extern const char *spg_identify(uint8 info);
+extern const char *spg_identify(uint8 rminfo);
 extern void spg_xlog_startup(void);
 extern void spg_xlog_cleanup(void);
 extern void spg_mask(char *pagedata, BlockNumber blkno);
diff --git a/src/include/access/xact.h b/src/include/access/xact.h
index c604ee11f8..31aabb96e3 100644
--- a/src/include/access/xact.h
+++ b/src/include/access/xact.h
@@ -512,9 +512,9 @@ extern void xact_desc(StringInfo buf, XLogReaderState *record);
 extern const char *xact_identify(uint8 info);
 
 /* also in xactdesc.c, so they can be shared between front/backend code */
-extern void ParseCommitRecord(uint8 info, xl_xact_commit *xlrec, xl_xact_parsed_commit *parsed);
-extern void ParseAbortRecord(uint8 info, xl_xact_abort *xlrec, xl_xact_parsed_abort *parsed);
-extern void ParsePrepareRecord(uint8 info, xl_xact_prepare *xlrec, xl_xact_parsed_prepare *parsed);
+extern void ParseCommitRecord(uint8 rminfo, xl_xact_commit *xlrec, xl_xact_parsed_commit *parsed);
+extern void ParseAbortRecord(uint8 rminfo, xl_xact_abort *xlrec, xl_xact_parsed_abort *parsed);
+extern void ParsePrepareRecord(uint8 rminfo, xl_xact_prepare *xlrec, xl_xact_parsed_prepare *parsed);
 
 extern void EnterParallelMode(void);
 extern void ExitParallelMode(void);
diff --git a/src/include/access/xlog.h b/src/include/access/xlog.h
index 3dbfa6b593..ba6672dd35 100644
--- a/src/include/access/xlog.h
+++ b/src/include/access/xlog.h
@@ -210,7 +210,7 @@ extern void XLogSetReplicationSlotMinimumLSN(XLogRecPtr lsn);
 
 extern void xlog_redo(XLogReaderState *record);
 extern void xlog_desc(StringInfo buf, XLogReaderState *record);
-extern const char *xlog_identify(uint8 info);
+extern const char *xlog_identify(uint8 rminfo);
 
 extern void issue_xlog_fsync(int fd, XLogSegNo segno, TimeLineID tli);
 
diff --git a/src/include/access/xloginsert.h b/src/include/access/xloginsert.h
index 001ff2f521..cfe53c7175 100644
--- a/src/include/access/xloginsert.h
+++ b/src/include/access/xloginsert.h
@@ -41,7 +41,8 @@
 /* prototypes for public functions in xloginsert.c: */
 extern void XLogBeginInsert(void);
 extern void XLogSetRecordFlags(uint8 flags);
-extern XLogRecPtr XLogInsert(RmgrId rmid, uint8 info);
+extern XLogRecPtr XLogInsert(RmgrId rmid, uint8 rminfo);
+extern XLogRecPtr XLogInsertExtended(RmgrId rmid, uint8 info, uint8 rminfo);
 extern void XLogEnsureRecordSpace(int max_block_id, int ndatas);
 extern void XLogRegisterData(char *data, uint32 len);
 extern void XLogRegisterBuffer(uint8 block_id, Buffer buffer, uint8 flags);
diff --git a/src/include/access/xlogreader.h b/src/include/access/xlogreader.h
index 6dcde2523a..db35246e88 100644
--- a/src/include/access/xlogreader.h
+++ b/src/include/access/xlogreader.h
@@ -410,6 +410,7 @@ extern bool DecodeXLogRecord(XLogReaderState *state,
 #define XLogRecGetPrev(decoder) ((decoder)->record->header.xl_prev)
 #define XLogRecGetInfo(decoder) ((decoder)->record->header.xl_info)
 #define XLogRecGetRmid(decoder) ((decoder)->record->header.xl_rmid)
+#define XLogRecGetRmInfo(decoder) ((decoder)->record->header.xl_rminfo)
 #define XLogRecGetXid(decoder) ((decoder)->record->header.xl_xid)
 #define XLogRecGetOrigin(decoder) ((decoder)->record->record_origin)
 #define XLogRecGetTopXid(decoder) ((decoder)->record->toplevel_xid)
diff --git a/src/include/access/xlogrecord.h b/src/include/access/xlogrecord.h
index 835151ec92..17093d93b6 100644
--- a/src/include/access/xlogrecord.h
+++ b/src/include/access/xlogrecord.h
@@ -45,7 +45,8 @@ typedef struct XLogRecord
 	XLogRecPtr	xl_prev;		/* ptr to previous record in log */
 	uint8		xl_info;		/* flag bits, see below */
 	RmgrId		xl_rmid;		/* resource manager for this record */
-	/* 2 bytes of padding here, initialize to zero */
+	uint8		xl_rminfo;		/* flag bits for rmgr use */
+	/* 1 byte of padding here, initialize to zero */
 	pg_crc32c	xl_crc;			/* CRC for this record */
 
 	/* XLogRecordBlockHeaders and XLogRecordDataHeader follow, no padding */
@@ -54,14 +55,6 @@ typedef struct XLogRecord
 
 #define SizeOfXLogRecord	(offsetof(XLogRecord, xl_crc) + sizeof(pg_crc32c))
 
-/*
- * The high 4 bits in xl_info may be used freely by rmgr. The
- * XLR_SPECIAL_REL_UPDATE and XLR_CHECK_CONSISTENCY bits can be passed by
- * XLogInsert caller. The rest are set internally by XLogInsert.
- */
-#define XLR_INFO_MASK			0x0F
-#define XLR_RMGR_INFO_MASK		0xF0
-
 /*
  * If a WAL record modifies any relation files, in ways not covered by the
  * usual block references, this flag is set. This is not used for anything
diff --git a/src/include/access/xlogstats.h b/src/include/access/xlogstats.h
index 7eb4370f2d..5df0f584c1 100644
--- a/src/include/access/xlogstats.h
+++ b/src/include/access/xlogstats.h
@@ -16,7 +16,7 @@
 #include "access/rmgr.h"
 #include "access/xlogreader.h"
 
-#define MAX_XLINFO_TYPES 16
+#define MAX_XLINFO_TYPES UINT8_MAX
 
 typedef struct XLogRecStats
 {
diff --git a/src/include/catalog/storage_xlog.h b/src/include/catalog/storage_xlog.h
index 44a5e2043b..4db1cdffad 100644
--- a/src/include/catalog/storage_xlog.h
+++ b/src/include/catalog/storage_xlog.h
@@ -54,6 +54,6 @@ extern void log_smgrcreate(const RelFileLocator *rlocator, ForkNumber forkNum);
 
 extern void smgr_redo(XLogReaderState *record);
 extern void smgr_desc(StringInfo buf, XLogReaderState *record);
-extern const char *smgr_identify(uint8 info);
+extern const char *smgr_identify(uint8 rminfo);
 
 #endif							/* STORAGE_XLOG_H */
diff --git a/src/include/commands/dbcommands_xlog.h b/src/include/commands/dbcommands_xlog.h
index 545e5430cc..109cd358d9 100644
--- a/src/include/commands/dbcommands_xlog.h
+++ b/src/include/commands/dbcommands_xlog.h
@@ -55,6 +55,6 @@ typedef struct xl_dbase_drop_rec
 
 extern void dbase_redo(XLogReaderState *record);
 extern void dbase_desc(StringInfo buf, XLogReaderState *record);
-extern const char *dbase_identify(uint8 info);
+extern const char *dbase_identify(uint8 rminfo);
 
 #endif							/* DBCOMMANDS_XLOG_H */
diff --git a/src/include/commands/sequence.h b/src/include/commands/sequence.h
index b3b04ccfa9..78c7b15cf2 100644
--- a/src/include/commands/sequence.h
+++ b/src/include/commands/sequence.h
@@ -64,7 +64,7 @@ extern void ResetSequenceCaches(void);
 
 extern void seq_redo(XLogReaderState *record);
 extern void seq_desc(StringInfo buf, XLogReaderState *record);
-extern const char *seq_identify(uint8 info);
+extern const char *seq_identify(uint8 rminfo);
 extern void seq_mask(char *page, BlockNumber blkno);
 
 #endif							/* SEQUENCE_H */
diff --git a/src/include/commands/tablespace.h b/src/include/commands/tablespace.h
index a11c9e9473..749413fc07 100644
--- a/src/include/commands/tablespace.h
+++ b/src/include/commands/tablespace.h
@@ -64,6 +64,6 @@ extern void remove_tablespace_symlink(const char *linkloc);
 
 extern void tblspc_redo(XLogReaderState *record);
 extern void tblspc_desc(StringInfo buf, XLogReaderState *record);
-extern const char *tblspc_identify(uint8 info);
+extern const char *tblspc_identify(uint8 rminfo);
 
 #endif							/* TABLESPACE_H */
diff --git a/src/include/replication/message.h b/src/include/replication/message.h
index 0b396c5669..6d3a77ea36 100644
--- a/src/include/replication/message.h
+++ b/src/include/replication/message.h
@@ -36,6 +36,6 @@ extern XLogRecPtr LogLogicalMessage(const char *prefix, const char *message,
 #define XLOG_LOGICAL_MESSAGE	0x00
 extern void logicalmsg_redo(XLogReaderState *record);
 extern void logicalmsg_desc(StringInfo buf, XLogReaderState *record);
-extern const char *logicalmsg_identify(uint8 info);
+extern const char *logicalmsg_identify(uint8 rminfo);
 
 #endif							/* PG_LOGICAL_MESSAGE_H */
diff --git a/src/include/storage/standbydefs.h b/src/include/storage/standbydefs.h
index c0234b6cf3..51625e45d9 100644
--- a/src/include/storage/standbydefs.h
+++ b/src/include/storage/standbydefs.h
@@ -22,7 +22,7 @@
 /* Recovery handlers for the Standby Rmgr (RM_STANDBY_ID) */
 extern void standby_redo(XLogReaderState *record);
 extern void standby_desc(StringInfo buf, XLogReaderState *record);
-extern const char *standby_identify(uint8 info);
+extern const char *standby_identify(uint8 rminfo);
 extern void standby_desc_invalidations(StringInfo buf,
 									   int nmsgs, SharedInvalidationMessage *msgs,
 									   Oid dbId, Oid tsId,
diff --git a/src/include/utils/relmapper.h b/src/include/utils/relmapper.h
index 92f1f779a4..6fd75b546f 100644
--- a/src/include/utils/relmapper.h
+++ b/src/include/utils/relmapper.h
@@ -68,6 +68,6 @@ extern void RestoreRelationMap(char *startAddress);
 
 extern void relmap_redo(XLogReaderState *record);
 extern void relmap_desc(StringInfo buf, XLogReaderState *record);
-extern const char *relmap_identify(uint8 info);
+extern const char *relmap_identify(uint8 rminfo);
 
 #endif							/* RELMAPPER_H */
-- 
2.30.2

