mirror of
https://github.com/postgres/postgres.git
synced 2025-04-25 21:42:33 +03:00
Refactor and fix TAP tests of pg_rewind
* Don't pass arguments to prove, since that's not supported on perl 5.8 which is the minimum version supported by the TAP tests. Refactor the test files themselves to run the tests twice, in both local and remote mode. * Use eq rather than == for string comparison. This thinko caused the remote versions of the tests to never run. * Add "use strict" and "use warnings", and fix warnings that that produced. * Increase the delay after standby promotion, to make the tests more robust. * In remote mode, the connection string to the promoted standby was incorrect, leading to connection errors. Patch by Michael Paquier, to address Peter Eisentraut's report.
This commit is contained in:
parent
b2a5545bd6
commit
53ba10770a
@ -47,6 +47,5 @@ clean distclean maintainer-clean:
|
|||||||
rm -f pg_rewind$(X) $(OBJS) xlogreader.c
|
rm -f pg_rewind$(X) $(OBJS) xlogreader.c
|
||||||
rm -rf tmp_check regress_log
|
rm -rf tmp_check regress_log
|
||||||
|
|
||||||
check: all
|
check:
|
||||||
$(prove_check) :: local
|
$(prove_check)
|
||||||
$(prove_check) :: remote
|
|
||||||
|
@ -29,6 +29,9 @@ package RewindTest;
|
|||||||
# master and standby servers. The data directories are also available
|
# master and standby servers. The data directories are also available
|
||||||
# in paths $test_master_datadir and $test_standby_datadir
|
# in paths $test_master_datadir and $test_standby_datadir
|
||||||
|
|
||||||
|
use strict;
|
||||||
|
use warnings;
|
||||||
|
|
||||||
use TestLib;
|
use TestLib;
|
||||||
use Test::More;
|
use Test::More;
|
||||||
|
|
||||||
@ -58,8 +61,8 @@ our @EXPORT = qw(
|
|||||||
|
|
||||||
# Adjust these paths for your environment
|
# Adjust these paths for your environment
|
||||||
my $testroot = "./tmp_check";
|
my $testroot = "./tmp_check";
|
||||||
$test_master_datadir="$testroot/data_master";
|
our $test_master_datadir="$testroot/data_master";
|
||||||
$test_standby_datadir="$testroot/data_standby";
|
our $test_standby_datadir="$testroot/data_standby";
|
||||||
|
|
||||||
mkdir $testroot;
|
mkdir $testroot;
|
||||||
|
|
||||||
@ -73,8 +76,8 @@ my $port_standby=$port_master + 1;
|
|||||||
my $log_path;
|
my $log_path;
|
||||||
my $tempdir_short;
|
my $tempdir_short;
|
||||||
|
|
||||||
$connstr_master="port=$port_master";
|
my $connstr_master="port=$port_master";
|
||||||
$connstr_standby="port=$port_standby";
|
my $connstr_standby="port=$port_standby";
|
||||||
|
|
||||||
$ENV{PGDATABASE} = "postgres";
|
$ENV{PGDATABASE} = "postgres";
|
||||||
|
|
||||||
@ -127,7 +130,8 @@ sub append_to_file
|
|||||||
|
|
||||||
sub init_rewind_test
|
sub init_rewind_test
|
||||||
{
|
{
|
||||||
($testname, $test_mode) = @_;
|
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}";
|
||||||
|
|
||||||
@ -195,11 +199,13 @@ sub promote_standby
|
|||||||
# Now promote slave and insert some new data on master, this will put
|
# Now promote slave and insert some new data on master, this will put
|
||||||
# the master out-of-sync with the standby.
|
# the master out-of-sync with the standby.
|
||||||
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");
|
||||||
sleep 1;
|
sleep 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
sub run_pg_rewind
|
sub run_pg_rewind
|
||||||
{
|
{
|
||||||
|
my $test_mode = shift;
|
||||||
|
|
||||||
# Stop the master and be ready to perform the rewind
|
# 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");
|
||||||
|
|
||||||
@ -212,7 +218,7 @@ sub run_pg_rewind
|
|||||||
# overwritten during the rewind.
|
# 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
|
# Now run pg_rewind
|
||||||
if ($test_mode == "local")
|
if ($test_mode eq "local")
|
||||||
{
|
{
|
||||||
# Do rewind using a local pgdata as source
|
# Do rewind using a local pgdata as source
|
||||||
# Stop the master and be ready to perform the rewind
|
# Stop the master and be ready to perform the rewind
|
||||||
@ -225,12 +231,12 @@ sub run_pg_rewind
|
|||||||
'>>', $log_path, '2>&1');
|
'>>', $log_path, '2>&1');
|
||||||
ok ($result, 'pg_rewind local');
|
ok ($result, 'pg_rewind local');
|
||||||
}
|
}
|
||||||
elsif ($test_mode == "remote")
|
elsif ($test_mode eq "remote")
|
||||||
{
|
{
|
||||||
# Do rewind using a remote connection as source
|
# Do rewind using a remote connection as source
|
||||||
my $result =
|
my $result =
|
||||||
run(['./pg_rewind',
|
run(['./pg_rewind',
|
||||||
"--source-server=\"port=$port_standby dbname=postgres\"",
|
"--source-server", "port=$port_standby dbname=postgres",
|
||||||
"--target-pgdata=$test_master_datadir"],
|
"--target-pgdata=$test_master_datadir"],
|
||||||
'>>', $log_path, '2>&1');
|
'>>', $log_path, '2>&1');
|
||||||
ok ($result, 'pg_rewind remote');
|
ok ($result, 'pg_rewind remote');
|
||||||
|
@ -1,80 +1,87 @@
|
|||||||
use strict;
|
use strict;
|
||||||
use warnings;
|
use warnings;
|
||||||
use TestLib;
|
use TestLib;
|
||||||
use Test::More tests => 4;
|
use Test::More tests => 8;
|
||||||
|
|
||||||
use RewindTest;
|
use RewindTest;
|
||||||
|
|
||||||
my $testmode = shift;
|
sub run_test
|
||||||
|
{
|
||||||
|
my $test_mode = shift;
|
||||||
|
|
||||||
RewindTest::init_rewind_test('basic', $testmode);
|
RewindTest::init_rewind_test('basic', $test_mode);
|
||||||
RewindTest::setup_cluster();
|
RewindTest::setup_cluster();
|
||||||
|
|
||||||
# Create a test table and insert a row in master.
|
# Create a test table and insert a row in master.
|
||||||
master_psql("CREATE TABLE tbl1 (d text)");
|
master_psql("CREATE TABLE tbl1 (d text)");
|
||||||
master_psql("INSERT INTO tbl1 VALUES ('in master')");
|
master_psql("INSERT INTO tbl1 VALUES ('in master')");
|
||||||
|
|
||||||
# This test table will be used to test truncation, i.e. the table
|
# This test table will be used to test truncation, i.e. the table
|
||||||
# is extended in the old master after promotion
|
# is extended in the old master after promotion
|
||||||
master_psql("CREATE TABLE trunc_tbl (d text)");
|
master_psql("CREATE TABLE trunc_tbl (d text)");
|
||||||
master_psql("INSERT INTO trunc_tbl VALUES ('in master')");
|
master_psql("INSERT INTO trunc_tbl VALUES ('in master')");
|
||||||
|
|
||||||
# This test table will be used to test the "copy-tail" case, i.e. the
|
# This test table will be used to test the "copy-tail" case, i.e. the
|
||||||
# table is truncated in the old master after promotion
|
# table is truncated in the old master after promotion
|
||||||
master_psql("CREATE TABLE tail_tbl (id integer, d text)");
|
master_psql("CREATE TABLE tail_tbl (id integer, d text)");
|
||||||
master_psql("INSERT INTO tail_tbl VALUES (0, 'in master')");
|
master_psql("INSERT INTO tail_tbl VALUES (0, 'in master')");
|
||||||
|
|
||||||
|
master_psql("CHECKPOINT");
|
||||||
|
|
||||||
master_psql("CHECKPOINT");
|
RewindTest::create_standby();
|
||||||
|
|
||||||
RewindTest::create_standby();
|
# Insert additional data on master that will be replicated to standby
|
||||||
|
master_psql("INSERT INTO tbl1 values ('in master, before promotion')");
|
||||||
|
master_psql("INSERT INTO trunc_tbl values ('in master, before promotion')");
|
||||||
|
master_psql("INSERT INTO tail_tbl SELECT g, 'in master, before promotion: ' || g FROM generate_series(1, 10000) g");
|
||||||
|
|
||||||
# Insert additional data on master that will be replicated to standby
|
master_psql('CHECKPOINT');
|
||||||
master_psql("INSERT INTO tbl1 values ('in master, before promotion')");
|
|
||||||
master_psql("INSERT INTO trunc_tbl values ('in master, before promotion')");
|
|
||||||
master_psql("INSERT INTO tail_tbl SELECT g, 'in master, before promotion: ' || g FROM generate_series(1, 10000) g");
|
|
||||||
|
|
||||||
master_psql('CHECKPOINT');
|
RewindTest::promote_standby();
|
||||||
|
|
||||||
RewindTest::promote_standby();
|
# Insert a row in the old master. This causes the master and standby
|
||||||
|
# to have "diverged", it's no longer possible to just apply the
|
||||||
|
# standy's logs over master directory - you need to rewind.
|
||||||
|
master_psql("INSERT INTO tbl1 VALUES ('in master, after promotion')");
|
||||||
|
|
||||||
# Insert a row in the old master. This causes the master and standby
|
# Also insert a new row in the standby, which won't be present in the
|
||||||
# to have "diverged", it's no longer possible to just apply the
|
# old master.
|
||||||
# standy's logs over master directory - you need to rewind.
|
standby_psql("INSERT INTO tbl1 VALUES ('in standby, after promotion')");
|
||||||
master_psql("INSERT INTO tbl1 VALUES ('in master, after promotion')");
|
|
||||||
|
|
||||||
# Also insert a new row in the standby, which won't be present in the
|
# Insert enough rows to trunc_tbl to extend the file. pg_rewind should
|
||||||
# old master.
|
# truncate it back to the old size.
|
||||||
standby_psql("INSERT INTO tbl1 VALUES ('in standby, after promotion')");
|
master_psql("INSERT INTO trunc_tbl SELECT 'in master, after promotion: ' || g FROM generate_series(1, 10000) g");
|
||||||
|
|
||||||
# Insert enough rows to trunc_tbl to extend the file. pg_rewind should
|
# Truncate tail_tbl. pg_rewind should copy back the truncated part
|
||||||
# truncate it back to the old size.
|
# (We cannot use an actual TRUNCATE command here, as that creates a
|
||||||
master_psql("INSERT INTO trunc_tbl SELECT 'in master, after promotion: ' || g FROM generate_series(1, 10000) g");
|
# whole new relfilenode)
|
||||||
|
master_psql("DELETE FROM tail_tbl WHERE id > 10");
|
||||||
|
master_psql("VACUUM tail_tbl");
|
||||||
|
|
||||||
# Truncate tail_tbl. pg_rewind should copy back the truncated part
|
RewindTest::run_pg_rewind($test_mode);
|
||||||
# (We cannot use an actual TRUNCATE command here, as that creates a
|
|
||||||
# whole new relfilenode)
|
|
||||||
master_psql("DELETE FROM tail_tbl WHERE id > 10");
|
|
||||||
master_psql("VACUUM tail_tbl");
|
|
||||||
|
|
||||||
RewindTest::run_pg_rewind();
|
check_query('SELECT * FROM tbl1',
|
||||||
|
qq(in master
|
||||||
check_query('SELECT * FROM tbl1',
|
|
||||||
qq(in master
|
|
||||||
in master, before promotion
|
in master, before promotion
|
||||||
in standby, after promotion
|
in standby, after promotion
|
||||||
),
|
),
|
||||||
'table content');
|
'table content');
|
||||||
|
|
||||||
check_query('SELECT * FROM trunc_tbl',
|
check_query('SELECT * FROM trunc_tbl',
|
||||||
qq(in master
|
qq(in master
|
||||||
in master, before promotion
|
in master, before promotion
|
||||||
),
|
),
|
||||||
'truncation');
|
'truncation');
|
||||||
|
|
||||||
check_query('SELECT count(*) FROM tail_tbl',
|
check_query('SELECT count(*) FROM tail_tbl',
|
||||||
qq(10001
|
qq(10001
|
||||||
),
|
),
|
||||||
'tail-copy');
|
'tail-copy');
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
# Run the test in both modes
|
||||||
|
run_test('local');
|
||||||
|
run_test('remote');
|
||||||
|
|
||||||
exit(0);
|
exit(0);
|
||||||
|
@ -1,41 +1,49 @@
|
|||||||
use strict;
|
use strict;
|
||||||
use warnings;
|
use warnings;
|
||||||
use TestLib;
|
use TestLib;
|
||||||
use Test::More tests => 2;
|
use Test::More tests => 4;
|
||||||
|
|
||||||
use RewindTest;
|
use RewindTest;
|
||||||
|
|
||||||
my $testmode = shift;
|
sub run_test
|
||||||
|
{
|
||||||
|
my $test_mode = shift;
|
||||||
|
|
||||||
RewindTest::init_rewind_test('databases', $testmode);
|
RewindTest::init_rewind_test('databases', $test_mode);
|
||||||
RewindTest::setup_cluster();
|
RewindTest::setup_cluster();
|
||||||
|
|
||||||
# Create a database in master.
|
# Create a database in master.
|
||||||
master_psql('CREATE DATABASE inmaster');
|
master_psql('CREATE DATABASE inmaster');
|
||||||
|
|
||||||
RewindTest::create_standby();
|
RewindTest::create_standby();
|
||||||
|
|
||||||
# Create another database, the creation is replicated to the standby
|
# Create another database, the creation is replicated to the standby
|
||||||
master_psql('CREATE DATABASE beforepromotion');
|
master_psql('CREATE DATABASE beforepromotion');
|
||||||
|
|
||||||
RewindTest::promote_standby();
|
RewindTest::promote_standby();
|
||||||
|
|
||||||
# Create databases in the old master and the new promoted standby.
|
# Create databases in the old master and the new promoted standby.
|
||||||
master_psql('CREATE DATABASE master_afterpromotion');
|
master_psql('CREATE DATABASE master_afterpromotion');
|
||||||
standby_psql('CREATE DATABASE standby_afterpromotion');
|
standby_psql('CREATE DATABASE standby_afterpromotion');
|
||||||
# The clusters are now diverged.
|
# The clusters are now diverged.
|
||||||
|
|
||||||
RewindTest::run_pg_rewind();
|
RewindTest::run_pg_rewind($test_mode);
|
||||||
|
|
||||||
# Check that the correct databases are present after pg_rewind.
|
# Check that the correct databases are present after pg_rewind.
|
||||||
check_query('SELECT datname FROM pg_database',
|
check_query('SELECT datname FROM pg_database',
|
||||||
qq(template1
|
qq(template1
|
||||||
template0
|
template0
|
||||||
postgres
|
postgres
|
||||||
inmaster
|
inmaster
|
||||||
beforepromotion
|
beforepromotion
|
||||||
standby_afterpromotion
|
standby_afterpromotion
|
||||||
),
|
),
|
||||||
'database names');
|
'database names');
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
# Run the test in both modes.
|
||||||
|
run_test('local');
|
||||||
|
run_test('remote');
|
||||||
|
|
||||||
exit(0);
|
exit(0);
|
||||||
|
@ -3,59 +3,69 @@
|
|||||||
use strict;
|
use strict;
|
||||||
use warnings;
|
use warnings;
|
||||||
use TestLib;
|
use TestLib;
|
||||||
use Test::More tests => 2;
|
use Test::More tests => 4;
|
||||||
|
|
||||||
use File::Find;
|
use File::Find;
|
||||||
|
|
||||||
use RewindTest;
|
use RewindTest;
|
||||||
|
|
||||||
my $testmode = shift;
|
|
||||||
|
|
||||||
RewindTest::init_rewind_test('extrafiles', $testmode);
|
sub run_test
|
||||||
RewindTest::setup_cluster();
|
{
|
||||||
|
my $test_mode = shift;
|
||||||
|
|
||||||
# Create a subdir and files that will be present in both
|
RewindTest::init_rewind_test('extrafiles', $test_mode);
|
||||||
mkdir "$test_master_datadir/tst_both_dir";
|
RewindTest::setup_cluster();
|
||||||
append_to_file "$test_master_datadir/tst_both_dir/both_file1", "in both1";
|
|
||||||
append_to_file "$test_master_datadir/tst_both_dir/both_file2", "in both2";
|
|
||||||
mkdir "$test_master_datadir/tst_both_dir/both_subdir/";
|
|
||||||
append_to_file "$test_master_datadir/tst_both_dir/both_subdir/both_file3", "in both3";
|
|
||||||
|
|
||||||
RewindTest::create_standby();
|
my $test_master_datadir = $RewindTest::test_master_datadir;
|
||||||
|
|
||||||
# Create different subdirs and files in master and standby
|
# Create a subdir and files that will be present in both
|
||||||
|
mkdir "$test_master_datadir/tst_both_dir";
|
||||||
|
append_to_file "$test_master_datadir/tst_both_dir/both_file1", "in both1";
|
||||||
|
append_to_file "$test_master_datadir/tst_both_dir/both_file2", "in both2";
|
||||||
|
mkdir "$test_master_datadir/tst_both_dir/both_subdir/";
|
||||||
|
append_to_file "$test_master_datadir/tst_both_dir/both_subdir/both_file3", "in both3";
|
||||||
|
|
||||||
mkdir "$test_standby_datadir/tst_standby_dir";
|
RewindTest::create_standby();
|
||||||
append_to_file "$test_standby_datadir/tst_standby_dir/standby_file1", "in standby1";
|
|
||||||
append_to_file "$test_standby_datadir/tst_standby_dir/standby_file2", "in standby2";
|
|
||||||
mkdir "$test_standby_datadir/tst_standby_dir/standby_subdir/";
|
|
||||||
append_to_file "$test_standby_datadir/tst_standby_dir/standby_subdir/standby_file3", "in standby3";
|
|
||||||
|
|
||||||
mkdir "$test_master_datadir/tst_master_dir";
|
# Create different subdirs and files in master and standby
|
||||||
append_to_file "$test_master_datadir/tst_master_dir/master_file1", "in master1";
|
|
||||||
append_to_file "$test_master_datadir/tst_master_dir/master_file2", "in master2";
|
|
||||||
mkdir "$test_master_datadir/tst_master_dir/master_subdir/";
|
|
||||||
append_to_file "$test_master_datadir/tst_master_dir/master_subdir/master_file3", "in master3";
|
|
||||||
|
|
||||||
RewindTest::promote_standby();
|
mkdir "$test_standby_datadir/tst_standby_dir";
|
||||||
RewindTest::run_pg_rewind();
|
append_to_file "$test_standby_datadir/tst_standby_dir/standby_file1", "in standby1";
|
||||||
|
append_to_file "$test_standby_datadir/tst_standby_dir/standby_file2", "in standby2";
|
||||||
|
mkdir "$test_standby_datadir/tst_standby_dir/standby_subdir/";
|
||||||
|
append_to_file "$test_standby_datadir/tst_standby_dir/standby_subdir/standby_file3", "in standby3";
|
||||||
|
|
||||||
# List files in the data directory after rewind.
|
mkdir "$test_master_datadir/tst_master_dir";
|
||||||
my @paths;
|
append_to_file "$test_master_datadir/tst_master_dir/master_file1", "in master1";
|
||||||
find(sub {push @paths, $File::Find::name if $File::Find::name =~ m/.*tst_.*/},
|
append_to_file "$test_master_datadir/tst_master_dir/master_file2", "in master2";
|
||||||
$test_master_datadir);
|
mkdir "$test_master_datadir/tst_master_dir/master_subdir/";
|
||||||
@paths = sort @paths;
|
append_to_file "$test_master_datadir/tst_master_dir/master_subdir/master_file3", "in master3";
|
||||||
is_deeply(\@paths,
|
|
||||||
["$test_master_datadir/tst_both_dir",
|
RewindTest::promote_standby();
|
||||||
"$test_master_datadir/tst_both_dir/both_file1",
|
RewindTest::run_pg_rewind($test_mode);
|
||||||
"$test_master_datadir/tst_both_dir/both_file2",
|
|
||||||
"$test_master_datadir/tst_both_dir/both_subdir",
|
# List files in the data directory after rewind.
|
||||||
"$test_master_datadir/tst_both_dir/both_subdir/both_file3",
|
my @paths;
|
||||||
"$test_master_datadir/tst_standby_dir",
|
find(sub {push @paths, $File::Find::name if $File::Find::name =~ m/.*tst_.*/},
|
||||||
"$test_master_datadir/tst_standby_dir/standby_file1",
|
$test_master_datadir);
|
||||||
"$test_master_datadir/tst_standby_dir/standby_file2",
|
@paths = sort @paths;
|
||||||
"$test_master_datadir/tst_standby_dir/standby_subdir",
|
is_deeply(\@paths,
|
||||||
"$test_master_datadir/tst_standby_dir/standby_subdir/standby_file3"],
|
["$test_master_datadir/tst_both_dir",
|
||||||
"file lists match");
|
"$test_master_datadir/tst_both_dir/both_file1",
|
||||||
|
"$test_master_datadir/tst_both_dir/both_file2",
|
||||||
|
"$test_master_datadir/tst_both_dir/both_subdir",
|
||||||
|
"$test_master_datadir/tst_both_dir/both_subdir/both_file3",
|
||||||
|
"$test_master_datadir/tst_standby_dir",
|
||||||
|
"$test_master_datadir/tst_standby_dir/standby_file1",
|
||||||
|
"$test_master_datadir/tst_standby_dir/standby_file2",
|
||||||
|
"$test_master_datadir/tst_standby_dir/standby_subdir",
|
||||||
|
"$test_master_datadir/tst_standby_dir/standby_subdir/standby_file3"],
|
||||||
|
"file lists match");
|
||||||
|
}
|
||||||
|
|
||||||
|
# Run the test in both modes.
|
||||||
|
run_test('local');
|
||||||
|
run_test('remote');
|
||||||
|
|
||||||
exit(0);
|
exit(0);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user