summaryrefslogtreecommitdiff
path: root/src/test/perl/PostgreSQL/Test/Cluster.pm
diff options
context:
space:
mode:
authorRobert Haas <rhaas@postgresql.org>2024-04-23 16:33:19 -0400
committerRobert Haas <rhaas@postgresql.org>2024-04-23 16:33:19 -0400
commit89ad3e1316bf0374f9e57456bf2888d14bf070f6 (patch)
tree9d10fdb194a691596f35f7d503b572ca39069a9c /src/test/perl/PostgreSQL/Test/Cluster.pm
parentba3e6e2bca97df14920375b0a1ebf4eab95b78b5 (diff)
Try again to add test coverage for pg_combinebackup w/tablespaces.
My previous attempt to add this had to be reverted in commit 82023d47de9e262730b1f9b4ea77fae201a89d0a. I've revised the problematic code a bit; hopefully it is OK now. Discussion: http://postgr.es/m/CA+Tgmobiv1QJR5PEJoDKeZDrJHZFRmi4XmWOqufN49DJj-3e2g@mail.gmail.com
Diffstat (limited to 'src/test/perl/PostgreSQL/Test/Cluster.pm')
-rw-r--r--src/test/perl/PostgreSQL/Test/Cluster.pm96
1 files changed, 89 insertions, 7 deletions
diff --git a/src/test/perl/PostgreSQL/Test/Cluster.pm b/src/test/perl/PostgreSQL/Test/Cluster.pm
index 9b2879c145c..aa9646329fb 100644
--- a/src/test/perl/PostgreSQL/Test/Cluster.pm
+++ b/src/test/perl/PostgreSQL/Test/Cluster.pm
@@ -777,7 +777,7 @@ sub backup_fs_cold
=pod
-=item $node->init_from_backup(root_node, backup_name)
+=item $node->init_from_backup(root_node, backup_name, %params)
Initialize a node from a backup, which may come from this node or a different
node. root_node must be a PostgreSQL::Test::Cluster reference, backup_name the string name
@@ -787,8 +787,13 @@ Does not start the node after initializing it.
By default, the backup is assumed to be plain format. To restore from
a tar-format backup, pass the name of the tar program to use in the
-keyword parameter tar_program. Note that tablespace tar files aren't
-handled here.
+keyword parameter tar_program.
+
+If there are tablespace present in the backup, include tablespace_map as
+a keyword parameter whose values is a hash. When combine_with_prior is used,
+the hash keys are the tablespace pathnames used in the backup; otherwise,
+they are tablespace OIDs. In either case, the values are the tablespace
+pathnames that should be used for the target cluster.
To restore from an incremental backup, pass the parameter combine_with_prior
as a reference to an array of prior backup names with which this backup
@@ -843,12 +848,20 @@ sub init_from_backup
}
local %ENV = $self->_get_env();
- PostgreSQL::Test::Utils::system_or_bail('pg_combinebackup', '-d',
- @prior_backup_path, $backup_path, '-o', $data_path);
+ my @combineargs = ('pg_combinebackup', '-d');
+ if (exists $params{tablespace_map})
+ {
+ while (my ($olddir, $newdir) = each %{$params{tablespace_map}})
+ {
+ push @combineargs, "-T$olddir=$newdir";
+ }
+ }
+ push @combineargs, @prior_backup_path, $backup_path, '-o', $data_path;
+ PostgreSQL::Test::Utils::system_or_bail(@combineargs);
}
elsif (defined $params{tar_program})
{
- mkdir($data_path);
+ mkdir($data_path) || die "mkdir $data_path: $!";
PostgreSQL::Test::Utils::system_or_bail($params{tar_program}, 'xf',
$backup_path . '/base.tar',
'-C', $data_path);
@@ -856,11 +869,80 @@ sub init_from_backup
$params{tar_program}, 'xf',
$backup_path . '/pg_wal.tar', '-C',
$data_path . '/pg_wal');
+
+ # We need to generate a tablespace_map file.
+ open(my $tsmap, ">", "$data_path/tablespace_map")
+ || die "$data_path/tablespace_map: $!";
+
+ # Extract tarfiles and add tablespace_map entries
+ my @tstars = grep { /^\d+.tar/ }
+ PostgreSQL::Test::Utils::slurp_dir($backup_path);
+ for my $tstar (@tstars)
+ {
+ my $tsoid = $tstar;
+ $tsoid =~ s/\.tar$//;
+
+ die "no tablespace mapping for $tstar"
+ if !exists $params{tablespace_map} ||
+ !exists $params{tablespace_map}{$tsoid};
+ my $newdir = $params{tablespace_map}{$tsoid};
+
+ mkdir($newdir) || die "mkdir $newdir: $!";
+ PostgreSQL::Test::Utils::system_or_bail($params{tar_program}, 'xf',
+ $backup_path . '/' . $tstar, '-C', $newdir);
+
+ my $escaped_newdir = $newdir;
+ $escaped_newdir =~ s/\\/\\\\/g;
+ print $tsmap "$tsoid $escaped_newdir\n";
+ }
+
+ # Close tablespace_map.
+ close($tsmap);
}
else
{
+ my @tsoids;
rmdir($data_path);
- PostgreSQL::Test::RecursiveCopy::copypath($backup_path, $data_path);
+
+ # Copy the main backup. If we see a tablespace directory for which we
+ # have a tablespace mapping, skip it, but remember that we saw it.
+ PostgreSQL::Test::RecursiveCopy::copypath($backup_path, $data_path,
+ 'filterfn' => sub {
+ my ($path) = @_;
+ if ($path =~ /^pg_tblspc\/(\d+)$/ &&
+ exists $params{tablespace_map}{$1})
+ {
+ push @tsoids, $1;
+ return 0;
+ }
+ return 1;
+ });
+
+ if (@tsoids > 0)
+ {
+ # We need to generate a tablespace_map file.
+ open(my $tsmap, ">", "$data_path/tablespace_map")
+ || die "$data_path/tablespace_map: $!";
+
+ # Now use the list of tablespace links to copy each tablespace.
+ for my $tsoid (@tsoids)
+ {
+ die "no tablespace mapping for $tsoid"
+ if !exists $params{tablespace_map} ||
+ !exists $params{tablespace_map}{$tsoid};
+
+ my $olddir = $backup_path . '/pg_tblspc/' . $tsoid;
+ my $newdir = $params{tablespace_map}{$tsoid};
+ PostgreSQL::Test::RecursiveCopy::copypath($olddir, $newdir);
+
+ my $escaped_newdir = $newdir;
+ $escaped_newdir =~ s/\\/\\\\/g;
+ print $tsmap "$tsoid $escaped_newdir\n";
+ }
+
+ # Close tablespace_map.
+ close($tsmap);
+ }
}
chmod(0700, $data_path) or die $!;