]> git.ipfire.org Git - thirdparty/postgresql.git/commitdiff
Add recovery/startup test with backup_label and missing checkpoint segment
authorMichael Paquier <michael@paquier.xyz>
Mon, 13 Jul 2026 00:19:20 +0000 (09:19 +0900)
committerMichael Paquier <michael@paquier.xyz>
Mon, 13 Jul 2026 00:19:20 +0000 (09:19 +0900)
This test is able to trigger the following failure at the beginning of
recovery, that was not covered yet:
FATAL:  could not locate required checkpoint record at %X/%X

Note that the backup used for the node created has its pg_wal/ removed,
which is why the segment expected is missing.

Extracted from a larger patch by the same author.

Author: Nitin Jadhav <nitinjadhavpostgres@gmail.com>
Discussion: https://postgr.es/m/CAMm1aWZ9Tv=Wrx52_2Ppw+6ULf_twRZuQm=ZWLA_a-kXWykHkQ@mail.gmail.com

src/test/recovery/t/042_low_level_backup.pl

index df4ae029fe645d9cc788bccbedb2ce76e671a748..7ed54e611eb71b63f43ae12692377f2cedf158a3 100644 (file)
@@ -68,6 +68,10 @@ $node_primary->poll_query_until('postgres',
 
 $node_primary->safe_psql('postgres', "checkpoint");
 
+# Save the segment holding the latest checkpoint record from pg_control.
+my $checkpoint_segment_name = $node_primary->safe_psql('postgres',
+       'SELECT pg_walfile_name(checkpoint_lsn) FROM pg_control_checkpoint()');
+
 # Copy pg_control last so it contains the new checkpoint.
 copy($node_primary->data_dir . '/global/pg_control',
        "$backup_dir/global/pg_control")
@@ -141,4 +145,24 @@ is($node_replica->safe_psql('postgres', $canary_query),
 ok($node_replica->log_contains('starting backup recovery with redo LSN'),
        'verify backup recovery performed with backup_label');
 
+# Recover with backup_label and the checkpoint segment removed.  Startup will
+# fail due to a missing checkpoint record.  Note that the backup had its
+# pg_wal/ wiped out previously.
+$node_replica = PostgreSQL::Test::Cluster->new('replica_missing_checkpoint');
+$node_replica->init_from_backup($node_primary, $backup_name);
+$node_replica->append_conf('postgresql.conf', "archive_mode = off");
+
+if (-e $node_replica->data_dir . "/pg_wal/$checkpoint_segment_name")
+{
+       unlink($node_replica->data_dir . "/pg_wal/$checkpoint_segment_name")
+         or BAIL_OUT("unable to unlink $checkpoint_segment_name");
+}
+
+is($node_replica->start(fail_ok => 1),
+       0, 'startup fails when checkpoint record WAL is missing');
+
+ok( $node_replica->log_contains(
+               'FATAL: .*could not locate required checkpoint record at'),
+       'ends with FATAL for missing required checkpoint record');
+
 done_testing();