diff --git a/contrib/pg_xlogdump/pg_xlogdump.c b/contrib/pg_xlogdump/pg_xlogdump.c
index 239321f..02ec9cb 100644
--- a/contrib/pg_xlogdump/pg_xlogdump.c
+++ b/contrib/pg_xlogdump/pg_xlogdump.c
@@ -15,28 +15,13 @@
 #include <dirent.h>
 #include <unistd.h>
 
-#include "access/clog.h"
-#include "access/gin_private.h"
-#include "access/gist_private.h"
-#include "access/heapam_xlog.h"
-#include "access/heapam_xlog.h"
-#include "access/multixact.h"
-#include "access/nbtree.h"
-#include "access/spgist_private.h"
-#include "access/xact.h"
-#include "access/xlog.h"
 #include "access/xlogreader.h"
 #include "access/transam.h"
 #include "catalog/pg_control.h"
 #include "catalog/storage_xlog.h"
-#include "commands/dbcommands.h"
-#include "commands/sequence.h"
-#include "commands/tablespace.h"
 #include "common/fe_memutils.h"
 #include "getopt_long.h"
 #include "rmgrdesc.h"
-#include "storage/standby.h"
-#include "utils/relmapper.h"
 
 
 static const char *progname;
@@ -457,386 +442,6 @@ XLogDumpDisplayRecord(XLogDumpConfig *config, XLogRecPtr ReadRecPtr, XLogRecord
 }
 
 /*
- * Given an xl_rmid and the high bits of xl_info, returns a string
- * describing the record type.
- */
-static const char *
-identify_record(RmgrId rmid, uint8 info)
-{
-	const RmgrDescData *desc = &RmgrDescTable[rmid];
-	const char *rec;
-
-	rec = psprintf("0x%x", info);
-
-	switch (rmid)
-	{
-		case RM_XLOG_ID:
-			switch (info)
-			{
-				case XLOG_CHECKPOINT_SHUTDOWN:
-					rec = "CHECKPOINT_SHUTDOWN";
-					break;
-				case XLOG_CHECKPOINT_ONLINE:
-					rec = "CHECKPOINT_ONLINE";
-					break;
-				case XLOG_NOOP:
-					rec = "NOOP";
-					break;
-				case XLOG_NEXTOID:
-					rec = "NEXTOID";
-					break;
-				case XLOG_SWITCH:
-					rec = "SWITCH";
-					break;
-				case XLOG_BACKUP_END:
-					rec = "BACKUP_END";
-					break;
-				case XLOG_PARAMETER_CHANGE:
-					rec = "PARAMETER_CHANGE";
-					break;
-				case XLOG_RESTORE_POINT:
-					rec = "RESTORE_POINT";
-					break;
-				case XLOG_FPW_CHANGE:
-					rec = "FPW_CHANGE";
-					break;
-				case XLOG_END_OF_RECOVERY:
-					rec = "END_OF_RECOVERY";
-					break;
-				case XLOG_FPI:
-					rec = "FPI";
-					break;
-			}
-			break;
-
-		case RM_XACT_ID:
-			switch (info)
-			{
-				case XLOG_XACT_COMMIT:
-					rec = "COMMIT";
-					break;
-				case XLOG_XACT_PREPARE:
-					rec = "PREPARE";
-					break;
-				case XLOG_XACT_ABORT:
-					rec = "ABORT";
-					break;
-				case XLOG_XACT_COMMIT_PREPARED:
-					rec = "COMMIT_PREPARED";
-					break;
-				case XLOG_XACT_ABORT_PREPARED:
-					rec = "ABORT_PREPARED";
-					break;
-				case XLOG_XACT_ASSIGNMENT:
-					rec = "ASSIGNMENT";
-					break;
-				case XLOG_XACT_COMMIT_COMPACT:
-					rec = "COMMIT_COMPACT";
-					break;
-			}
-			break;
-
-		case RM_SMGR_ID:
-			switch (info)
-			{
-				case XLOG_SMGR_CREATE:
-					rec = "CREATE";
-					break;
-				case XLOG_SMGR_TRUNCATE:
-					rec = "TRUNCATE";
-					break;
-			}
-			break;
-
-		case RM_CLOG_ID:
-			switch (info)
-			{
-				case CLOG_ZEROPAGE:
-					rec = "ZEROPAGE";
-					break;
-				case CLOG_TRUNCATE:
-					rec = "TRUNCATE";
-					break;
-			}
-			break;
-
-		case RM_DBASE_ID:
-			switch (info)
-			{
-				case XLOG_DBASE_CREATE:
-					rec = "CREATE";
-					break;
-				case XLOG_DBASE_DROP:
-					rec = "DROP";
-					break;
-			}
-			break;
-
-		case RM_TBLSPC_ID:
-			switch (info)
-			{
-				case XLOG_TBLSPC_CREATE:
-					rec = "CREATE";
-					break;
-				case XLOG_TBLSPC_DROP:
-					rec = "DROP";
-					break;
-			}
-			break;
-
-		case RM_MULTIXACT_ID:
-			switch (info)
-			{
-				case XLOG_MULTIXACT_ZERO_OFF_PAGE:
-					rec = "ZERO_OFF_PAGE";
-					break;
-				case XLOG_MULTIXACT_ZERO_MEM_PAGE:
-					rec = "ZERO_MEM_PAGE";
-					break;
-				case XLOG_MULTIXACT_CREATE_ID:
-					rec = "CREATE_ID";
-					break;
-			}
-			break;
-
-		case RM_RELMAP_ID:
-			switch (info)
-			{
-				case XLOG_RELMAP_UPDATE:
-					rec = "UPDATE";
-					break;
-			}
-			break;
-
-		case RM_STANDBY_ID:
-			switch (info)
-			{
-				case XLOG_STANDBY_LOCK:
-					rec = "LOCK";
-					break;
-				case XLOG_RUNNING_XACTS:
-					rec = "RUNNING_XACTS";
-					break;
-			}
-			break;
-
-		case RM_HEAP2_ID:
-			switch (info & XLOG_HEAP_OPMASK)
-			{
-				case XLOG_HEAP2_CLEAN:
-					rec = "CLEAN";
-					break;
-				case XLOG_HEAP2_FREEZE_PAGE:
-					rec = "FREEZE_PAGE";
-					break;
-				case XLOG_HEAP2_CLEANUP_INFO:
-					rec = "CLEANUP_INFO";
-					break;
-				case XLOG_HEAP2_VISIBLE:
-					rec = "VISIBLE";
-					break;
-				case XLOG_HEAP2_MULTI_INSERT:
-					rec = "MULTI_INSERT";
-					break;
-				case XLOG_HEAP2_LOCK_UPDATED:
-					rec = "LOCK_UPDATED";
-					break;
-				case XLOG_HEAP2_NEW_CID:
-					rec = "NEW_CID";
-					break;
-				case XLOG_HEAP2_REWRITE:
-					rec = "REWRITE";
-					break;
-			}
-
-			if (info & XLOG_HEAP_INIT_PAGE)
-				rec = psprintf("%s+INIT", rec);
-
-			break;
-
-		case RM_HEAP_ID:
-			switch (info & XLOG_HEAP_OPMASK)
-			{
-				case XLOG_HEAP_INSERT:
-					rec = "INSERT";
-					break;
-				case XLOG_HEAP_DELETE:
-					rec = "DELETE";
-					break;
-				case XLOG_HEAP_UPDATE:
-					rec = "UPDATE";
-					break;
-				case XLOG_HEAP_HOT_UPDATE:
-					rec = "HOT_UPDATE";
-					break;
-				case XLOG_HEAP_NEWPAGE:
-					rec = "NEWPAGE";
-					break;
-				case XLOG_HEAP_LOCK:
-					rec = "LOCK";
-					break;
-				case XLOG_HEAP_INPLACE:
-					rec = "INPLACE";
-					break;
-			}
-
-			if (info & XLOG_HEAP_INIT_PAGE)
-				rec = psprintf("%s+INIT", rec);
-
-			break;
-
-		case RM_BTREE_ID:
-			switch (info)
-			{
-				case XLOG_BTREE_INSERT_LEAF:
-					rec = "INSERT_LEAF";
-					break;
-				case XLOG_BTREE_INSERT_UPPER:
-					rec = "INSERT_UPPER";
-					break;
-				case XLOG_BTREE_INSERT_META:
-					rec = "INSERT_META";
-					break;
-				case XLOG_BTREE_SPLIT_L:
-					rec = "SPLIT_L";
-					break;
-				case XLOG_BTREE_SPLIT_R:
-					rec = "SPLIT_R";
-					break;
-				case XLOG_BTREE_SPLIT_L_ROOT:
-					rec = "SPLIT_L_ROOT";
-					break;
-				case XLOG_BTREE_SPLIT_R_ROOT:
-					rec = "SPLIT_R_ROOT";
-					break;
-				case XLOG_BTREE_VACUUM:
-					rec = "VACUUM";
-					break;
-				case XLOG_BTREE_DELETE:
-					rec = "DELETE";
-					break;
-				case XLOG_BTREE_MARK_PAGE_HALFDEAD:
-					rec = "MARK_PAGE_HALFDEAD";
-					break;
-				case XLOG_BTREE_UNLINK_PAGE:
-					rec = "UNLINK_PAGE";
-					break;
-				case XLOG_BTREE_UNLINK_PAGE_META:
-					rec = "UNLINK_PAGE_META";
-					break;
-				case XLOG_BTREE_NEWROOT:
-					rec = "NEWROOT";
-					break;
-				case XLOG_BTREE_REUSE_PAGE:
-					rec = "REUSE_PAGE";
-					break;
-			}
-			break;
-
-		case RM_HASH_ID:
-			break;
-
-		case RM_GIN_ID:
-			switch (info)
-			{
-				case XLOG_GIN_CREATE_INDEX:
-					rec = "CREATE_INDEX";
-					break;
-				case XLOG_GIN_CREATE_PTREE:
-					rec = "CREATE_PTREE";
-					break;
-				case XLOG_GIN_INSERT:
-					rec = "INSERT";
-					break;
-				case XLOG_GIN_SPLIT:
-					rec = "SPLIT";
-					break;
-				case XLOG_GIN_VACUUM_PAGE:
-					rec = "VACUUM_PAGE";
-					break;
-				case XLOG_GIN_VACUUM_DATA_LEAF_PAGE:
-					rec = "VACUUM_DATA_LEAF_PAGE";
-					break;
-				case XLOG_GIN_DELETE_PAGE:
-					rec = "DELETE_PAGE";
-					break;
-				case XLOG_GIN_UPDATE_META_PAGE:
-					rec = "UPDATE_META_PAGE";
-					break;
-				case XLOG_GIN_INSERT_LISTPAGE:
-					rec = "INSERT_LISTPAGE";
-					break;
-				case XLOG_GIN_DELETE_LISTPAGE:
-					rec = "DELETE_LISTPAGE";
-					break;
-			}
-			break;
-
-		case RM_GIST_ID:
-			switch (info)
-			{
-				case XLOG_GIST_PAGE_UPDATE:
-					rec = "PAGE_UPDATE";
-					break;
-				case XLOG_GIST_PAGE_SPLIT:
-					rec = "PAGE_SPLIT";
-					break;
-				case XLOG_GIST_CREATE_INDEX:
-					rec = "CREATE_INDEX";
-					break;
-			}
-			break;
-
-		case RM_SEQ_ID:
-			switch (info)
-			{
-				case XLOG_SEQ_LOG:
-					rec = "LOG";
-					break;
-			}
-			break;
-
-		case RM_SPGIST_ID:
-			switch (info)
-			{
-				case XLOG_SPGIST_CREATE_INDEX:
-					rec = "CREATE_INDEX";
-					break;
-				case XLOG_SPGIST_ADD_LEAF:
-					rec = "ADD_LEAF";
-					break;
-				case XLOG_SPGIST_MOVE_LEAFS:
-					rec = "MOVE_LEAFS";
-					break;
-				case XLOG_SPGIST_ADD_NODE:
-					rec = "ADD_NODE";
-					break;
-				case XLOG_SPGIST_SPLIT_TUPLE:
-					rec = "SPLIT_TUPLE";
-					break;
-				case XLOG_SPGIST_PICKSPLIT:
-					rec = "PICKSPLIT";
-					break;
-				case XLOG_SPGIST_VACUUM_LEAF:
-					rec = "VACUUM_LEAF";
-					break;
-				case XLOG_SPGIST_VACUUM_ROOT:
-					rec = "VACUUM_ROOT";
-					break;
-				case XLOG_SPGIST_VACUUM_REDIRECT:
-					rec = "VACUUM_REDIRECT";
-					break;
-			}
-			break;
-
-		default:
-			break;
-	}
-
-	return psprintf("%s/%s", desc->rm_name, rec);
-}
-
-/*
  * Display a single row of record counts and sizes for an rmgr or record.
  */
 static void
