diff options
Diffstat (limited to 'src/test/recovery/t/004_timeline_switch.pl')
-rw-r--r-- | src/test/recovery/t/004_timeline_switch.pl | 110 |
1 files changed, 110 insertions, 0 deletions
diff --git a/src/test/recovery/t/004_timeline_switch.pl b/src/test/recovery/t/004_timeline_switch.pl new file mode 100644 index 0000000..3203d93 --- /dev/null +++ b/src/test/recovery/t/004_timeline_switch.pl @@ -0,0 +1,110 @@ + +# Copyright (c) 2021-2022, PostgreSQL Global Development Group + +# Test for timeline switch +use strict; +use warnings; +use File::Path qw(rmtree); +use PostgreSQL::Test::Cluster; +use PostgreSQL::Test::Utils; +use Test::More; + +$ENV{PGDATABASE} = 'postgres'; + +# Ensure that a cascading standby is able to follow a newly-promoted standby +# on a new timeline. + +# Initialize primary node +my $node_primary = PostgreSQL::Test::Cluster->new('primary'); +$node_primary->init(allows_streaming => 1); +$node_primary->start; + +# Take backup +my $backup_name = 'my_backup'; +$node_primary->backup($backup_name); + +# Create two standbys linking to it +my $node_standby_1 = PostgreSQL::Test::Cluster->new('standby_1'); +$node_standby_1->init_from_backup($node_primary, $backup_name, + has_streaming => 1); +$node_standby_1->start; +my $node_standby_2 = PostgreSQL::Test::Cluster->new('standby_2'); +$node_standby_2->init_from_backup($node_primary, $backup_name, + has_streaming => 1); +$node_standby_2->start; + +# Create some content on primary +$node_primary->safe_psql('postgres', + "CREATE TABLE tab_int AS SELECT generate_series(1,1000) AS a"); + +# Wait until standby has replayed enough data on standby 1 +$node_primary->wait_for_catchup($node_standby_1); + +# Stop and remove primary +$node_primary->teardown_node; + +# promote standby 1 using "pg_promote", switching it to a new timeline +my $psql_out = ''; +$node_standby_1->psql( + 'postgres', + "SELECT pg_promote(wait_seconds => 300)", + stdout => \$psql_out); +is($psql_out, 't', "promotion of standby with pg_promote"); + +# Switch standby 2 to replay from standby 1 +my $connstr_1 = $node_standby_1->connstr; +$node_standby_2->append_conf( + 'postgresql.conf', qq( +primary_conninfo='$connstr_1' +)); +$node_standby_2->restart; + +# Insert some data in standby 1 and check its presence in standby 2 +# to ensure that the timeline switch has been done. +$node_standby_1->safe_psql('postgres', + "INSERT INTO tab_int VALUES (generate_series(1001,2000))"); +$node_standby_1->wait_for_catchup($node_standby_2); + +my $result = + $node_standby_2->safe_psql('postgres', "SELECT count(*) FROM tab_int"); +is($result, qq(2000), 'check content of standby 2'); + + +# Ensure that a standby is able to follow a primary on a newer timeline +# when WAL archiving is enabled. + +# Initialize primary node +my $node_primary_2 = PostgreSQL::Test::Cluster->new('primary_2'); +$node_primary_2->init(allows_streaming => 1, has_archiving => 1); +$node_primary_2->append_conf( + 'postgresql.conf', qq( +wal_keep_size = 512MB +)); +$node_primary_2->start; + +# Take backup +$node_primary_2->backup($backup_name); + +# Create standby node +my $node_standby_3 = PostgreSQL::Test::Cluster->new('standby_3'); +$node_standby_3->init_from_backup($node_primary_2, $backup_name, + has_streaming => 1); + +# Restart primary node in standby mode and promote it, switching it +# to a new timeline. +$node_primary_2->set_standby_mode; +$node_primary_2->restart; +$node_primary_2->promote; + +# Start standby node, create some content on primary and check its presence +# in standby, to ensure that the timeline switch has been done. +$node_standby_3->start; +$node_primary_2->safe_psql('postgres', + "CREATE TABLE tab_int AS SELECT 1 AS a"); +$node_primary_2->wait_for_catchup($node_standby_3); + +my $result_2 = + $node_standby_3->safe_psql('postgres', "SELECT count(*) FROM tab_int"); +is($result_2, qq(1), 'check content of standby 3'); + +done_testing(); |