Hi,

On 2020-03-29 21:23:06 -0400, David Steele wrote:
> On 3/29/20 9:07 PM, Andres Freund wrote:
> > On 2020-03-29 20:42:35 -0400, Robert Haas wrote:
> > > > What do you think of having the verification process also call 
> > > > pg_waldump to
> > > > validate the WAL CRCs (shown upthread)?  That looked helpful and simple.
> > > 
> > > I don't love calls to external binaries, but I think the thing that
> > > really bothers me is that pg_waldump is practically bound to terminate
> > > with an error, because the last WAL segment will end with a partial
> > > record.
> > 
> > I don't think that's the case here. You should know the last required
> > record, which should allow to specify the precise end for pg_waldump. If
> > it errors out reading to that point, we'd be in trouble.
> 
> Exactly. All WAL generated during the backup should read fine with
> pg_waldump or there is a problem.

See the attached minimal prototype for what I am thinking of.

This would not correctly handle the case where the timeline changes
while taking a base backup. But I'm not sure that'd be all that serious
a limitation for now?

I'd personally not want to use a base backup that included a timeline
switch...

Greetings,

Andres Freund
diff --git c/src/bin/pg_basebackup/pg_basebackup.c i/src/bin/pg_basebackup/pg_basebackup.c
index c5d95958b29..b61492eba4c 100644
--- c/src/bin/pg_basebackup/pg_basebackup.c
+++ i/src/bin/pg_basebackup/pg_basebackup.c
@@ -2033,6 +2033,11 @@ BaseBackup(void)
 
 	if (verbose)
 		pg_log_info("base backup completed");
+
+	if (format == 'p')
+		pg_log_info("pg_waldump --just-parse -p \"%s\" -t %u -s %s -e %s",
+					basedir, starttli,
+					xlogstart, xlogend);
 }
 
 
diff --git c/src/bin/pg_waldump/pg_waldump.c i/src/bin/pg_waldump/pg_waldump.c
index 279acfa0440..63f4a9cba1f 100644
--- c/src/bin/pg_waldump/pg_waldump.c
+++ i/src/bin/pg_waldump/pg_waldump.c
@@ -40,6 +40,7 @@ typedef struct XLogDumpPrivate
 typedef struct XLogDumpConfig
 {
 	/* display options */
+	bool		just_parse;
 	bool		bkp_details;
 	int			stop_after_records;
 	int			already_displayed_records;
@@ -749,6 +750,7 @@ main(int argc, char **argv)
 	char	   *errormsg;
 
 	static struct option long_options[] = {
+		{"just-parse", no_argument, NULL, 'j'},
 		{"bkp-details", no_argument, NULL, 'b'},
 		{"end", required_argument, NULL, 'e'},
 		{"follow", no_argument, NULL, 'f'},
@@ -794,6 +796,7 @@ main(int argc, char **argv)
 	private.endptr = InvalidXLogRecPtr;
 	private.endptr_reached = false;
 
+	config.just_parse = false;
 	config.bkp_details = false;
 	config.stop_after_records = -1;
 	config.already_displayed_records = 0;
@@ -810,11 +813,14 @@ main(int argc, char **argv)
 		goto bad_argument;
 	}
 
-	while ((option = getopt_long(argc, argv, "be:fn:p:r:s:t:x:z",
+	while ((option = getopt_long(argc, argv, "be:fjn:p:r:s:t:x:z",
 								 long_options, &optindex)) != -1)
 	{
 		switch (option)
 		{
+			case 'j':
+				config.just_parse = true;
+				break;
 			case 'b':
 				config.bkp_details = true;
 				break;
@@ -1076,10 +1082,13 @@ main(int argc, char **argv)
 			continue;
 
 		/* process the record */
-		if (config.stats == true)
-			XLogDumpCountRecord(&config, &stats, xlogreader_state);
-		else
-			XLogDumpDisplayRecord(&config, xlogreader_state);
+		if (!config.just_parse)
+		{
+			if (config.stats == true)
+				XLogDumpCountRecord(&config, &stats, xlogreader_state);
+			else
+				XLogDumpDisplayRecord(&config, xlogreader_state);
+		}
 
 		/* check whether we printed enough */
 		config.already_displayed_records++;

Reply via email to