@@ -894,11 +499,10 @@ XLogDumpDisplayStats(XLogDumpConfig *config, XLogDumpStats *stats)
 	for (ri = 0; ri < RM_NEXT_ID; ri++)
 	{
 		uint64		count, rec_len, fpi_len;
+		const RmgrDescData *desc = &RmgrDescTable[ri];
 
 		if (!config->stats_per_record)
 		{
-			const RmgrDescData *desc = &RmgrDescTable[ri];
-
 			count = stats->rmgr_stats[ri].count;
 			rec_len = stats->rmgr_stats[ri].rec_len;
 			fpi_len = stats->rmgr_stats[ri].fpi_len;
@@ -913,6 +517,8 @@ XLogDumpDisplayStats(XLogDumpConfig *config, XLogDumpStats *stats)
 		{
 			for (rj = 0; rj < 16; rj++)
 			{
+				const char *id;
+
 				count = stats->record_stats[ri][rj].count;
 				rec_len = stats->record_stats[ri][rj].rec_len;
 				fpi_len = stats->record_stats[ri][rj].fpi_len;
@@ -921,7 +527,11 @@ XLogDumpDisplayStats(XLogDumpConfig *config, XLogDumpStats *stats)
 				if (count == 0)
 					continue;
 
-				XLogDumpStatsRow(identify_record(ri, rj << 4),
+				id = desc->rm_identify(rj << 4);
+				if (id == NULL)
+					id = psprintf("0x%x", rj << 4);
+
+				XLogDumpStatsRow(psprintf("%s/%s", desc->rm_name, id),
 								 count, 100*(double)count/total_count,
 								 rec_len, 100*(double)rec_len/total_rec_len,
 								 fpi_len, 100*(double)fpi_len/total_fpi_len,
diff --git a/contrib/pg_xlogdump/rmgrdesc.c b/contrib/pg_xlogdump/rmgrdesc.c
index cbcaaa6..dc27fd1 100644
--- a/contrib/pg_xlogdump/rmgrdesc.c
+++ b/contrib/pg_xlogdump/rmgrdesc.c
@@ -27,8 +27,8 @@
 #include "storage/standby.h"
 #include "utils/relmapper.h"
 
-#define PG_RMGR(symname,name,redo,desc,startup,cleanup) \
-	{ name, desc, },
+#define PG_RMGR(symname,name,redo,desc,identify,startup,cleanup) \
+	{ name, desc, identify, },
 
 const RmgrDescData RmgrDescTable[RM_MAX_ID + 1] = {
 #include "access/rmgrlist.h"
diff --git a/contrib/pg_xlogdump/rmgrdesc.h b/contrib/pg_xlogdump/rmgrdesc.h
index d964118..da805c5 100644
--- a/contrib/pg_xlogdump/rmgrdesc.h
+++ b/contrib/pg_xlogdump/rmgrdesc.h
@@ -14,6 +14,7 @@ typedef struct RmgrDescData
 {
 	const char *rm_name;
 	void		(*rm_desc) (StringInfo buf, XLogRecord *record);
+	const char *(*rm_identify) (uint8 info);
 } RmgrDescData;
 
 extern const RmgrDescData RmgrDescTable[];
diff --git a/src/backend/access/rmgrdesc/clogdesc.c b/src/backend/access/rmgrdesc/clogdesc.c
index e82baa8..08f225d 100644
--- a/src/backend/access/rmgrdesc/clogdesc.c
+++ b/src/backend/access/rmgrdesc/clogdesc.c
@@ -40,3 +40,21 @@ clog_desc(StringInfo buf, XLogRecord *record)
 	else
 		appendStringInfoString(buf, "UNKNOWN");
 }
+
+const char *
+clog_identify(uint8 info)
+{
+	const char *id = NULL;
+
+	switch (info)
+	{
+		case CLOG_ZEROPAGE:
+			id = "ZEROPAGE";
+			break;
+		case CLOG_TRUNCATE:
+			id = "TRUNCATE";
+			break;
+	}
+
+	return id;
+}
diff --git a/src/backend/access/rmgrdesc/dbasedesc.c b/src/backend/access/rmgrdesc/dbasedesc.c
index 0230716..38f3a39 100644
--- a/src/backend/access/rmgrdesc/dbasedesc.c
+++ b/src/backend/access/rmgrdesc/dbasedesc.c
@@ -42,3 +42,21 @@ dbase_desc(StringInfo buf, XLogRecord *record)
 	else
 		appendStringInfoString(buf, "UNKNOWN");
 }
+
+const char *
+dbase_identify(uint8 info)
+{
+	const char *id = NULL;
+
+	switch (info)
+	{
+		case XLOG_DBASE_CREATE:
+			id = "CREATE";
+			break;
+		case XLOG_DBASE_DROP:
+			id = "DROP";
+			break;
+	}
+
+	return id;
+}
diff --git a/src/backend/access/rmgrdesc/gindesc.c b/src/backend/access/rmgrdesc/gindesc.c
index 12d68d7..115ad5b 100644
--- a/src/backend/access/rmgrdesc/gindesc.c
+++ b/src/backend/access/rmgrdesc/gindesc.c
@@ -187,3 +187,45 @@ gin_desc(StringInfo buf, XLogRecord *record)
 			break;
 	}
 }
+
+const char *
+gin_identify(uint8 info)
+{
+	const char *id = NULL;
+
+	switch (info)
+	{
+		case XLOG_GIN_CREATE_INDEX:
+			id = "CREATE_INDEX";
+			break;
+		case XLOG_GIN_CREATE_PTREE:
+			id = "CREATE_PTREE";
+			break;
+		case XLOG_GIN_INSERT:
+			id = "INSERT";
+			break;
+		case XLOG_GIN_SPLIT:
+			id = "SPLIT";
+			break;
+		case XLOG_GIN_VACUUM_PAGE:
+			id = "VACUUM_PAGE";
+			break;
+		case XLOG_GIN_VACUUM_DATA_LEAF_PAGE:
+			id = "VACUUM_DATA_LEAF_PAGE";
+			break;
+		case XLOG_GIN_DELETE_PAGE:
+			id = "DELETE_PAGE";
+			break;
+		case XLOG_GIN_UPDATE_META_PAGE:
+			id = "UPDATE_META_PAGE";
+			break;
+		case XLOG_GIN_INSERT_LISTPAGE:
+			id = "INSERT_LISTPAGE";
+			break;
+		case XLOG_GIN_DELETE_LISTPAGE:
+			id = "DELETE_LISTPAGE";
+			break;
+	}
+
+	return id;
+}
diff --git a/src/backend/access/rmgrdesc/gistdesc.c b/src/backend/access/rmgrdesc/gistdesc.c
index cdac496..e4f288b 100644
--- a/src/backend/access/rmgrdesc/gistdesc.c
+++ b/src/backend/access/rmgrdesc/gistdesc.c
@@ -67,3 +67,24 @@ gist_desc(StringInfo buf, XLogRecord *record)
 			break;
 	}
 }
+
+const char *
+gist_identify(uint8 info)
+{
+	const char *id = NULL;
+
+	switch (info)
+	{
+		case XLOG_GIST_PAGE_UPDATE:
+			id = "PAGE_UPDATE";
+			break;
+		case XLOG_GIST_PAGE_SPLIT:
+			id = "PAGE_SPLIT";
+			break;
+		case XLOG_GIST_CREATE_INDEX:
+			id = "CREATE_INDEX";
+			break;
+	}
+
+	return id;
+}
diff --git a/src/backend/access/rmgrdesc/hashdesc.c b/src/backend/access/rmgrdesc/hashdesc.c
index 86a0376..c58461c 100644
--- a/src/backend/access/rmgrdesc/hashdesc.c
+++ b/src/backend/access/rmgrdesc/hashdesc.c
@@ -20,3 +20,9 @@ void
 hash_desc(StringInfo buf, XLogRecord *record)
 {
 }
+
+const char *
+hash_identify(uint8 info)
+{
+	return NULL;
+}
diff --git a/src/backend/access/rmgrdesc/heapdesc.c b/src/backend/access/rmgrdesc/heapdesc.c
index 7df18fa..e6149be 100644
--- a/src/backend/access/rmgrdesc/heapdesc.c
+++ b/src/backend/access/rmgrdesc/heapdesc.c
@@ -202,3 +202,78 @@ heap2_desc(StringInfo buf, XLogRecord *record)
 	else
 		appendStringInfoString(buf, "UNKNOWN");
 }
