Author: Noah Misch Commit: Noah Misch diff --git a/contrib/amcheck/Makefile b/contrib/amcheck/Makefile index b82f221..9a7f4f7 100644 --- a/contrib/amcheck/Makefile +++ b/contrib/amcheck/Makefile @@ -13,6 +13,7 @@ PGFILEDESC = "amcheck - function for verifying relation integrity" REGRESS = check check_btree check_heap TAP_TESTS = 1 +EXTRA_INSTALL=contrib/pg_walinspect ifdef USE_PGXS PG_CONFIG = pg_config diff --git a/contrib/amcheck/t/004_pitr.pl b/contrib/amcheck/t/004_pitr.pl new file mode 100644 index 0000000..ec6d87e --- /dev/null +++ b/contrib/amcheck/t/004_pitr.pl @@ -0,0 +1,65 @@ + +# Copyright (c) 2021-2023, PostgreSQL Global Development Group + +# Test integrity of intermediate states by PITR to those states +use strict; +use warnings; +use PostgreSQL::Test::Cluster; +use PostgreSQL::Test::Utils; +use Test::More; + +# origin node: generate WAL records of interest. +my $origin = PostgreSQL::Test::Cluster->new('origin'); +$origin->init(has_archiving => 1, allows_streaming => 1); +$origin->append_conf('postgresql.conf', 'autovacuum = off'); +$origin->start; +$origin->backup('my_backup'); +# Create a table with each of 6 PK values spanning 1/4 of a block. Delete the +# first four, so one index leaf is eligible for deletion. Make a replication +# slot just so pg_walinspect will always have access to later WAL. +my $setup = <safe_psql('postgres', $setup); +my $before_vacuum_lsn = + $origin->safe_psql('postgres', "SELECT pg_current_wal_lsn()"); +# VACUUM to delete the aforementioned leaf page. Find the LSN of that +# UNLINK_PAGE record. +my $exec = <safe_psql('postgres', $exec); +$origin->stop; + +# replica node: amcheck at notable points in the WAL stream +my $replica = PostgreSQL::Test::Cluster->new('replica'); +$replica->init_from_backup($origin, 'my_backup', has_restoring => 1); +$replica->append_conf('postgresql.conf', + "recovery_target_lsn = '$unlink_lsn'"); +$replica->append_conf('postgresql.conf', 'recovery_target_inclusive = off'); +$replica->append_conf('postgresql.conf', 'recovery_target_action = promote'); +$replica->start; +$replica->poll_query_until('postgres', "SELECT pg_is_in_recovery() = 'f';") + or die "Timed out while waiting for PITR promotion"; +# recovery done; run amcheck +is( $replica->psql( + 'postgres', "SELECT bt_index_parent_check('not_leftmost_pk', true)"), + 0); +is( $replica->psql( + 'postgres', "SELECT bt_index_check('not_leftmost_pk', true)"), + 0); + +done_testing();