From 957177881692b772a1415316bcf0babcc7958e09 Mon Sep 17 00:00:00 2001 From: Ronan Dunklau Date: Tue, 26 Oct 2021 10:54:12 +0200 Subject: [PATCH v16 1/2] Add a test for pg_receivewal following timeline switch. pg_receivewal is able to follow a timeline switch, but this was not tested anywher. This test case verify that it works as expected both when resuming from a replication slot and from the archive directory, which have different methods of retrieving the timeline it left off. --- src/bin/pg_basebackup/t/020_pg_receivewal.pl | 58 +++++++++++++++++++- 1 file changed, 57 insertions(+), 1 deletion(-) diff --git a/src/bin/pg_basebackup/t/020_pg_receivewal.pl b/src/bin/pg_basebackup/t/020_pg_receivewal.pl index 092c9b6f25..e0422e2242 100644 --- a/src/bin/pg_basebackup/t/020_pg_receivewal.pl +++ b/src/bin/pg_basebackup/t/020_pg_receivewal.pl @@ -5,7 +5,7 @@ use strict; use warnings; use PostgreSQL::Test::Utils; use PostgreSQL::Test::Cluster; -use Test::More tests => 31; +use Test::More tests => 35; program_help_ok('pg_receivewal'); program_version_ok('pg_receivewal'); @@ -206,3 +206,59 @@ $primary->command_ok( "WAL streamed from the slot's restart_lsn"); ok(-e "$slot_dir/$walfile_streamed", "WAL from the slot's restart_lsn has been archived"); + +# Test a timeline switch. +# This test is split in two, using the same standby: one test check the +# resume-from-folder case, the other the resume-from-slot one. + +# Setup a standby for our tests +my $backup_name = "basebackup"; +$primary->backup($backup_name); +my $standby = PostgreSQL::Test::Cluster->new("standby"); +$standby->init_from_backup($primary, $backup_name, has_streaming => 1); +$standby->start; + +# Create a replication slot on this new standby +my $archive_slot = "archive_slot"; +$standby->psql('', + "CREATE_REPLICATION_SLOT $archive_slot PHYSICAL (RESERVE_WAL)", + replication => 1); +# Get a walfilename from before the promotion to make sure it is archived +# after promotion +my $walfile_before_promotion = $primary->safe_psql('postgres', + "SELECT pg_walfile_name(pg_current_wal_insert_lsn())"); +# Switch wal to make sure it is not a partial file but a complete segment. +$primary->psql('postgres', 'INSERT INTO test_table VALUES (1);'); +$primary->psql('postgres', 'SELECT pg_switch_wal();'); +$primary->wait_for_catchup($standby, 'replay', $primary->lsn('write')); + +# Everything is setup, promote the standby to trigger a timeline switch +$standby->psql( + 'postgres', + "SELECT pg_promote(wait_seconds => 300)"); + +# Force a wal switch to make sure at least one full WAL is archived on the new +# timeline, and fetch this walfilename. +my $walfile_after_promotion = $standby->safe_psql('postgres', + "SELECT pg_walfile_name(pg_current_wal_insert_lsn())"); +$standby->psql('postgres', 'INSERT INTO test_table VALUES (1);'); +$standby->psql('postgres', 'SELECT pg_switch_wal();'); +$nextlsn = + $standby->safe_psql('postgres', 'SELECT pg_current_wal_insert_lsn();'); +chomp($nextlsn); +$standby->psql('postgres', 'INSERT INTO test_table VALUES (1);'); + +# Now try to resume from the slot after the promotion. +my $timeline_dir = $primary->basedir . '/timeline_wal'; +mkdir($timeline_dir); + +$standby->command_ok( + [ 'pg_receivewal', '-D', $timeline_dir, '--verbose', '--endpos', $nextlsn, + '--slot', $archive_slot, '--no-sync', '-n'], + "Stream some wal after promoting, resuming from the slot's position"); +ok(-e "$timeline_dir/$walfile_before_promotion", + "WAL from the old timeline has been archived resuming from the slot"); +ok(-e "$timeline_dir/$walfile_after_promotion", + "WAL from the new timeline has been archived resuming from the slot"); +ok(-e "$timeline_dir/00000002.history", + "Timeline history file has been archived resuming from the slot"); -- 2.33.1