+
+const char *
+heap_identify(uint8 info)
+{
+	const char *id = NULL;
+
+	switch (info & XLOG_HEAP_OPMASK)
+	{
+		case XLOG_HEAP_INSERT:
+			id = "INSERT";
+			break;
+		case XLOG_HEAP_DELETE:
+			id = "DELETE";
+			break;
+		case XLOG_HEAP_UPDATE:
+			id = "UPDATE";
+			break;
+		case XLOG_HEAP_HOT_UPDATE:
+			id = "HOT_UPDATE";
+			break;
+		case XLOG_HEAP_NEWPAGE:
+			id = "NEWPAGE";
+			break;
+		case XLOG_HEAP_LOCK:
+			id = "LOCK";
+			break;
+		case XLOG_HEAP_INPLACE:
+			id = "INPLACE";
+			break;
+	}
+
+	if (info & XLOG_HEAP_INIT_PAGE)
+		id = psprintf("%s+INIT", id);
+
+	return id;
+}
+
+const char *
+heap2_identify(uint8 info)
+{
+	const char *id = NULL;
+
+	switch (info & XLOG_HEAP_OPMASK)
+	{
+		case XLOG_HEAP2_CLEAN:
+			id = "CLEAN";
+			break;
+		case XLOG_HEAP2_FREEZE_PAGE:
+			id = "FREEZE_PAGE";
+			break;
+		case XLOG_HEAP2_CLEANUP_INFO:
+			id = "CLEANUP_INFO";
+			break;
+		case XLOG_HEAP2_VISIBLE:
+			id = "VISIBLE";
+			break;
+		case XLOG_HEAP2_MULTI_INSERT:
+			id = "MULTI_INSERT";
+			break;
+		case XLOG_HEAP2_LOCK_UPDATED:
+			id = "LOCK_UPDATED";
+			break;
+		case XLOG_HEAP2_NEW_CID:
+			id = "NEW_CID";
+			break;
+		case XLOG_HEAP2_REWRITE:
+			id = "REWRITE";
+			break;
+	}
+
+	if (info & XLOG_HEAP_INIT_PAGE)
+		id = psprintf("%s+INIT", id);
+
+	return id;
+}
diff --git a/src/backend/access/rmgrdesc/mxactdesc.c b/src/backend/access/rmgrdesc/mxactdesc.c
index 50d9b55..d77b1c8 100644
--- a/src/backend/access/rmgrdesc/mxactdesc.c
+++ b/src/backend/access/rmgrdesc/mxactdesc.c
@@ -79,3 +79,24 @@ multixact_desc(StringInfo buf, XLogRecord *record)
 	else
 		appendStringInfoString(buf, "UNKNOWN");
 }
