diff options
Diffstat (limited to 'src/bin/pg_rewind/RewindTest.pm')
-rw-r--r-- | src/bin/pg_rewind/RewindTest.pm | 148 |
1 files changed, 94 insertions, 54 deletions
diff --git a/src/bin/pg_rewind/RewindTest.pm b/src/bin/pg_rewind/RewindTest.pm index 6ea2f871aab..5219ec967ae 100644 --- a/src/bin/pg_rewind/RewindTest.pm +++ b/src/bin/pg_rewind/RewindTest.pm @@ -67,8 +67,8 @@ our @EXPORT = qw( # for debugging purposes, my $testroot = tempdir; -our $test_master_datadir="$testroot/data_master"; -our $test_standby_datadir="$testroot/data_standby"; +our $test_master_datadir = "$testroot/data_master"; +our $test_standby_datadir = "$testroot/data_standby"; mkdir $testroot; @@ -76,14 +76,14 @@ mkdir $testroot; mkdir "regress_log"; # Define non-conflicting ports for both nodes. -my $port_master=$ENV{PGPORT}; -my $port_standby=$port_master + 1; +my $port_master = $ENV{PGPORT}; +my $port_standby = $port_master + 1; my $log_path; my $tempdir_short; -my $connstr_master="port=$port_master"; -my $connstr_standby="port=$port_standby"; +my $connstr_master = "port=$port_master"; +my $connstr_standby = "port=$port_standby"; $ENV{PGDATABASE} = "postgres"; @@ -109,19 +109,25 @@ sub check_query my ($stdout, $stderr); # we want just the output, no formatting - my $result = run ['psql', '-q', '-A', '-t', '--no-psqlrc', - '-d', $connstr_master, - '-c' , $query], - '>', \$stdout, '2>', \$stderr; + my $result = run [ + 'psql', '-q', '-A', '-t', '--no-psqlrc', '-d', + $connstr_master, '-c', $query ], + '>', \$stdout, '2>', \$stderr; + # We don't use ok() for the exit code and stderr, because we want this # check to be just a single test. - if (!$result) { - fail ("$test_name: psql exit code"); - } elsif ($stderr ne '') { + if (!$result) + { + fail("$test_name: psql exit code"); + } + elsif ($stderr ne '') + { diag $stderr; - fail ("$test_name: psql no stderr"); - } else { - is ($stdout, $expected_stdout, "$test_name: query result matches"); + fail("$test_name: psql no stderr"); + } + else + { + is($stdout, $expected_stdout, "$test_name: query result matches"); } } @@ -131,12 +137,12 @@ sub poll_query_until my ($query, $connstr) = @_; my $max_attempts = 30; - my $attempts = 0; + my $attempts = 0; my ($stdout, $stderr); while ($attempts < $max_attempts) { - my $cmd = ['psql', '-At', '-c', "$query", '-d', "$connstr" ]; + my $cmd = [ 'psql', '-At', '-c', "$query", '-d', "$connstr" ]; my $result = run $cmd, '>', \$stdout, '2>', \$stderr; chomp($stdout); @@ -158,7 +164,7 @@ sub poll_query_until sub append_to_file { - my($filename, $str) = @_; + my ($filename, $str) = @_; open my $fh, ">>", $filename or die "could not open file $filename"; print $fh $str; @@ -167,10 +173,10 @@ sub append_to_file sub init_rewind_test { - my $testname = shift; + my $testname = shift; my $test_mode = shift; - $log_path="regress_log/pg_rewind_log_${testname}_${test_mode}"; + $log_path = "regress_log/pg_rewind_log_${testname}_${test_mode}"; remove_tree $log_path; } @@ -184,7 +190,8 @@ sub setup_cluster standard_initdb($test_master_datadir); # Custom parameters for master's postgresql.conf - append_to_file("$test_master_datadir/postgresql.conf", qq( + append_to_file( + "$test_master_datadir/postgresql.conf", qq( wal_level = hot_standby max_wal_senders = 2 wal_keep_segments = 20 @@ -197,38 +204,47 @@ max_connections = 10 )); # Accept replication connections on master - append_to_file("$test_master_datadir/pg_hba.conf", qq( + append_to_file( + "$test_master_datadir/pg_hba.conf", qq( local replication all trust )); - system_or_bail("pg_ctl -w -D $test_master_datadir -o \"-k $tempdir_short --listen-addresses='' -p $port_master\" start >>$log_path 2>&1"); + system_or_bail( +"pg_ctl -w -D $test_master_datadir -o \"-k $tempdir_short --listen-addresses='' -p $port_master\" start >>$log_path 2>&1" + ); #### Now run the test-specific parts to initialize the master before setting # up standby - $ENV{PGHOST} = $tempdir_short; + $ENV{PGHOST} = $tempdir_short; } sub create_standby { + # Set up standby with necessary parameter remove_tree $test_standby_datadir; # Base backup is taken with xlog files included - system_or_bail("pg_basebackup -D $test_standby_datadir -p $port_master -x >>$log_path 2>&1"); - append_to_file("$test_standby_datadir/recovery.conf", qq( + system_or_bail( +"pg_basebackup -D $test_standby_datadir -p $port_master -x >>$log_path 2>&1"); + append_to_file( + "$test_standby_datadir/recovery.conf", qq( primary_conninfo='$connstr_master application_name=rewind_standby' standby_mode=on recovery_target_timeline='latest' )); # Start standby - system_or_bail("pg_ctl -w -D $test_standby_datadir -o \"-k $tempdir_short --listen-addresses='' -p $port_standby\" start >>$log_path 2>&1"); + system_or_bail( +"pg_ctl -w -D $test_standby_datadir -o \"-k $tempdir_short --listen-addresses='' -p $port_standby\" start >>$log_path 2>&1" + ); # Wait until the standby has caught up with the primary, by polling # pg_stat_replication. - my $caughtup_query = "SELECT pg_current_xlog_location() = replay_location FROM pg_stat_replication WHERE application_name = 'rewind_standby';"; + my $caughtup_query = +"SELECT pg_current_xlog_location() = replay_location FROM pg_stat_replication WHERE application_name = 'rewind_standby';"; poll_query_until($caughtup_query, $connstr_master) - or die "Timed out while waiting for standby to catch up"; + or die "Timed out while waiting for standby to catch up"; } sub promote_standby @@ -239,9 +255,10 @@ sub promote_standby # Now promote slave and insert some new data on master, this will put # the master out-of-sync with the standby. Wait until the standby is # out of recovery mode, and is ready to accept read-write connections. - system_or_bail("pg_ctl -w -D $test_standby_datadir promote >>$log_path 2>&1"); + system_or_bail( + "pg_ctl -w -D $test_standby_datadir promote >>$log_path 2>&1"); poll_query_until("SELECT NOT pg_is_in_recovery()", $connstr_standby) - or die "Timed out while waiting for promotion of standby"; + or die "Timed out while waiting for promotion of standby"; # Force a checkpoint after the promotion. pg_rewind looks at the control # file todetermine what timeline the server is on, and that isn't updated @@ -257,7 +274,8 @@ sub run_pg_rewind my $test_mode = shift; # Stop the master and be ready to perform the rewind - system_or_bail("pg_ctl -w -D $test_master_datadir stop -m fast >>$log_path 2>&1"); + system_or_bail( + "pg_ctl -w -D $test_master_datadir stop -m fast >>$log_path 2>&1"); # At this point, the rewind processing is ready to run. # We now have a very simple scenario with a few diverged WAL record. @@ -266,47 +284,67 @@ sub run_pg_rewind # Keep a temporary postgresql.conf for master node or it would be # overwritten during the rewind. - copy("$test_master_datadir/postgresql.conf", "$testroot/master-postgresql.conf.tmp"); + copy( + "$test_master_datadir/postgresql.conf", + "$testroot/master-postgresql.conf.tmp"); + # Now run pg_rewind if ($test_mode eq "local") { + # Do rewind using a local pgdata as source # Stop the master and be ready to perform the rewind - system_or_bail("pg_ctl -w -D $test_standby_datadir stop -m fast >>$log_path 2>&1"); - my $result = - run(['pg_rewind', - "--debug", - "--source-pgdata=$test_standby_datadir", - "--target-pgdata=$test_master_datadir"], - '>>', $log_path, '2>&1'); - ok ($result, 'pg_rewind local'); + system_or_bail( + "pg_ctl -w -D $test_standby_datadir stop -m fast >>$log_path 2>&1" + ); + my $result = run( + [ 'pg_rewind', + "--debug", + "--source-pgdata=$test_standby_datadir", + "--target-pgdata=$test_master_datadir" ], + '>>', + $log_path, + '2>&1'); + ok($result, 'pg_rewind local'); } elsif ($test_mode eq "remote") { + # Do rewind using a remote connection as source - my $result = - run(['pg_rewind', - "--source-server", "port=$port_standby dbname=postgres", - "--target-pgdata=$test_master_datadir"], - '>>', $log_path, '2>&1'); - ok ($result, 'pg_rewind remote'); - } else { + my $result = run( + [ 'pg_rewind', + "--source-server", + "port=$port_standby dbname=postgres", + "--target-pgdata=$test_master_datadir" ], + '>>', + $log_path, + '2>&1'); + ok($result, 'pg_rewind remote'); + } + else + { + # Cannot come here normally die("Incorrect test mode specified"); } # Now move back postgresql.conf with old settings - move("$testroot/master-postgresql.conf.tmp", "$test_master_datadir/postgresql.conf"); + move( + "$testroot/master-postgresql.conf.tmp", + "$test_master_datadir/postgresql.conf"); # Plug-in rewound node to the now-promoted standby node - append_to_file("$test_master_datadir/recovery.conf", qq( + append_to_file( + "$test_master_datadir/recovery.conf", qq( primary_conninfo='port=$port_standby' standby_mode=on recovery_target_timeline='latest' )); # Restart the master to check that rewind went correctly - system_or_bail("pg_ctl -w -D $test_master_datadir -o \"-k $tempdir_short --listen-addresses='' -p $port_master\" start >>$log_path 2>&1"); + system_or_bail( +"pg_ctl -w -D $test_master_datadir -o \"-k $tempdir_short --listen-addresses='' -p $port_master\" start >>$log_path 2>&1" + ); #### Now run the test-specific parts to check the result } @@ -316,11 +354,13 @@ sub clean_rewind_test { if ($test_master_datadir) { - system "pg_ctl -D $test_master_datadir -s -m immediate stop 2> /dev/null"; + system + "pg_ctl -D $test_master_datadir -s -m immediate stop 2> /dev/null"; } if ($test_standby_datadir) { - system "pg_ctl -D $test_standby_datadir -s -m immediate stop 2> /dev/null"; + system + "pg_ctl -D $test_standby_datadir -s -m immediate stop 2> /dev/null"; } } |