diff --git a/src/bin/pg_waldump/pg_waldump.c b/src/bin/pg_waldump/pg_waldump.c
index d1c1cf0fa4..0153af5517 100644
--- a/src/bin/pg_waldump/pg_waldump.c
+++ b/src/bin/pg_waldump/pg_waldump.c
@@ -69,6 +69,8 @@ typedef struct XLogDumpStats
 
 static void fatal_error(const char *fmt,...) pg_attribute_printf(1, 2);
 
+static XLogRecPtr	lsn_to_dump;
+
 /*
  * Big red button to push when things go horribly wrong.
  */
@@ -445,6 +447,10 @@ XLogDumpDisplayRecord(XLogDumpConfig *config, XLogReaderState *record)
 	int			block_id;
 	uint8		info = XLogRecGetInfo(record);
 	XLogRecPtr	xl_prev = XLogRecGetPrev(record);
+	bool		dump_data = false;
+
+	if (record->ReadRecPtr == lsn_to_dump)
+		dump_data = true;
 
 	XLogDumpRecordLen(record, &rec_len, &fpi_len);
 
@@ -491,6 +497,27 @@ XLogDumpDisplayRecord(XLogDumpConfig *config, XLogReaderState *record)
 				else
 					printf(" FPW for WAL verification");
 			}
+
+			if (dump_data)
+			{
+				char   *path;
+				char	page[BLCKSZ];
+				FILE   *file;
+
+				/* LSN.relfilenode.blkno */
+				path = psprintf("%08x_%08x.%u_%u_%u.%u",
+								(uint32) (record->ReadRecPtr >> 32),
+								(uint32) record->ReadRecPtr,
+								rnode.spcNode, rnode.dbNode, rnode.relNode,
+								blk);
+				file = fopen(path, PG_BINARY_W);
+				if (file == NULL)
+					fatal_error("could not open output file \"%s\": %s\n",
+								path, strerror(errno));
+				RestoreBlockImage(record, block_id, page);
+				fwrite((void *) page, 1, BLCKSZ, file);
+				fclose(file);
+			}
 		}
 		putchar('\n');
 	}
@@ -745,6 +772,7 @@ main(int argc, char **argv)
 		{"limit", required_argument, NULL, 'n'},
 		{"path", required_argument, NULL, 'p'},
 		{"rmgr", required_argument, NULL, 'r'},
+		{"save-fpi", required_argument, NULL, 2},
 		{"start", required_argument, NULL, 's'},
 		{"timeline", required_argument, NULL, 't'},
 		{"xid", required_argument, NULL, 'x'},
@@ -775,6 +803,7 @@ main(int argc, char **argv)
 	config.filter_by_rmgr = -1;
 	config.filter_by_xid = InvalidTransactionId;
 	config.filter_by_xid_enabled = false;
+	lsn_to_dump = InvalidXLogRecPtr;
 	config.stats = false;
 	config.stats_per_record = false;
 
@@ -892,6 +921,17 @@ main(int argc, char **argv)
 					}
 				}
 				break;
+			case 2:
+				/* save-fpi */
+				if (sscanf(optarg, "%X/%X", &xlogid, &xrecoff) != 2)
+				{
+					fprintf(stderr, _("%s: could not parse start WAL location \"%s\"\n"),
+							progname, optarg);
+					goto bad_argument;
+				}
+				else
+					lsn_to_dump = (uint64) xlogid << 32 | xrecoff;
+				break;
 			default:
 				goto bad_argument;
 		}