+
+const char *
+multixact_identify(uint8 info)
+{
+	const char *id = NULL;
+
+	switch (info)
+	{
+		case XLOG_MULTIXACT_ZERO_OFF_PAGE:
+			id = "ZERO_OFF_PAGE";
+			break;
+		case XLOG_MULTIXACT_ZERO_MEM_PAGE:
+			id = "ZERO_MEM_PAGE";
+			break;
+		case XLOG_MULTIXACT_CREATE_ID:
+			id = "CREATE_ID";
+			break;
+	}
+
+	return id;
+}
diff --git a/src/backend/access/rmgrdesc/nbtdesc.c b/src/backend/access/rmgrdesc/nbtdesc.c
index bf3389c..821715c 100644
--- a/src/backend/access/rmgrdesc/nbtdesc.c
+++ b/src/backend/access/rmgrdesc/nbtdesc.c
@@ -172,3 +172,57 @@ btree_desc(StringInfo buf, XLogRecord *record)
 			break;
 	}
 }
+
+const char *
+btree_identify(uint8 info)
+{
+	const char *id = NULL;
+
+	switch (info)
+	{
+		case XLOG_BTREE_INSERT_LEAF:
+			id = "INSERT_LEAF";
+			break;
+		case XLOG_BTREE_INSERT_UPPER:
+			id = "INSERT_UPPER";
+			break;
+		case XLOG_BTREE_INSERT_META:
+			id = "INSERT_META";
+			break;
+		case XLOG_BTREE_SPLIT_L:
+			id = "SPLIT_L";
+			break;
+		case XLOG_BTREE_SPLIT_R:
+			id = "SPLIT_R";
+			break;
+		case XLOG_BTREE_SPLIT_L_ROOT:
+			id = "SPLIT_L_ROOT";
+			break;
+		case XLOG_BTREE_SPLIT_R_ROOT:
+			id = "SPLIT_R_ROOT";
+			break;
+		case XLOG_BTREE_VACUUM:
+			id = "VACUUM";
+			break;
+		case XLOG_BTREE_DELETE:
+			id = "DELETE";
+			break;
+		case XLOG_BTREE_MARK_PAGE_HALFDEAD:
+			id = "MARK_PAGE_HALFDEAD";
+			break;
+		case XLOG_BTREE_UNLINK_PAGE:
+			id = "UNLINK_PAGE";
+			break;
+		case XLOG_BTREE_UNLINK_PAGE_META:
+			id = "UNLINK_PAGE_META";
+			break;
+		case XLOG_BTREE_NEWROOT:
+			id = "NEWROOT";
+			break;
+		case XLOG_BTREE_REUSE_PAGE:
+			id = "REUSE_PAGE";
+			break;
+	}
+
+	return id;
+}
diff --git a/src/backend/access/rmgrdesc/relmapdesc.c b/src/backend/access/rmgrdesc/relmapdesc.c
index 06fd4b3..2aebf22 100644
--- a/src/backend/access/rmgrdesc/relmapdesc.c
+++ b/src/backend/access/rmgrdesc/relmapdesc.c
@@ -32,3 +32,18 @@ relmap_desc(StringInfo buf, XLogRecord *record)
 	else
 		appendStringInfoString(buf, "UNKNOWN");
 }
