From: Michael Paquier Date: Mon, 13 Jul 2026 00:19:20 +0000 (+0900) Subject: Add recovery/startup test with backup_label and missing checkpoint segment X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=2b8598a2b045b172a8f726ba130e9eb764dc0688;p=thirdparty%2Fpostgresql.git Add recovery/startup test with backup_label and missing checkpoint segment 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 Discussion: https://postgr.es/m/CAMm1aWZ9Tv=Wrx52_2Ppw+6ULf_twRZuQm=ZWLA_a-kXWykHkQ@mail.gmail.com --- diff --git a/src/test/recovery/t/042_low_level_backup.pl b/src/test/recovery/t/042_low_level_backup.pl index df4ae029fe6..7ed54e611eb 100644 --- a/src/test/recovery/t/042_low_level_backup.pl +++ b/src/test/recovery/t/042_low_level_backup.pl @@ -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();