1
0
mirror of https://github.com/postgres/postgres.git synced 2025-11-24 00:23:06 +03:00

Try again to add test coverage for pg_combinebackup w/tablespaces.

My previous attempt to add this had to be reverted in commit
82023d47de. I've revised the problematic
code a bit; hopefully it is OK now.

Discussion: http://postgr.es/m/CA+Tgmobiv1QJR5PEJoDKeZDrJHZFRmi4XmWOqufN49DJj-3e2g@mail.gmail.com
This commit is contained in:
Robert Haas
2024-04-23 16:33:19 -04:00
parent ba3e6e2bca
commit 89ad3e1316
3 changed files with 126 additions and 28 deletions

View File

@@ -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 $!;