+
+const char *
+relmap_identify(uint8 info)
+{
+	const char *id = NULL;
+
+	switch (info)
+	{
+		case XLOG_RELMAP_UPDATE:
+			id = "UPDATE";
+			break;
+	}
+
+	return id;
+}
diff --git a/src/backend/access/rmgrdesc/seqdesc.c b/src/backend/access/rmgrdesc/seqdesc.c
index 42eb9b9..157c7c6 100644
--- a/src/backend/access/rmgrdesc/seqdesc.c
+++ b/src/backend/access/rmgrdesc/seqdesc.c
@@ -35,3 +35,18 @@ seq_desc(StringInfo buf, XLogRecord *record)
 	appendStringInfo(buf, "rel %u/%u/%u",
 			   xlrec->node.spcNode, xlrec->node.dbNode, xlrec->node.relNode);
 }
+
+const char *
+seq_identify(uint8 info)
+{
+	const char *id = NULL;
+
+	switch (info)
+	{
+		case XLOG_SEQ_LOG:
+			id = "LOG";
+			break;
+	}
+
+	return id;
+}
diff --git a/src/backend/access/rmgrdesc/smgrdesc.c b/src/backend/access/rmgrdesc/smgrdesc.c
index c76c815..0a7a6e2 100644
--- a/src/backend/access/rmgrdesc/smgrdesc.c
+++ b/src/backend/access/rmgrdesc/smgrdesc.c
@@ -44,3 +44,21 @@ smgr_desc(StringInfo buf, XLogRecord *record)
 	else
 		appendStringInfoString(buf, "UNKNOWN");
 }
+
+const char *
+smgr_identify(uint8 info)
+{
+	const char *id = NULL;
+
+	switch (info)
+	{
+		case XLOG_SMGR_CREATE:
+			id = "CREATE";
+			break;
+		case XLOG_SMGR_TRUNCATE:
+			id = "TRUNCATE";
+			break;
+	}
+
+	return id;
+}
diff --git a/src/backend/access/rmgrdesc/spgdesc.c b/src/backend/access/rmgrdesc/spgdesc.c
index ed369b2..76f43ff 100644
--- a/src/backend/access/rmgrdesc/spgdesc.c
+++ b/src/backend/access/rmgrdesc/spgdesc.c
@@ -88,3 +88,42 @@ spg_desc(StringInfo buf, XLogRecord *record)
 			break;
 	}
 }
+
+const char *
+spg_identify(uint8 info)
+{
+	const char *id = NULL;
+
+	switch (info)
+	{
+		case XLOG_SPGIST_CREATE_INDEX:
+			id = "CREATE_INDEX";
+			break;
+		case XLOG_SPGIST_ADD_LEAF:
+			id = "ADD_LEAF";
+			break;
+		case XLOG_SPGIST_MOVE_LEAFS:
+			id = "MOVE_LEAFS";
+			break;
+		case XLOG_SPGIST_ADD_NODE:
+			id = "ADD_NODE";
+			break;
+		case XLOG_SPGIST_SPLIT_TUPLE:
+			id = "SPLIT_TUPLE";
+			break;
+		case XLOG_SPGIST_PICKSPLIT:
+			id = "PICKSPLIT";
+			break;
+		case XLOG_SPGIST_VACUUM_LEAF:
+			id = "VACUUM_LEAF";
+			break;
+		case XLOG_SPGIST_VACUUM_ROOT:
+			id = "VACUUM_ROOT";
+			break;
+		case XLOG_SPGIST_VACUUM_REDIRECT:
+			id = "VACUUM_REDIRECT";
+			break;
+	}
+
+	return id;
+}
diff --git a/src/backend/access/rmgrdesc/standbydesc.c b/src/backend/access/rmgrdesc/standbydesc.c
index a127d38..77503d4 100644
--- a/src/backend/access/rmgrdesc/standbydesc.c
+++ b/src/backend/access/rmgrdesc/standbydesc.c
@@ -64,3 +64,21 @@ standby_desc(StringInfo buf, XLogRecord *record)
 	else
 		appendStringInfoString(buf, "UNKNOWN");
 }
+
+const char *
+standby_identify(uint8 info)
+{
+	const char *id = NULL;
+
+	switch (info)
+	{
+		case XLOG_STANDBY_LOCK:
+			id = "LOCK";
+			break;
+		case XLOG_RUNNING_XACTS:
+			id = "RUNNING_XACTS";
+			break;
+	}
+
+	return id;
+}
diff --git a/src/backend/access/rmgrdesc/tblspcdesc.c b/src/backend/access/rmgrdesc/tblspcdesc.c
index 30b1f06..c947845 100644
--- a/src/backend/access/rmgrdesc/tblspcdesc.c
+++ b/src/backend/access/rmgrdesc/tblspcdesc.c
@@ -39,3 +39,21 @@ tblspc_desc(StringInfo buf, XLogRecord *record)
 	else
 		appendStringInfoString(buf, "UNKNOWN");
 }
+
+const char *
+tblspc_identify(uint8 info)
+{
+	const char *id = NULL;
+
+	switch (info)
+	{
+		case XLOG_TBLSPC_CREATE:
+			id = "CREATE";
+			break;
+		case XLOG_TBLSPC_DROP:
+			id = "DROP";
+			break;
+	}
+
+	return id;
+}
diff --git a/src/backend/access/rmgrdesc/xactdesc.c b/src/backend/access/rmgrdesc/xactdesc.c
index 994931e..8ea10c9 100644
--- a/src/backend/access/rmgrdesc/xactdesc.c
+++ b/src/backend/access/rmgrdesc/xactdesc.c
@@ -196,3 +196,36 @@ xact_desc(StringInfo buf, XLogRecord *record)
 	else
 		appendStringInfoString(buf, "UNKNOWN");
 }
