Make PostgreSQL::Test::Cluster::init_from_backup handle tablespaces.
This commit doesn't use this infrastructure for anything new, although it does adapt 010_pg_basebackup.pl to use it. However, a future commit will use this to improve test coverage for pg_combinebackup. Patch by me, reviewed (but not fully endorsed) by Andres Freund. Discussion: http://postgr.es/m/CA+TgmoYdXTjo9iQeoipTccDpWZzvBNS6EndY2uARM+T4yG_yDg@mail.gmail.com
This commit is contained in:
parent
41d2c6f952
commit
6bf5c42b55
|
@ -407,25 +407,12 @@ SKIP:
|
||||||
|
|
||||||
my $node2 = PostgreSQL::Test::Cluster->new('replica');
|
my $node2 = PostgreSQL::Test::Cluster->new('replica');
|
||||||
|
|
||||||
# Recover main data directory
|
# Recover the backup
|
||||||
$node2->init_from_backup($node, 'tarbackup2', tar_program => $tar);
|
|
||||||
|
|
||||||
# Recover tablespace into a new directory (not where it was!)
|
|
||||||
my $repTsDir = "$tempdir/tblspc1replica";
|
|
||||||
my $realRepTsDir = "$real_sys_tempdir/tblspc1replica";
|
|
||||||
mkdir $repTsDir;
|
|
||||||
PostgreSQL::Test::Utils::system_or_bail($tar, 'xf', $tblspc_tars[0],
|
|
||||||
'-C', $repTsDir);
|
|
||||||
|
|
||||||
# Update tablespace map to point to new directory.
|
|
||||||
# XXX Ideally pg_basebackup would handle this.
|
|
||||||
$tblspc_tars[0] =~ m|/([0-9]*)\.tar$|;
|
$tblspc_tars[0] =~ m|/([0-9]*)\.tar$|;
|
||||||
my $tblspcoid = $1;
|
my $tblspcoid = $1;
|
||||||
my $escapedRepTsDir = $realRepTsDir;
|
my $realRepTsDir = "$real_sys_tempdir/tblspc1replica";
|
||||||
$escapedRepTsDir =~ s/\\/\\\\/g;
|
$node2->init_from_backup($node, 'tarbackup2', tar_program => $tar,
|
||||||
open my $mapfile, '>', $node2->data_dir . '/tablespace_map' or die $!;
|
'tablespace_map' => { $tblspcoid => $realRepTsDir });
|
||||||
print $mapfile "$tblspcoid $escapedRepTsDir\n";
|
|
||||||
close $mapfile;
|
|
||||||
|
|
||||||
$node2->start;
|
$node2->start;
|
||||||
my $result = $node2->safe_psql('postgres', 'SELECT * FROM test1');
|
my $result = $node2->safe_psql('postgres', 'SELECT * FROM test1');
|
||||||
|
|
|
@ -777,7 +777,7 @@ sub backup_fs_cold
|
||||||
|
|
||||||
=pod
|
=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
|
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
|
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
|
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
|
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
|
keyword parameter tar_program.
|
||||||
handled here.
|
|
||||||
|
If there are tablespace present in the backup, include tablespace_map as
|
||||||
|
a keyword parameter whose values is a hash. When tar_program is used, the
|
||||||
|
hash keys are tablespace OIDs; otherwise, they are the tablespace pathnames
|
||||||
|
used in the backup. 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
|
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
|
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();
|
local %ENV = $self->_get_env();
|
||||||
PostgreSQL::Test::Utils::system_or_bail('pg_combinebackup', '-d',
|
my @combineargs = ('pg_combinebackup', '-d');
|
||||||
@prior_backup_path, $backup_path, '-o', $data_path);
|
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})
|
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',
|
PostgreSQL::Test::Utils::system_or_bail($params{tar_program}, 'xf',
|
||||||
$backup_path . '/base.tar',
|
$backup_path . '/base.tar',
|
||||||
'-C', $data_path);
|
'-C', $data_path);
|
||||||
|
@ -856,11 +869,77 @@ sub init_from_backup
|
||||||
$params{tar_program}, 'xf',
|
$params{tar_program}, 'xf',
|
||||||
$backup_path . '/pg_wal.tar', '-C',
|
$backup_path . '/pg_wal.tar', '-C',
|
||||||
$data_path . '/pg_wal');
|
$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
|
else
|
||||||
{
|
{
|
||||||
|
my @tsoids;
|
||||||
rmdir($data_path);
|
rmdir($data_path);
|
||||||
PostgreSQL::Test::RecursiveCopy::copypath($backup_path, $data_path);
|
|
||||||
|
# Copy the main backup. Exclude tablespace links, but remember them.
|
||||||
|
PostgreSQL::Test::RecursiveCopy::copypath($backup_path, $data_path,
|
||||||
|
'filterfn' => sub {
|
||||||
|
my ($path) = @_;
|
||||||
|
if ($path =~ /^pg_tblspc\/(\d+)$/ && -l "$backup_path/$path")
|
||||||
|
{
|
||||||
|
push @tsoids, $1;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
});
|
||||||
|
|
||||||
|
# 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)
|
||||||
|
{
|
||||||
|
my $olddir = readlink("$backup_path/pg_tblspc/$tsoid")
|
||||||
|
|| die "readlink $backup_path/pg_tblspc/$tsoid: $!";
|
||||||
|
|
||||||
|
die "no tablespace mapping for $olddir"
|
||||||
|
if !exists $params{tablespace_map} ||
|
||||||
|
!exists $params{tablespace_map}{$olddir};
|
||||||
|
|
||||||
|
my $newdir = $params{tablespace_map}{$olddir};
|
||||||
|
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 $!;
|
chmod(0700, $data_path) or die $!;
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue