From 43172d6e025af48a7ea31a8700d25455b20453c5 Mon Sep 17 00:00:00 2001 From: Shaoqi Bai Date: Fri, 8 Mar 2019 18:04:20 +0800 Subject: [PATCH] Add tablespace tap test for pg_rewind --- src/bin/pg_rewind/t/006_tablespace.pl | 83 +++++++++++++++++++++++++++ src/bin/pg_rewind/t/RewindTest.pm | 26 +++++++++ src/test/perl/PostgresNode.pm | 26 +++++++++ src/test/perl/RecursiveCopy.pm | 18 +++++- 4 files changed, 150 insertions(+), 3 deletions(-) create mode 100644 src/bin/pg_rewind/t/006_tablespace.pl diff --git a/src/bin/pg_rewind/t/006_tablespace.pl b/src/bin/pg_rewind/t/006_tablespace.pl new file mode 100644 index 0000000000..19b3403c90 --- /dev/null +++ b/src/bin/pg_rewind/t/006_tablespace.pl @@ -0,0 +1,83 @@ +use strict; +use warnings; +use File::Path qw(rmtree); +use TestLib; +use Test::More tests => 6; + +use FindBin; +use lib $FindBin::RealBin; + +use RewindTest; + +my $tempdir = TestLib::tempdir; + +sub run_test +{ + my $test_mode = shift; + + RewindTest::setup_cluster($test_mode, ['-g']); + RewindTest::start_master(); + + rmtree("$tempdir/inmaster"); + rmtree("$tempdir/instandby"); + rmtree("$tempdir/master_beforepromotion"); + rmtree("$tempdir/master_afterpromotion"); + rmtree("$tempdir/standby_afterpromotion"); + + mkdir "$tempdir/inmaster"; + mkdir "$tempdir/instandby"; + + # Create a tablespace in master. + master_psql("CREATE TABLESPACE inmaster LOCATION '$tempdir/inmaster'"); + + RewindTest::create_standby_tbl_mapping($test_mode, "$tempdir/inmaster", "$tempdir/instandby"); + + mkdir "$tempdir/master_beforepromotion"; + + # Create a tablespace, it has to be droped before doing pg_rewind, or else pg_rewind will fail + master_psql("CREATE TABLESPACE master_beforepromotion LOCATION '$tempdir/master_beforepromotion'"); + + RewindTest::promote_standby(); + + mkdir "$tempdir/master_afterpromotion"; + mkdir "$tempdir/standby_afterpromotion"; + + # Create tablespaces in the old master and the new promoted standby. + master_psql("CREATE TABLESPACE master_afterpromotion LOCATION '$tempdir/master_afterpromotion'"); + standby_psql("CREATE TABLESPACE standby_afterpromotion LOCATION '$tempdir/standby_afterpromotion'"); + # Drop tablespace in the new promoted standby, because pg_rewind can not handle this case. + standby_psql("DROP TABLESPACE standby_afterpromotion"); + + # The clusters are now diverged. + + RewindTest::run_pg_rewind($test_mode); + + # Check that the correct databases are present after pg_rewind. + check_query( + 'SELECT spcname FROM pg_tablespace ORDER BY spcname', + qq(inmaster +master_beforepromotion +pg_default +pg_global +), + 'tablespace names'); + + # Permissions on PGDATA should have group permissions + SKIP: + { + skip "unix-style permissions not supported on Windows", 1 + if ($windows_os); + + ok(check_mode_recursive($node_master->data_dir(), 0750, 0640), + 'check PGDATA permissions'); + } + + RewindTest::clean_rewind_test(); + return; +} + +# Run the test in both modes. +run_test('local'); +run_test('remote'); + +exit(0); diff --git a/src/bin/pg_rewind/t/RewindTest.pm b/src/bin/pg_rewind/t/RewindTest.pm index 85cae7e47b..81bf4d0e47 100644 --- a/src/bin/pg_rewind/t/RewindTest.pm +++ b/src/bin/pg_rewind/t/RewindTest.pm @@ -174,6 +174,32 @@ primary_conninfo='$connstr_master application_name=rewind_standby' return; } +sub create_standby_tbl_mapping +{ + my $extra_name = shift; + + $node_standby = + get_new_node('standby' . ($extra_name ? "_${extra_name}" : '')); + my ($olddir, $newdir) = @_; + $node_master->backup_tbl_mapping('my_backup', $olddir, $newdir); + $node_standby->init_from_backup($node_master, 'my_backup'); + my $connstr_master = $node_master->connstr(); + $node_standby->append_conf( + "postgresql.conf", qq( +primary_conninfo='$connstr_master application_name=rewind_standby' +)); + + $node_standby->set_standby_mode(); + + # Start standby + $node_standby->start; + + # The standby may have WAL to apply before it matches the primary. That + # is fine, because no test examines the standby before promotion. + + return; +} + sub promote_standby { #### Now run the test-specific parts to run after standby has been started diff --git a/src/test/perl/PostgresNode.pm b/src/test/perl/PostgresNode.pm index 0634aefd20..8d2f0c044d 100644 --- a/src/test/perl/PostgresNode.pm +++ b/src/test/perl/PostgresNode.pm @@ -546,6 +546,32 @@ sub backup return; } +=item $node->backup_tblspc_mapping(backup_name, olddir, newdir) + +Create a hot backup with B in subdirectory B of +B<< $node->backup_dir >>, with configuration --tablespace-mapping=B=B +, including the WAL. WAL files +fetched at the end of the backup, not streamed. + +You'll have to configure a suitable B on the +target server since it isn't done by default. + +=cut + +sub backup_tbl_mapping +{ + my ($self, $backup_name, $olddir, $newdir) = @_; + my $backup_path = $self->backup_dir . '/' . $backup_name; + my $port = $self->port; + my $name = $self->name; + + print "# Taking pg_basebackup $backup_name from node \"$name\"\n"; + TestLib::system_or_bail('pg_basebackup', '-D', $backup_path, '-p', $port, + '-T', "$olddir=$newdir", '--no-sync'); + print "# Backup finished\n"; + return; +} + =item $node->backup_fs_hot(backup_name) Create a backup with a filesystem level copy in subdirectory B of diff --git a/src/test/perl/RecursiveCopy.pm b/src/test/perl/RecursiveCopy.pm index baf5d0ac63..1840de8c8e 100644 --- a/src/test/perl/RecursiveCopy.pm +++ b/src/test/perl/RecursiveCopy.pm @@ -99,7 +99,7 @@ sub _copypath_recurse # Check for symlink -- needed only on source dir # (note: this will fall through quietly if file is already gone) - croak "Cannot operate on symlink \"$srcpath\"" if -l $srcpath; + # croak "Cannot operate on symlink \"$srcpath\"" if -l $srcpath; # Abort if destination path already exists. Should we allow directories # to exist already? @@ -107,7 +107,7 @@ sub _copypath_recurse # If this source path is a file, simply copy it to destination with the # same name and we're done. - if (-f $srcpath) + if (-f $srcpath && !(-l $srcpath)) { my $fh; unless (open($fh, '<', $srcpath)) @@ -122,7 +122,7 @@ sub _copypath_recurse } # If it's a directory, create it on dest and recurse into it. - if (-d $srcpath) + if (-d $srcpath && !(-l $srcpath)) { my $directory; unless (opendir($directory, $srcpath)) @@ -145,6 +145,18 @@ sub _copypath_recurse return 1; } + if (-l $srcpath) + { + my $old_link = $srcpath; + my $new_link = $destpath; + + my $dst = readlink($old_link); + my @stat = lstat($old_link); + + symlink $dst, $new_link; + return 1; + } + # If it disappeared from sight, that's OK. return 1 if !-e $srcpath; -- 2.19.1