+
+const char *
+xact_identify(uint8 info)
+{
+	const char *id = NULL;
+
+	switch (info)
+	{
+		case XLOG_XACT_COMMIT:
+			id = "COMMIT";
+			break;
+		case XLOG_XACT_PREPARE:
+			id = "PREPARE";
+			break;
+		case XLOG_XACT_ABORT:
+			id = "ABORT";
+			break;
+		case XLOG_XACT_COMMIT_PREPARED:
+			id = "COMMIT_PREPARED";
+			break;
+		case XLOG_XACT_ABORT_PREPARED:
+			id = "ABORT_PREPARED";
+			break;
+		case XLOG_XACT_ASSIGNMENT:
+			id = "ASSIGNMENT";
+			break;
+		case XLOG_XACT_COMMIT_COMPACT:
+			id = "COMMIT_COMPACT";
+			break;
+	}
+
+	return id;
+}
diff --git a/src/backend/access/rmgrdesc/xlogdesc.c b/src/backend/access/rmgrdesc/xlogdesc.c
index 2224da1..04a1f24 100644
--- a/src/backend/access/rmgrdesc/xlogdesc.c
+++ b/src/backend/access/rmgrdesc/xlogdesc.c
@@ -144,3 +144,48 @@ xlog_desc(StringInfo buf, XLogRecord *record)
 	else
 		appendStringInfoString(buf, "UNKNOWN");
 }
+
+const char *
+xlog_identify(uint8 info)
+{
+	const char *id = NULL;
+
+	switch (info)
+	{
+		case XLOG_CHECKPOINT_SHUTDOWN:
+			id = "CHECKPOINT_SHUTDOWN";
+			break;
+		case XLOG_CHECKPOINT_ONLINE:
+			id = "CHECKPOINT_ONLINE";
+			break;
+		case XLOG_NOOP:
+			id = "NOOP";
+			break;
+		case XLOG_NEXTOID:
+			id = "NEXTOID";
+			break;
+		case XLOG_SWITCH:
+			id = "SWITCH";
+			break;
+		case XLOG_BACKUP_END:
+			id = "BACKUP_END";
+			break;
+		case XLOG_PARAMETER_CHANGE:
+			id = "PARAMETER_CHANGE";
+			break;
+		case XLOG_RESTORE_POINT:
+			id = "RESTORE_POINT";
+			break;
+		case XLOG_FPW_CHANGE:
+			id = "FPW_CHANGE";
+			break;
+		case XLOG_END_OF_RECOVERY:
+			id = "END_OF_RECOVERY";
+			break;
+		case XLOG_FPI:
+			id = "FPI";
+			break;
+	}
+
+	return id;
+}
diff --git a/src/backend/access/transam/rmgr.c b/src/backend/access/transam/rmgr.c
index c0a7a6f..2645a7a 100644
--- a/src/backend/access/transam/rmgr.c
+++ b/src/backend/access/transam/rmgr.c
@@ -25,8 +25,8 @@
 #include "utils/relmapper.h"
 
 /* must be kept in sync with RmgrData definition in xlog_internal.h */
