diff --git a/src/bin/pg_waldump/pg_waldump.c b/src/bin/pg_waldump/pg_waldump.c
index 31e99c2a6d..011606ecf2 100644
--- a/src/bin/pg_waldump/pg_waldump.c
+++ b/src/bin/pg_waldump/pg_waldump.c
@@ -24,6 +24,7 @@
 #include "common/logging.h"
 #include "getopt_long.h"
 #include "rmgrdesc.h"
+#include "catalog/pg_control.h"
 
 static const char *progname;
 
@@ -380,9 +381,11 @@ WALDumpReadPage(XLogReaderState *state, XLogRecPtr targetPagePtr, int reqLen,
  * Calculate the size of a record, split into !FPI and FPI parts.
  */
 static void
-XLogDumpRecordLen(XLogReaderState *record, uint32 *rec_len, uint32 *fpi_len)
+XLogDumpRecordLen(XLogReaderState *record, uint32 *rec_len, uint32 *fpi_len, uint32 *junk_len)
 {
 	int			block_id;
+	RmgrId		rmid;
+	uint8		info;
 
 	/*
 	 * Calculate the amount of FPI data in the record.
@@ -403,6 +406,31 @@ XLogDumpRecordLen(XLogReaderState *record, uint32 *rec_len, uint32 *fpi_len)
 	 * all the block images.
 	 */
 	*rec_len = XLogRecGetTotalLen(record) - *fpi_len;
+
+	rmid = XLogRecGetRmid(record);
+	info = XLogRecGetInfo(record) & ~XLR_INFO_MASK;
+
+	/*
+	 * If it's a wal switch record, we should caculate the junk size which skipped
+	 * by this record.
+	 */
+	*junk_len = 0;
+	if(RM_XLOG_ID == rmid && XLOG_SWITCH == info)
+	{
+		XLogSegNo	startSegNo;
+		XLogSegNo	endSegNo;
+
+		XLByteToSeg(record->ReadRecPtr, startSegNo, record->segcxt.ws_segsize);
+		XLByteToSeg(record->EndRecPtr, endSegNo, record->segcxt.ws_segsize);
+
+		*junk_len = record->EndRecPtr - record->ReadRecPtr - XLogRecGetTotalLen(record);
+		/*
+		 * If the wal switch record spread on two segments, we should extra minus the
+		 * long page head.
+		 */
+		if(startSegNo != endSegNo)
+			*junk_len -= SizeOfXLogLongPHD;
+	}
 }
 
 /*
@@ -416,12 +444,14 @@ XLogDumpCountRecord(XLogDumpConfig *config, XLogDumpStats *stats,
 	uint8		recid;
 	uint32		rec_len;
 	uint32		fpi_len;
+	uint32		junk_len;
 
 	stats->count++;
 
 	rmid = XLogRecGetRmid(record);
 
-	XLogDumpRecordLen(record, &rec_len, &fpi_len);
+	XLogDumpRecordLen(record, &rec_len, &fpi_len, &junk_len);
+	rec_len += junk_len;
 
 	/* Update per-rmgr statistics */
 
@@ -435,9 +465,7 @@ XLogDumpCountRecord(XLogDumpConfig *config, XLogDumpStats *stats,
 	 * are the rmgr's domain (resulting in sixteen possible entries per
 	 * RmgrId).
 	 */
-
 	recid = XLogRecGetInfo(record) >> 4;
-
 	stats->record_stats[rmid][recid].count++;
 	stats->record_stats[rmid][recid].rec_len += rec_len;
 	stats->record_stats[rmid][recid].fpi_len += fpi_len;
@@ -453,6 +481,7 @@ XLogDumpDisplayRecord(XLogDumpConfig *config, XLogReaderState *record)
 	const RmgrDescData *desc = &RmgrDescTable[XLogRecGetRmid(record)];
 	uint32		rec_len;
 	uint32		fpi_len;
+	uint32		junk_len;
 	RelFileNode rnode;
 	ForkNumber	forknum;
 	BlockNumber blk;
@@ -461,11 +490,11 @@ XLogDumpDisplayRecord(XLogDumpConfig *config, XLogReaderState *record)
 	XLogRecPtr	xl_prev = XLogRecGetPrev(record);
 	StringInfoData s;
 
-	XLogDumpRecordLen(record, &rec_len, &fpi_len);
+	XLogDumpRecordLen(record, &rec_len, &fpi_len, &junk_len);
 
 	printf("rmgr: %-11s len (rec/tot): %6u/%6u, tx: %10u, lsn: %X/%08X, prev %X/%08X, ",
 		   desc->rm_name,
-		   rec_len, XLogRecGetTotalLen(record),
+		   rec_len, XLogRecGetTotalLen(record) + junk_len,
 		   XLogRecGetXid(record),
 		   (uint32) (record->ReadRecPtr >> 32), (uint32) record->ReadRecPtr,
 		   (uint32) (xl_prev >> 32), (uint32) xl_prev);
