2014-04-15 03:33:46 +02:00
|
|
|
use strict;
|
|
|
|
use warnings;
|
|
|
|
use Cwd;
|
2015-07-29 18:17:02 +02:00
|
|
|
use Config;
|
2014-04-15 03:33:46 +02:00
|
|
|
use TestLib;
|
2015-07-22 03:06:45 +02:00
|
|
|
use Test::More tests => 51;
|
2014-04-15 03:33:46 +02:00
|
|
|
|
|
|
|
program_help_ok('pg_basebackup');
|
|
|
|
program_version_ok('pg_basebackup');
|
|
|
|
program_options_handling_ok('pg_basebackup');
|
|
|
|
|
|
|
|
my $tempdir = tempdir;
|
|
|
|
start_test_server $tempdir;
|
|
|
|
|
2014-05-06 18:12:18 +02:00
|
|
|
command_fails(['pg_basebackup'],
|
|
|
|
'pg_basebackup needs target directory specified');
|
|
|
|
command_fails(
|
|
|
|
[ 'pg_basebackup', '-D', "$tempdir/backup" ],
|
|
|
|
'pg_basebackup fails because of hba');
|
2014-04-15 03:33:46 +02:00
|
|
|
|
2015-06-22 02:04:36 +02:00
|
|
|
# Some Windows ANSI code pages may reject this filename, in which case we
|
|
|
|
# quietly proceed without this bit of test coverage.
|
|
|
|
if (open BADCHARS, ">>$tempdir/pgdata/FOO\xe0\xe0\xe0BAR")
|
|
|
|
{
|
|
|
|
print BADCHARS "test backup of file with non-UTF8 name\n";
|
|
|
|
close BADCHARS;
|
|
|
|
}
|
|
|
|
|
2015-07-29 18:17:02 +02:00
|
|
|
configure_hba_for_replication "$tempdir/pgdata";
|
2015-07-09 12:19:10 +02:00
|
|
|
system_or_bail 'pg_ctl', '-D', "$tempdir/pgdata", 'reload';
|
2014-04-15 03:33:46 +02:00
|
|
|
|
2014-05-06 18:12:18 +02:00
|
|
|
command_fails(
|
|
|
|
[ 'pg_basebackup', '-D', "$tempdir/backup" ],
|
|
|
|
'pg_basebackup fails because of WAL configuration');
|
2014-04-15 03:33:46 +02:00
|
|
|
|
|
|
|
open CONF, ">>$tempdir/pgdata/postgresql.conf";
|
2015-07-22 03:06:45 +02:00
|
|
|
print CONF "max_replication_slots = 10\n";
|
2014-04-15 03:33:46 +02:00
|
|
|
print CONF "max_wal_senders = 10\n";
|
|
|
|
print CONF "wal_level = archive\n";
|
|
|
|
close CONF;
|
|
|
|
restart_test_server;
|
|
|
|
|
2014-05-06 18:12:18 +02:00
|
|
|
command_ok([ 'pg_basebackup', '-D', "$tempdir/backup" ],
|
|
|
|
'pg_basebackup runs');
|
2014-04-15 03:33:46 +02:00
|
|
|
ok(-f "$tempdir/backup/PG_VERSION", 'backup was created');
|
|
|
|
|
2015-07-01 03:15:29 +02:00
|
|
|
is_deeply([sort(slurp_dir("$tempdir/backup/pg_xlog/"))],
|
|
|
|
[sort qw(. .. archive_status)],
|
|
|
|
'no WAL files copied');
|
|
|
|
|
2014-05-06 18:12:18 +02:00
|
|
|
command_ok(
|
|
|
|
[ 'pg_basebackup', '-D', "$tempdir/backup2", '--xlogdir',
|
|
|
|
"$tempdir/xlog2" ],
|
|
|
|
'separate xlog directory');
|
2014-04-15 03:33:46 +02:00
|
|
|
ok(-f "$tempdir/backup2/PG_VERSION", 'backup was created');
|
2014-05-06 18:12:18 +02:00
|
|
|
ok(-d "$tempdir/xlog2/", 'xlog directory was created');
|
2014-04-15 03:33:46 +02:00
|
|
|
|
2014-05-06 18:12:18 +02:00
|
|
|
command_ok([ 'pg_basebackup', '-D', "$tempdir/tarbackup", '-Ft' ],
|
|
|
|
'tar format');
|
2014-04-15 03:33:46 +02:00
|
|
|
ok(-f "$tempdir/tarbackup/base.tar", 'backup tar was created');
|
|
|
|
|
2014-05-06 18:12:18 +02:00
|
|
|
command_fails(
|
|
|
|
[ 'pg_basebackup', '-D', "$tempdir/backup_foo", '-Fp', "-T=/foo" ],
|
|
|
|
'-T with empty old directory fails');
|
|
|
|
command_fails(
|
|
|
|
[ 'pg_basebackup', '-D', "$tempdir/backup_foo", '-Fp', "-T/foo=" ],
|
|
|
|
'-T with empty new directory fails');
|
|
|
|
command_fails(
|
|
|
|
[ 'pg_basebackup', '-D', "$tempdir/backup_foo", '-Fp',
|
|
|
|
"-T/foo=/bar=/baz" ],
|
|
|
|
'-T with multiple = fails');
|
|
|
|
command_fails(
|
|
|
|
[ 'pg_basebackup', '-D', "$tempdir/backup_foo", '-Fp', "-Tfoo=/bar" ],
|
|
|
|
'-T with old directory not absolute fails');
|
|
|
|
command_fails(
|
|
|
|
[ 'pg_basebackup', '-D', "$tempdir/backup_foo", '-Fp', "-T/foo=bar" ],
|
|
|
|
'-T with new directory not absolute fails');
|
|
|
|
command_fails(
|
|
|
|
[ 'pg_basebackup', '-D', "$tempdir/backup_foo", '-Fp', "-Tfoo" ],
|
|
|
|
'-T with invalid format fails');
|
2015-02-24 19:41:07 +01:00
|
|
|
|
2015-07-29 18:17:02 +02:00
|
|
|
# Tar format doesn't support filenames longer than 100 bytes.
|
|
|
|
my $superlongname = "superlongname_" . ("x" x 100);
|
|
|
|
my $superlongpath = "$tempdir/pgdata/$superlongname";
|
|
|
|
|
|
|
|
open FILE, ">$superlongpath" or die "unable to create file $superlongpath";
|
|
|
|
close FILE;
|
|
|
|
command_fails([ 'pg_basebackup', '-D', "$tempdir/tarbackup_l1", '-Ft' ],
|
|
|
|
'pg_basebackup tar with long name fails');
|
|
|
|
unlink "$tempdir/pgdata/$superlongname";
|
|
|
|
|
|
|
|
# The following tests test symlinks. Windows doesn't have symlinks, so
|
|
|
|
# skip on Windows.
|
|
|
|
SKIP: {
|
2015-08-03 02:58:18 +02:00
|
|
|
skip "symlinks not supported on Windows", 10 if ($windows_os);
|
2015-07-29 18:17:02 +02:00
|
|
|
|
|
|
|
# Create a temporary directory in the system location and symlink it
|
|
|
|
# to our physical temp location. That way we can use shorter names
|
|
|
|
# for the tablespace directories, which hopefully won't run afoul of
|
|
|
|
# the 99 character length limit.
|
|
|
|
my $shorter_tempdir = tempdir_short . "/tempdir";
|
|
|
|
symlink "$tempdir", $shorter_tempdir;
|
|
|
|
|
|
|
|
mkdir "$tempdir/tblspc1";
|
|
|
|
psql 'postgres',
|
|
|
|
"CREATE TABLESPACE tblspc1 LOCATION '$shorter_tempdir/tblspc1';";
|
|
|
|
psql 'postgres', "CREATE TABLE test1 (a int) TABLESPACE tblspc1;";
|
|
|
|
command_ok([ 'pg_basebackup', '-D', "$tempdir/tarbackup2", '-Ft' ],
|
|
|
|
'tar format with tablespaces');
|
|
|
|
ok(-f "$tempdir/tarbackup2/base.tar", 'backup tar was created');
|
|
|
|
my @tblspc_tars = glob "$tempdir/tarbackup2/[0-9]*.tar";
|
|
|
|
is(scalar(@tblspc_tars), 1, 'one tablespace tar was created');
|
|
|
|
|
|
|
|
command_fails(
|
|
|
|
[ 'pg_basebackup', '-D', "$tempdir/backup1", '-Fp' ],
|
|
|
|
'plain format with tablespaces fails without tablespace mapping');
|
|
|
|
|
|
|
|
command_ok(
|
|
|
|
[ 'pg_basebackup', '-D', "$tempdir/backup1", '-Fp',
|
|
|
|
"-T$shorter_tempdir/tblspc1=$tempdir/tbackup/tblspc1" ],
|
|
|
|
'plain format with tablespaces succeeds with tablespace mapping');
|
|
|
|
ok(-d "$tempdir/tbackup/tblspc1", 'tablespace was relocated');
|
|
|
|
opendir(my $dh, "$tempdir/pgdata/pg_tblspc") or die;
|
|
|
|
ok( ( grep {
|
|
|
|
-l "$tempdir/backup1/pg_tblspc/$_"
|
|
|
|
and readlink "$tempdir/backup1/pg_tblspc/$_" eq
|
|
|
|
"$tempdir/tbackup/tblspc1"
|
|
|
|
} readdir($dh)),
|
|
|
|
"tablespace symlink was updated");
|
|
|
|
closedir $dh;
|
|
|
|
|
|
|
|
mkdir "$tempdir/tbl=spc2";
|
|
|
|
psql 'postgres', "DROP TABLE test1;";
|
|
|
|
psql 'postgres', "DROP TABLESPACE tblspc1;";
|
|
|
|
psql 'postgres',
|
|
|
|
"CREATE TABLESPACE tblspc2 LOCATION '$shorter_tempdir/tbl=spc2';";
|
|
|
|
command_ok(
|
|
|
|
[ 'pg_basebackup', '-D', "$tempdir/backup3", '-Fp',
|
|
|
|
"-T$shorter_tempdir/tbl\\=spc2=$tempdir/tbackup/tbl\\=spc2" ],
|
|
|
|
'mapping tablespace with = sign in path');
|
|
|
|
ok(-d "$tempdir/tbackup/tbl=spc2", 'tablespace with = sign was relocated');
|
|
|
|
psql 'postgres', "DROP TABLESPACE tblspc2;";
|
|
|
|
|
|
|
|
mkdir "$tempdir/$superlongname";
|
|
|
|
psql 'postgres',
|
|
|
|
"CREATE TABLESPACE tblspc3 LOCATION '$tempdir/$superlongname';";
|
|
|
|
command_ok([ 'pg_basebackup', '-D', "$tempdir/tarbackup_l3", '-Ft' ],
|
|
|
|
'pg_basebackup tar with long symlink target');
|
|
|
|
psql 'postgres', "DROP TABLESPACE tblspc3;";
|
|
|
|
}
|
2015-07-01 03:15:05 +02:00
|
|
|
|
|
|
|
command_ok([ 'pg_basebackup', '-D', "$tempdir/backupR", '-R' ],
|
|
|
|
'pg_basebackup -R runs');
|
|
|
|
ok(-f "$tempdir/backupR/recovery.conf", 'recovery.conf was created');
|
|
|
|
my $recovery_conf = slurp_file "$tempdir/backupR/recovery.conf";
|
|
|
|
like($recovery_conf, qr/^standby_mode = 'on'$/m, 'recovery.conf sets standby_mode');
|
|
|
|
like($recovery_conf, qr/^primary_conninfo = '.*port=$ENV{PGPORT}.*'$/m, 'recovery.conf sets primary_conninfo');
|
2015-07-01 03:15:29 +02:00
|
|
|
|
|
|
|
command_ok([ 'pg_basebackup', '-D', "$tempdir/backupxf", '-X', 'fetch' ],
|
|
|
|
'pg_basebackup -X fetch runs');
|
|
|
|
ok(grep(/^[0-9A-F]{24}$/, slurp_dir("$tempdir/backupxf/pg_xlog")), 'WAL files copied');
|
|
|
|
command_ok([ 'pg_basebackup', '-D', "$tempdir/backupxs", '-X', 'stream' ],
|
|
|
|
'pg_basebackup -X stream runs');
|
|
|
|
ok(grep(/^[0-9A-F]{24}$/, slurp_dir("$tempdir/backupxf/pg_xlog")), 'WAL files copied');
|
2015-07-22 03:06:45 +02:00
|
|
|
|
|
|
|
command_fails([ 'pg_basebackup', '-D', "$tempdir/fail", '-S', 'slot1' ],
|
|
|
|
'pg_basebackup with replication slot fails without -X stream');
|
|
|
|
command_fails([ 'pg_basebackup', '-D', "$tempdir/backupxs_sl_fail", '-X', 'stream', '-S', 'slot1' ],
|
|
|
|
'pg_basebackup fails with nonexistent replication slot');
|
|
|
|
|
|
|
|
psql 'postgres', q{SELECT * FROM pg_create_physical_replication_slot('slot1')};
|
|
|
|
my $lsn = psql 'postgres', q{SELECT restart_lsn FROM pg_replication_slots WHERE slot_name = 'slot1'};
|
|
|
|
is($lsn, '', 'restart LSN of new slot is null');
|
|
|
|
command_ok([ 'pg_basebackup', '-D', "$tempdir/backupxs_sl", '-X', 'stream', '-S', 'slot1' ],
|
|
|
|
'pg_basebackup -X stream with replication slot runs');
|
|
|
|
$lsn = psql 'postgres', q{SELECT restart_lsn FROM pg_replication_slots WHERE slot_name = 'slot1'};
|
2015-07-29 18:17:02 +02:00
|
|
|
like($lsn, qr!^0/[0-9A-Z]{7,8}$!, 'restart LSN of slot has advanced');
|
2015-07-22 03:06:45 +02:00
|
|
|
|
|
|
|
command_ok([ 'pg_basebackup', '-D', "$tempdir/backupxs_sl_R", '-X', 'stream', '-S', 'slot1', '-R' ],
|
|
|
|
'pg_basebackup with replication slot and -R runs');
|
|
|
|
like(slurp_file("$tempdir/backupxs_sl_R/recovery.conf"),
|
|
|
|
qr/^primary_slot_name = 'slot1'$/m,
|
|
|
|
'recovery.conf sets primary_slot_name');
|