From: Kyotaro Horiguchi Date: Mon, 22 Apr 2019 20:58:53 +0900 Subject: [PATCH 2/5] Allow TAP test to excecise tablespace. To perform tablespace related checks, this patch lets PostgresNode::backup have a new parameter "tablespace_mapping", and make init_from_backup handle capable to handle a backup created using tablespace_mapping. --- src/test/perl/PostgresNode.pm | 45 +++++++++++++++++++++++++++++++++++++----- src/test/perl/RecursiveCopy.pm | 38 +++++++++++++++++++++++++++++++---- 2 files changed, 74 insertions(+), 9 deletions(-) diff --git a/src/test/perl/PostgresNode.pm b/src/test/perl/PostgresNode.pm index 76874141c5..e951acc461 100644 --- a/src/test/perl/PostgresNode.pm +++ b/src/test/perl/PostgresNode.pm @@ -157,6 +157,7 @@ sub new _host => $pghost, _basedir => "$TestLib::tmp_check/t_${testname}_${name}_data", _name => $name, + _tablespaces => [], _logfile_generation => 0, _logfile_base => "$TestLib::log_path/${testname}_${name}", _logfile => "$TestLib::log_path/${testname}_${name}.log" @@ -342,6 +343,26 @@ sub backup_dir =pod +=item $node->make_tablespace_dir() + +make a tablespace directory + +=cut + +sub make_tablespace_dir +{ + my ($self, $name) = @_; + my $basedir = $self->basedir; + + die "tablespace name contains '/'" if ($name =~ m#/#); + my $reldir = "../$name"; + mkdir $self->data_dir() . "/". $reldir; + push($self->{_tablespaces}, $reldir); + return $reldir; +} + +=pod + =item $node->info() Return a string containing human-readable diagnostic information (paths, etc) @@ -540,13 +561,27 @@ target server since it isn't done by default. sub backup { - my ($self, $backup_name) = @_; - my $backup_path = $self->backup_dir . '/' . $backup_name; + my ($self, $backup_name, %params) = @_; + my $backup_path = $self->backup_dir . '/' . $backup_name . '/' . "pgdata"; my $name = $self->name; + my @rest = (); + + if (defined $params{tablespace_mapping}) + { + foreach my $p (split /,/, $params{tablespace_mapping}) + { + push(@rest, "--tablespace-mapping=$p"); + } + } + + foreach my $p ($self->{_tablespaces}) + { + mkdir "$backup_path/$p"; + } print "# Taking pg_basebackup $backup_name from node \"$name\"\n"; TestLib::system_or_bail('pg_basebackup', '-D', $backup_path, '-h', - $self->host, '-p', $self->port, '--no-sync'); + $self->host, '-p', $self->port, '--no-sync', @rest); print "# Backup finished\n"; return; } @@ -592,7 +627,7 @@ sub backup_fs_cold sub _backup_fs { my ($self, $backup_name, $hot) = @_; - my $backup_path = $self->backup_dir . '/' . $backup_name; + my $backup_path = $self->backup_dir . '/' . $backup_name . '/' . "pgdata"; my $port = $self->port; my $name = $self->name; @@ -655,7 +690,7 @@ unconditionally set to enable replication connections. sub init_from_backup { my ($self, $root_node, $backup_name, %params) = @_; - my $backup_path = $root_node->backup_dir . '/' . $backup_name; + my $backup_path = $root_node->backup_dir . '/' . $backup_name . '/' . "pgdata"; my $host = $self->host; my $port = $self->port; my $node_name = $self->name; diff --git a/src/test/perl/RecursiveCopy.pm b/src/test/perl/RecursiveCopy.pm index baf5d0ac63..f165db7348 100644 --- a/src/test/perl/RecursiveCopy.pm +++ b/src/test/perl/RecursiveCopy.pm @@ -22,6 +22,7 @@ use warnings; use Carp; use File::Basename; use File::Copy; +use TestLib; =pod @@ -97,14 +98,43 @@ sub _copypath_recurse # invoke the filter and skip all further operation if it returns false return 1 unless &$filterfn($curr_path); - # 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; - # Abort if destination path already exists. Should we allow directories # to exist already? croak "Destination path \"$destpath\" already exists" if -e $destpath; + # Check for symlink -- needed only on source dir + # (note: this will fall through quietly if file is already gone) + if (-l $srcpath) + { + croak "Cannot operate on symlink \"$srcpath\"" + if ($srcpath !~ /\/(pg_tblspc\/[0-9]+)$/); + + # We have mapped tablespaces. Copy them individually + my $linkname = $1; + my $rpath = my $target = readlink($srcpath); + + #convert to pgdata-based if relative + $rpath =~ s#^\.\./##; + + my $srcrealdir = "$base_src_dir/$rpath"; + my $dstrealdir = "$base_dest_dir/$rpath"; + + mkdir $dstrealdir; + opendir(my $dh, $srcrealdir); + while (readdir $dh) + { + next if (/^\.\.?$/); + my $spath = "$srcrealdir/$_"; + my $dpath = "$dstrealdir/$_"; + + copypath($spath, $dpath); + } + closedir $dh; + + symlink $target, $destpath; + return 1; + } + # If this source path is a file, simply copy it to destination with the # same name and we're done. if (-f $srcpath) -- 2.16.3 ----Next_Part(Wed_Apr_24_17_02_28_2019_644)-- Content-Type: Text/X-Patch; charset=us-ascii Content-Transfer-Encoding: 7bit Content-Disposition: inline; filename="v2-0003-Add-check-for-recovery-failure-caused-by-tablespace.patch"