diff --git a/src/bin/pg_controldata/pg_controldata.c b/src/bin/pg_controldata/pg_controldata.c index 5c77f40313b..30ad46912e1 100644 --- a/src/bin/pg_controldata/pg_controldata.c +++ b/src/bin/pg_controldata/pg_controldata.c @@ -167,7 +167,14 @@ main(int argc, char *argv[]) /* get a copy of the control file */ ControlFile = get_controlfile(DataDir, &crc_ok); - if (!crc_ok) + if (ControlFile->pg_control_version != PG_CONTROL_VERSION) + { + pg_log_warning("control file version (%u) does not match the version understood by this program (%u)", + ControlFile->pg_control_version, PG_CONTROL_VERSION); + pg_log_warning_detail("Either the control file has been created with a different version of PostgreSQL, " + "or it is corrupt. The results below are untrustworthy."); + } + else if (!crc_ok) { pg_log_warning("calculated CRC checksum does not match value stored in control file"); pg_log_warning_detail("Either the control file is corrupt, or it has a different layout than this program " diff --git a/src/bin/pg_controldata/t/001_pg_controldata.pl b/src/bin/pg_controldata/t/001_pg_controldata.pl index 4aea00d6d5a..6ace61f9314 100644 --- a/src/bin/pg_controldata/t/001_pg_controldata.pl +++ b/src/bin/pg_controldata/t/001_pg_controldata.pl @@ -21,16 +21,22 @@ command_like([ 'pg_controldata', $node->data_dir ], qr/checkpoint/, 'pg_controldata produces output'); -# check with a corrupted pg_control +# Check with a corrupted pg_control +# +# To corrupt it, overwrite most of it with zeros. We leave the +# beginning portion that contains the pg_control version number (first +# 16 bytes) unmodified because otherwise you get an error about the +# version number, instead of checksum mismatch. my $pg_control = $node->data_dir . '/global/pg_control'; my $size = -s $pg_control; -open my $fh, '>', $pg_control or BAIL_OUT($!); +open my $fh, '+<', $pg_control or BAIL_OUT($!); binmode $fh; -# fill file with zeros -print $fh pack("x[$size]"); +my ($overwrite_off, $overwrite_len) = (16, $size - 16); +seek $fh, $overwrite_off, 0 or BAIL_OUT($!); +print $fh pack("x[$overwrite_len]"); close $fh; command_checks_all(