diff --git i/src/backend/access/rmgrdesc/heapdesc.c w/src/backend/access/rmgrdesc/heapdesc.c
index 5c29fd9eae2..f7105a38e81 100644
--- i/src/backend/access/rmgrdesc/heapdesc.c
+++ w/src/backend/access/rmgrdesc/heapdesc.c
@@ -114,6 +114,41 @@ heap_desc(StringInfo buf, XLogReaderState *record)
 		appendStringInfo(buf, "off %u", xlrec->offnum);
 	}
 }
+
+static void
+print_offset_array(StringInfo buf, const char *name, OffsetNumber *offsets, int count)
+{
+	if (count > 0)
+	{
+		appendStringInfo(buf, ", %s: [", name);
+		for (int i = 0; i < count; i++)
+		{
+			if (i > 0)
+				appendStringInfoString(buf, ", ");
+			appendStringInfo(buf, "%u", offsets[i]);
+		}
+		appendStringInfoString(buf, "]");
+	}
+
+}
+
+static void
+print_redirect_array(StringInfo buf, const char *name, OffsetNumber *offsets, int count)
+{
+	if (count > 0)
+	{
+		appendStringInfo(buf, ", %s: [", name);
+		for (int i = 0; i < count; i++)
+		{
+			if (i > 0)
+				appendStringInfoString(buf, ", ");
+			appendStringInfo(buf, "%u->%u", offsets[i*2], offsets[i*2+1]);
+		}
+		appendStringInfoString(buf, "]");
+	}
+
+}
+
 void
 heap2_desc(StringInfo buf, XLogReaderState *record)
 {
@@ -129,12 +164,51 @@ heap2_desc(StringInfo buf, XLogReaderState *record)
 						 xlrec->latestRemovedXid,
 						 xlrec->nredirected,
 						 xlrec->ndead);
+
+
+		if (!XLogRecHasBlockImage(record, 0))
+		{
+			OffsetNumber *end;
+			OffsetNumber *redirected;
+			OffsetNumber *nowdead;
+			OffsetNumber *nowunused;
+			int			nredirected;
+			int			ndead;
+			int			nunused;
+			Size		datalen;
+
+			redirected = (OffsetNumber *) XLogRecGetBlockData(record, 0, &datalen);
+
+			nredirected = xlrec->nredirected;
+			ndead = xlrec->ndead;
+			end = (OffsetNumber *) ((char *) redirected + datalen);
+			nowdead = redirected + (nredirected * 2);
+			nowunused = nowdead + ndead;
+			nunused = (end - nowunused);
+			Assert(nunused >= 0);
+
+			appendStringInfo(buf, " nunused %u", nunused);
+
+			print_offset_array(buf, "unused", nowunused, nunused);
+			print_redirect_array(buf, "redirected", redirected, nredirected);
+			print_offset_array(buf, "dead", nowdead, ndead);
+		}
 	}
 	else if (info == XLOG_HEAP2_VACUUM)
 	{
 		xl_heap_vacuum *xlrec = (xl_heap_vacuum *) rec;
 
 		appendStringInfo(buf, "nunused %u", xlrec->nunused);
+
+		if (!XLogRecHasBlockImage(record, 0))
+		{
+			OffsetNumber *nowunused;
+			Size		datalen;
+
+			nowunused = (OffsetNumber *) XLogRecGetBlockData(record, 0, &datalen);
+
+			print_offset_array(buf, "unused", nowunused, xlrec->nunused);
+		}
 	}
 	else if (info == XLOG_HEAP2_FREEZE_PAGE)
 	{