-#define PG_RMGR(symname,name,redo,desc,startup,cleanup) \
-	{ name, redo, desc, startup, cleanup },
+#define PG_RMGR(symname,name,redo,desc,identify,startup,cleanup) \
+	{ name, redo, desc, identify, startup, cleanup },
 
 const RmgrData RmgrTable[RM_MAX_ID + 1] = {
 #include "access/rmgrlist.h"
diff --git a/src/include/access/clog.h b/src/include/access/clog.h
index be9b867..8562631 100644
--- a/src/include/access/clog.h
+++ b/src/include/access/clog.h
@@ -49,5 +49,6 @@ extern void TruncateCLOG(TransactionId oldestXact);
 
 extern void clog_redo(XLogRecPtr lsn, XLogRecord *record);
 extern void clog_desc(StringInfo buf, XLogRecord *record);
+extern const char *clog_identify(uint8 info);
 
 #endif   /* CLOG_H */
diff --git a/src/include/access/gin.h b/src/include/access/gin.h
index a0b288d..0ebecb4 100644
--- a/src/include/access/gin.h
+++ b/src/include/access/gin.h
@@ -74,6 +74,7 @@ extern void ginUpdateStats(Relation index, const GinStatsData *stats);
 /* ginxlog.c */
 extern void gin_redo(XLogRecPtr lsn, XLogRecord *record);
 extern void gin_desc(StringInfo buf, XLogRecord *record);
+extern const char *gin_identify(uint8 info);
 extern void gin_xlog_startup(void);
 extern void gin_xlog_cleanup(void);
 
diff --git a/src/include/access/gist_private.h b/src/include/access/gist_private.h
index 03e9903..879f113 100644
--- a/src/include/access/gist_private.h
+++ b/src/include/access/gist_private.h
@@ -452,6 +452,7 @@ extern SplitedPageLayout *gistSplit(Relation r, Page page, IndexTuple *itup,
 /* gistxlog.c */
 extern void gist_redo(XLogRecPtr lsn, XLogRecord *record);
 extern void gist_desc(StringInfo buf, XLogRecord *record);
+extern const char *gist_identify(uint8 info);
 extern void gist_xlog_startup(void);
 extern void gist_xlog_cleanup(void);
 
diff --git a/src/include/access/hash.h b/src/include/access/hash.h
index 42a1d94..950c1a4 100644
--- a/src/include/access/hash.h
+++ b/src/include/access/hash.h
@@ -357,5 +357,6 @@ extern OffsetNumber _hash_binsearch_last(Page page, uint32 hash_value);
 /* hash.c */
 extern void hash_redo(XLogRecPtr lsn, XLogRecord *record);
 extern void hash_desc(StringInfo buf, XLogRecord *record);
+extern const char *hash_identify(uint8 info);
 
 #endif   /* HASH_H */
diff --git a/src/include/access/heapam_xlog.h b/src/include/access/heapam_xlog.h
index 05beb00..0e00a11 100644
--- a/src/include/access/heapam_xlog.h
+++ b/src/include/access/heapam_xlog.h
@@ -369,8 +369,10 @@ extern void HeapTupleHeaderAdvanceLatestRemovedXid(HeapTupleHeader tuple,
 
 extern void heap_redo(XLogRecPtr lsn, XLogRecord *record);
 extern void heap_desc(StringInfo buf, XLogRecord *record);
+extern const char *heap_identify(uint8 info);
 extern void heap2_redo(XLogRecPtr lsn, XLogRecord *record);
 extern void heap2_desc(StringInfo buf, XLogRecord *record);
+extern const char *heap2_identify(uint8 info);
 extern void heap_xlog_logical_rewrite(XLogRecPtr lsn, XLogRecord *r);
 
 extern XLogRecPtr log_heap_cleanup_info(RelFileNode rnode,
diff --git a/src/include/access/multixact.h b/src/include/access/multixact.h
index f6d2e04..1910e7a 100644
--- a/src/include/access/multixact.h
+++ b/src/include/access/multixact.h
@@ -136,6 +136,7 @@ extern void multixact_twophase_postabort(TransactionId xid, uint16 info,
 
 extern void multixact_redo(XLogRecPtr lsn, XLogRecord *record);
 extern void multixact_desc(StringInfo buf, XLogRecord *record);
+extern const char *multixact_identify(uint8 info);
 extern char *mxid_to_string(MultiXactId multi, int nmembers,
 			   MultiXactMember *members);
 
diff --git a/src/include/access/nbtree.h b/src/include/access/nbtree.h
index 9fa943f..90fd6d0 100644
--- a/src/include/access/nbtree.h
+++ b/src/include/access/nbtree.h
@@ -726,5 +726,6 @@ extern void _bt_leafbuild(BTSpool *btspool, BTSpool *spool2);
  */
 extern void btree_redo(XLogRecPtr lsn, XLogRecord *record);
 extern void btree_desc(StringInfo buf, XLogRecord *record);
+extern const char *btree_identify(uint8 info);
 
 #endif   /* NBTREE_H */
diff --git a/src/include/access/rmgr.h b/src/include/access/rmgr.h
index 1b577a2..ff7fe62 100644
--- a/src/include/access/rmgr.h
+++ b/src/include/access/rmgr.h
@@ -19,7 +19,7 @@ typedef uint8 RmgrId;
  * Note: RM_MAX_ID must fit in RmgrId; widening that type will affect the XLOG
  * file format.
  */
-#define PG_RMGR(symname,name,redo,desc,startup,cleanup) \
+#define PG_RMGR(symname,name,redo,desc,identify,startup,cleanup) \
 	symname,
 
 typedef enum RmgrIds
diff --git a/src/include/access/rmgrlist.h b/src/include/access/rmgrlist.h
index 662fb77..77d4574 100644
--- a/src/include/access/rmgrlist.h
+++ b/src/include/access/rmgrlist.h
@@ -25,20 +25,20 @@
  */
 
 /* symbol name, textual name, redo, desc, startup, cleanup */
-PG_RMGR(RM_XLOG_ID, "XLOG", xlog_redo, xlog_desc, NULL, NULL)
-PG_RMGR(RM_XACT_ID, "Transaction", xact_redo, xact_desc, NULL, NULL)
-PG_RMGR(RM_SMGR_ID, "Storage", smgr_redo, smgr_desc, NULL, NULL)
-PG_RMGR(RM_CLOG_ID, "CLOG", clog_redo, clog_desc, NULL, NULL)
-PG_RMGR(RM_DBASE_ID, "Database", dbase_redo, dbase_desc, NULL, NULL)
-PG_RMGR(RM_TBLSPC_ID, "Tablespace", tblspc_redo, tblspc_desc, NULL, NULL)
-PG_RMGR(RM_MULTIXACT_ID, "MultiXact", multixact_redo, multixact_desc, NULL, NULL)
-PG_RMGR(RM_RELMAP_ID, "RelMap", relmap_redo, relmap_desc, NULL, NULL)
-PG_RMGR(RM_STANDBY_ID, "Standby", standby_redo, standby_desc, NULL, NULL)
-PG_RMGR(RM_HEAP2_ID, "Heap2", heap2_redo, heap2_desc, NULL, NULL)
-PG_RMGR(RM_HEAP_ID, "Heap", heap_redo, heap_desc, NULL, NULL)
-PG_RMGR(RM_BTREE_ID, "Btree", btree_redo, btree_desc, NULL, NULL)
-PG_RMGR(RM_HASH_ID, "Hash", hash_redo, hash_desc, NULL, NULL)
-PG_RMGR(RM_GIN_ID, "Gin", gin_redo, gin_desc, gin_xlog_startup, gin_xlog_cleanup)
-PG_RMGR(RM_GIST_ID, "Gist", gist_redo, gist_desc, gist_xlog_startup, gist_xlog_cleanup)
-PG_RMGR(RM_SEQ_ID, "Sequence", seq_redo, seq_desc, NULL, NULL)
-PG_RMGR(RM_SPGIST_ID, "SPGist", spg_redo, spg_desc, spg_xlog_startup, spg_xlog_cleanup)
+PG_RMGR(RM_XLOG_ID, "XLOG", xlog_redo, xlog_desc, xlog_identify, NULL, NULL)
+PG_RMGR(RM_XACT_ID, "Transaction", xact_redo, xact_desc, xact_identify, NULL, NULL)
+PG_RMGR(RM_SMGR_ID, "Storage", smgr_redo, smgr_desc, smgr_identify, NULL, NULL)
+PG_RMGR(RM_CLOG_ID, "CLOG", clog_redo, clog_desc, clog_identify, NULL, NULL)
+PG_RMGR(RM_DBASE_ID, "Database", dbase_redo, dbase_desc, dbase_identify, NULL, NULL)
+PG_RMGR(RM_TBLSPC_ID, "Tablespace", tblspc_redo, tblspc_desc, tblspc_identify, NULL, NULL)
+PG_RMGR(RM_MULTIXACT_ID, "MultiXact", multixact_redo, multixact_desc, multixact_identify, NULL, NULL)
+PG_RMGR(RM_RELMAP_ID, "RelMap", relmap_redo, relmap_desc, relmap_identify, NULL, NULL)
+PG_RMGR(RM_STANDBY_ID, "Standby", standby_redo, standby_desc, standby_identify, NULL, NULL)
+PG_RMGR(RM_HEAP2_ID, "Heap2", heap2_redo, heap2_desc, heap2_identify, NULL, NULL)
+PG_RMGR(RM_HEAP_ID, "Heap", heap_redo, heap_desc, heap_identify, NULL, NULL)
+PG_RMGR(RM_BTREE_ID, "Btree", btree_redo, btree_desc, btree_identify, NULL, NULL)
+PG_RMGR(RM_HASH_ID, "Hash", hash_redo, hash_desc, hash_identify, NULL, NULL)
+PG_RMGR(RM_GIN_ID, "Gin", gin_redo, gin_desc, gin_identify, gin_xlog_startup, gin_xlog_cleanup)
+PG_RMGR(RM_GIST_ID, "Gist", gist_redo, gist_desc, gist_identify, gist_xlog_startup, gist_xlog_cleanup)
+PG_RMGR(RM_SEQ_ID, "Sequence", seq_redo, seq_desc, seq_identify, NULL, NULL)
+PG_RMGR(RM_SPGIST_ID, "SPGist", spg_redo, spg_desc, spg_identify, spg_xlog_startup, spg_xlog_cleanup)
diff --git a/src/include/access/spgist.h b/src/include/access/spgist.h
index 7f8655c..f218a83 100644
--- a/src/include/access/spgist.h
+++ b/src/include/access/spgist.h
@@ -198,6 +198,7 @@ extern Datum spgvacuumcleanup(PG_FUNCTION_ARGS);
 /* spgxlog.c */
 extern void spg_redo(XLogRecPtr lsn, XLogRecord *record);
 extern void spg_desc(StringInfo buf, XLogRecord *record);
+extern const char *spg_identify(uint8 info);
 extern void spg_xlog_startup(void);
 extern void spg_xlog_cleanup(void);
 
diff --git a/src/include/access/xact.h b/src/include/access/xact.h
index 10ee943..ff7c426 100644
--- a/src/include/access/xact.h
+++ b/src/include/access/xact.h
@@ -257,5 +257,6 @@ extern int	xactGetCommittedChildren(TransactionId **ptr);
 
 extern void xact_redo(XLogRecPtr lsn, XLogRecord *record);
 extern void xact_desc(StringInfo buf, XLogRecord *record);
+extern const char *xact_identify(uint8 info);
 
 #endif   /* XACT_H */
diff --git a/src/include/access/xlog.h b/src/include/access/xlog.h
index 85f9cb7..e16d43c 100644
--- a/src/include/access/xlog.h
+++ b/src/include/access/xlog.h
@@ -299,6 +299,7 @@ extern Buffer RestoreBackupBlock(XLogRecPtr lsn, XLogRecord *record,
 
 extern void xlog_redo(XLogRecPtr lsn, XLogRecord *record);
 extern void xlog_desc(StringInfo buf, XLogRecord *record);
+extern const char *xlog_identify(uint8 info);
 
 extern void issue_xlog_fsync(int fd, XLogSegNo segno);
 
diff --git a/src/include/access/xlog_internal.h b/src/include/access/xlog_internal.h
index 8c8de38..5839426 100644
--- a/src/include/access/xlog_internal.h
+++ b/src/include/access/xlog_internal.h
@@ -246,6 +246,7 @@ typedef struct RmgrData
 	const char *rm_name;
 	void		(*rm_redo) (XLogRecPtr lsn, struct XLogRecord *rptr);
 	void		(*rm_desc) (StringInfo buf, struct XLogRecord *rptr);
+	const char *(*rm_identify) (uint8 info);
 	void		(*rm_startup) (void);
 	void		(*rm_cleanup) (void);
 } RmgrData;
diff --git a/src/include/catalog/storage_xlog.h b/src/include/catalog/storage_xlog.h
index 7081c99..5fc7235 100644
--- a/src/include/catalog/storage_xlog.h
+++ b/src/include/catalog/storage_xlog.h
@@ -45,5 +45,6 @@ extern void log_smgrcreate(RelFileNode *rnode, ForkNumber forkNum);
 
 extern void smgr_redo(XLogRecPtr lsn, XLogRecord *record);
 extern void smgr_desc(StringInfo buf, XLogRecord *record);
+extern const char *smgr_identify(uint8 info);
 
 #endif   /* STORAGE_XLOG_H */
diff --git a/src/include/commands/dbcommands.h b/src/include/commands/dbcommands.h
index c2380dc..811713f 100644
--- a/src/include/commands/dbcommands.h
+++ b/src/include/commands/dbcommands.h
@@ -64,6 +64,7 @@ extern char *get_database_name(Oid dbid);
 
 extern void dbase_redo(XLogRecPtr lsn, XLogRecord *rptr);
 extern void dbase_desc(StringInfo buf, XLogRecord *rptr);
+extern const char *dbase_identify(uint8 info);
 
 extern void check_encoding_locale_matches(int encoding, const char *collate, const char *ctype);
 
diff --git a/src/include/commands/sequence.h b/src/include/commands/sequence.h
index 8819c00..914d155 100644
--- a/src/include/commands/sequence.h
+++ b/src/include/commands/sequence.h
@@ -78,5 +78,6 @@ extern void ResetSequenceCaches(void);
 
 extern void seq_redo(XLogRecPtr lsn, XLogRecord *rptr);
 extern void seq_desc(StringInfo buf, XLogRecord *rptr);
+extern const char *seq_identify(uint8 info);
 
 #endif   /* SEQUENCE_H */
diff --git a/src/include/commands/tablespace.h b/src/include/commands/tablespace.h
index 073cb0d..5823bd9 100644
--- a/src/include/commands/tablespace.h
+++ b/src/include/commands/tablespace.h
@@ -58,5 +58,6 @@ extern bool directory_is_empty(const char *path);
 
 extern void tblspc_redo(XLogRecPtr lsn, XLogRecord *rptr);
 extern void tblspc_desc(StringInfo buf, XLogRecord *rptr);
+extern const char *tblspc_identify(uint8 info);
 
 #endif   /* TABLESPACE_H */
diff --git a/src/include/storage/standby.h b/src/include/storage/standby.h
index da22fd3..1c63af5 100644
--- a/src/include/storage/standby.h
+++ b/src/include/storage/standby.h
@@ -83,6 +83,7 @@ typedef struct xl_running_xacts
 /* Recovery handlers for the Standby Rmgr (RM_STANDBY_ID) */
 extern void standby_redo(XLogRecPtr lsn, XLogRecord *record);
 extern void standby_desc(StringInfo buf, XLogRecord *record);
+extern const char *standby_identify(uint8 info);
 
 /*
  * Declarations for GetRunningTransactionData(). Similar to Snapshots, but
diff --git a/src/include/utils/relmapper.h b/src/include/utils/relmapper.h
index 76bcf18..37937dd 100644
--- a/src/include/utils/relmapper.h
+++ b/src/include/utils/relmapper.h
@@ -60,5 +60,6 @@ extern void RelationMapInitializePhase3(void);
 
 extern void relmap_redo(XLogRecPtr lsn, XLogRecord *record);
 extern void relmap_desc(StringInfo buf, XLogRecord *record);
+extern const char *relmap_identify(uint8 info);
 
 #endif   /* RELMAPPER_H */
