2013-11-17 21:58:21 +03:00
|
|
|
#!/usr/bin/perl
|
|
|
|
|
2014-02-05 19:35:09 +03:00
|
|
|
# /Library/PostgreSQL/9.3/bin/pg_ctl start -o "-c port=7000" -D /Users/backrest/test/backup/db/20140205-103801F/base -l /Users/backrest/test/backup/db/20140205-103801F/base/postgresql.log -w -s
|
|
|
|
|
2013-11-17 21:58:21 +03:00
|
|
|
#use strict;
|
2013-11-23 07:24:37 +03:00
|
|
|
use DBI;
|
2013-11-24 03:16:09 +03:00
|
|
|
use IPC::System::Simple qw(capture);
|
2013-12-02 22:34:37 +03:00
|
|
|
use Config::IniFiles;
|
2013-12-11 03:11:54 +03:00
|
|
|
use File::Find;
|
2013-11-17 21:58:21 +03:00
|
|
|
|
2013-11-24 03:16:09 +03:00
|
|
|
sub trim
|
|
|
|
{
|
|
|
|
local($strBuffer) = @_;
|
|
|
|
|
|
|
|
$strBuffer =~ s/^\s+|\s+$//g;
|
|
|
|
|
|
|
|
return $strBuffer;
|
|
|
|
}
|
2013-11-17 21:58:21 +03:00
|
|
|
|
|
|
|
sub execute
|
|
|
|
{
|
|
|
|
local($strCommand) = @_;
|
|
|
|
my $strOutput;
|
|
|
|
|
2013-11-24 03:16:09 +03:00
|
|
|
print("$strCommand");
|
|
|
|
$strOutput = trim(capture($strCommand));
|
|
|
|
|
|
|
|
if ($strOutput eq "")
|
|
|
|
{
|
|
|
|
print(" ... complete\n\n");
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
print(" ... complete\n$strOutput\n\n");
|
|
|
|
}
|
2013-11-17 21:58:21 +03:00
|
|
|
|
2013-11-23 07:24:37 +03:00
|
|
|
return $strOutput;
|
2013-11-17 21:58:21 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
sub pg_create
|
|
|
|
{
|
2013-12-07 04:24:14 +03:00
|
|
|
local($strPgBinPath, $strTestPath, $strTestDir, $strArchiveDir, $strBackupDir) = @_;
|
2013-11-17 21:58:21 +03:00
|
|
|
|
2013-11-24 03:16:09 +03:00
|
|
|
execute("mkdir $strTestPath");
|
2013-12-07 04:24:14 +03:00
|
|
|
execute("mkdir $strTestPath/$strTestDir");
|
|
|
|
execute("mkdir $strTestPath/$strTestDir/ts1");
|
|
|
|
execute("mkdir $strTestPath/$strTestDir/ts2");
|
|
|
|
execute($strPgBinPath . "/initdb -D $strTestPath/$strTestDir/common -A trust -k");
|
|
|
|
execute("mkdir $strTestPath/$strBackupDir");
|
2014-01-04 05:19:41 +03:00
|
|
|
# execute("mkdir -p $strTestPath/$strArchiveDir");
|
2013-11-17 21:58:21 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
sub pg_start
|
|
|
|
{
|
2013-11-24 03:16:09 +03:00
|
|
|
local($strPgBinPath, $strDbPath, $strPort, $strAchiveCommand) = @_;
|
|
|
|
my $strCommand = "$strPgBinPath/pg_ctl start -o \"-c port=$strPort -c wal_level=archive -c archive_mode=on -c archive_command=\'$strAchiveCommand\'\" -D $strDbPath -l $strDbPath/postgresql.log -w -s";
|
2013-11-17 21:58:21 +03:00
|
|
|
|
|
|
|
execute($strCommand);
|
|
|
|
}
|
|
|
|
|
2013-11-23 07:24:37 +03:00
|
|
|
sub pg_password_set
|
|
|
|
{
|
2013-12-11 03:11:54 +03:00
|
|
|
local($strPgBinPath, $strPath, $strUser, $strPort) = @_;
|
|
|
|
my $strCommand = "$strPgBinPath/psql --port=$strPort -c \"alter user $strUser with password 'password'\" postgres";
|
2013-11-23 07:24:37 +03:00
|
|
|
|
|
|
|
execute($strCommand);
|
|
|
|
}
|
|
|
|
|
2013-11-17 21:58:21 +03:00
|
|
|
sub pg_stop
|
|
|
|
{
|
2013-11-24 03:16:09 +03:00
|
|
|
local($strPgBinPath, $strPath) = @_;
|
2013-12-11 03:11:54 +03:00
|
|
|
my $strCommand = "$strPgBinPath/pg_ctl stop -D $strPath -w -s -m fast";
|
2013-11-17 21:58:21 +03:00
|
|
|
|
|
|
|
execute($strCommand);
|
|
|
|
}
|
|
|
|
|
|
|
|
sub pg_drop
|
|
|
|
{
|
2013-11-24 03:16:09 +03:00
|
|
|
local($strTestPath) = @_;
|
|
|
|
my $strCommand = "rm -rf $strTestPath";
|
2013-11-17 21:58:21 +03:00
|
|
|
|
|
|
|
execute($strCommand);
|
|
|
|
}
|
|
|
|
|
2013-11-23 07:24:37 +03:00
|
|
|
sub pg_execute
|
|
|
|
{
|
|
|
|
local($dbh, $strSql) = @_;
|
|
|
|
|
2013-11-24 04:05:04 +03:00
|
|
|
print($strSql);
|
2013-11-23 07:24:37 +03:00
|
|
|
$sth = $dbh->prepare($strSql);
|
2013-12-07 04:24:14 +03:00
|
|
|
$sth->execute() or die;
|
2013-11-24 04:05:04 +03:00
|
|
|
$sth->finish();
|
|
|
|
|
|
|
|
print(" ... complete\n\n");
|
2013-11-23 07:24:37 +03:00
|
|
|
}
|
|
|
|
|
2013-12-11 03:11:54 +03:00
|
|
|
sub archive_command_build
|
|
|
|
{
|
|
|
|
my $strBackRestBinPath = shift;
|
|
|
|
my $strDestinationPath = shift;
|
|
|
|
my $bCompression = shift;
|
|
|
|
my $bChecksum = shift;
|
|
|
|
|
2014-02-06 20:49:54 +03:00
|
|
|
my $strCommand = "$strBackRestBinPath/pg_backrest.pl --stanza=db --config=$strBackRestBinPath/pg_backrest.conf";
|
2013-12-11 03:11:54 +03:00
|
|
|
|
2014-02-12 15:39:42 +03:00
|
|
|
# if (!$bCompression)
|
|
|
|
# {
|
|
|
|
# $strCommand .= " --no-compression"
|
|
|
|
# }
|
|
|
|
#
|
|
|
|
# if (!$bChecksum)
|
|
|
|
# {
|
|
|
|
# $strCommand .= " --no-checksum"
|
|
|
|
# }
|
2013-12-11 03:11:54 +03:00
|
|
|
|
2014-01-04 05:19:41 +03:00
|
|
|
return $strCommand . " archive-push %p";
|
2013-12-11 03:11:54 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
sub wait_for_file
|
|
|
|
{
|
|
|
|
my $strDir = shift;
|
|
|
|
my $strRegEx = shift;
|
|
|
|
my $iSeconds = shift;
|
|
|
|
|
|
|
|
my $lTime = time();
|
|
|
|
my $hDir;
|
|
|
|
|
|
|
|
while ($lTime > time() - $iSeconds)
|
|
|
|
{
|
|
|
|
opendir $hDir, $strDir or die "Could not open dir: $!\n";
|
|
|
|
my @stryFile = grep(/$strRegEx/i, readdir $hDir);
|
|
|
|
close $hDir;
|
|
|
|
|
|
|
|
if (scalar @stryFile == 1)
|
|
|
|
{
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
# if (glob($strFile))
|
|
|
|
# {
|
|
|
|
# return;
|
|
|
|
# }
|
|
|
|
|
|
|
|
sleep(1);
|
|
|
|
}
|
|
|
|
|
|
|
|
die "could not find $strDir/$strRegEx after $iSeconds second(s)";
|
|
|
|
}
|
|
|
|
|
2013-12-11 04:16:43 +03:00
|
|
|
sub pgbr_backup
|
|
|
|
{
|
|
|
|
my $strBackRestBinPath = shift;
|
|
|
|
my $strCluster = shift;
|
|
|
|
|
|
|
|
my $strCommand = "$strBackRestBinPath/pg_backrest.pl --config=$strBackRestBinPath/pg_backrest.conf backup $strCluster";
|
|
|
|
|
|
|
|
execute($strCommand);
|
|
|
|
}
|
|
|
|
|
2013-11-23 07:24:37 +03:00
|
|
|
my $strUser = execute('whoami');
|
2013-11-24 03:16:09 +03:00
|
|
|
|
|
|
|
my $strTestPath = "/Users/dsteele/test";
|
|
|
|
my $strDbDir = "db";
|
2014-01-04 05:19:41 +03:00
|
|
|
my $strArchiveDir = "backup/db/archive";
|
2013-12-07 04:24:14 +03:00
|
|
|
my $strBackupDir = "backup";
|
2013-11-23 07:24:37 +03:00
|
|
|
|
2013-11-24 03:16:09 +03:00
|
|
|
my $strPgBinPath = "/Library/PostgreSQL/9.3/bin";
|
2013-12-11 03:11:54 +03:00
|
|
|
my $strPort = "6001";
|
2013-11-24 03:16:09 +03:00
|
|
|
|
|
|
|
my $strBackRestBinPath = "/Users/dsteele/pg_backrest";
|
2013-12-11 03:18:41 +03:00
|
|
|
my $strArchiveCommand = archive_command_build($strBackRestBinPath, "$strTestPath/$strArchiveDir", 0, 0);
|
2013-11-24 03:16:09 +03:00
|
|
|
|
|
|
|
################################################################################
|
|
|
|
# Stop the current test cluster if it is running and create a new one
|
|
|
|
################################################################################
|
|
|
|
eval {pg_stop($strPgBinPath, "$strTestPath/$strDbDir")};
|
|
|
|
|
|
|
|
if ($@)
|
|
|
|
{
|
|
|
|
print(" ... unable to stop pg server (ignoring): " . trim($@) . "\n\n")
|
|
|
|
}
|
|
|
|
|
|
|
|
pg_drop($strTestPath);
|
2013-12-07 04:24:14 +03:00
|
|
|
pg_create($strPgBinPath, $strTestPath, $strDbDir, $strArchiveDir, $strBackupDir);
|
|
|
|
pg_start($strPgBinPath, "$strTestPath/$strDbDir/common", $strPort, $strArchiveCommand);
|
2013-12-11 03:11:54 +03:00
|
|
|
pg_password_set($strPgBinPath, "$strTestPath/$strDbDir/common", $strUser, $strPort);
|
2013-11-23 07:24:37 +03:00
|
|
|
|
2013-11-24 03:16:09 +03:00
|
|
|
################################################################################
|
2013-11-24 04:05:04 +03:00
|
|
|
# Connect and start tests
|
2013-11-24 03:16:09 +03:00
|
|
|
################################################################################
|
2013-12-11 03:11:54 +03:00
|
|
|
$dbh = DBI->connect("dbi:Pg:dbname=postgres;port=$strPort;host=127.0.0.1", $strUser,
|
2013-11-24 04:05:04 +03:00
|
|
|
'password', {AutoCommit => 1});
|
|
|
|
|
2013-12-07 04:24:14 +03:00
|
|
|
pg_execute($dbh, "create tablespace ts1 location '$strTestPath/$strDbDir/ts1'");
|
|
|
|
pg_execute($dbh, "create tablespace ts2 location '$strTestPath/$strDbDir/ts2'");
|
|
|
|
|
2013-11-23 07:24:37 +03:00
|
|
|
pg_execute($dbh, "create table test (id int)");
|
2013-12-07 04:24:14 +03:00
|
|
|
pg_execute($dbh, "create table test_ts1 (id int) tablespace ts1");
|
|
|
|
pg_execute($dbh, "create table test_ts2 (id int) tablespace ts1");
|
2013-11-23 07:24:37 +03:00
|
|
|
|
|
|
|
pg_execute($dbh, "insert into test values (1)");
|
|
|
|
pg_execute($dbh, "select pg_switch_xlog()");
|
|
|
|
|
2014-01-04 05:19:41 +03:00
|
|
|
execute("mkdir -p $strTestPath/$strArchiveDir/0000000100000000");
|
|
|
|
|
2013-12-11 03:11:54 +03:00
|
|
|
# Test for archive log file 000000010000000000000001
|
2014-01-04 05:19:41 +03:00
|
|
|
wait_for_file("$strTestPath/$strArchiveDir/0000000100000000", "^000000010000000000000001\$", 5);
|
2013-12-11 03:11:54 +03:00
|
|
|
|
2013-12-11 03:18:41 +03:00
|
|
|
# Turn on log checksum for the next test
|
2013-12-11 03:11:54 +03:00
|
|
|
$dbh->disconnect();
|
|
|
|
pg_stop($strPgBinPath, "$strTestPath/$strDbDir/common");
|
|
|
|
$strArchiveCommand = archive_command_build($strBackRestBinPath, "$strTestPath/$strArchiveDir", 0, 1);
|
|
|
|
pg_start($strPgBinPath, "$strTestPath/$strDbDir/common", $strPort, $strArchiveCommand);
|
|
|
|
$dbh = DBI->connect("dbi:Pg:dbname=postgres;port=$strPort;host=127.0.0.1", $strUser,
|
|
|
|
'password', {AutoCommit => 1});
|
|
|
|
|
|
|
|
# Write another value into the test table
|
2013-11-23 07:24:37 +03:00
|
|
|
pg_execute($dbh, "insert into test values (2)");
|
|
|
|
pg_execute($dbh, "select pg_switch_xlog()");
|
|
|
|
|
2013-12-11 03:11:54 +03:00
|
|
|
# Test for archive log file 000000010000000000000002
|
2014-01-04 05:19:41 +03:00
|
|
|
wait_for_file("$strTestPath/$strArchiveDir/0000000100000000", "^000000010000000000000002-([a-f]|[0-9]){40}\$", 5);
|
2013-12-11 03:11:54 +03:00
|
|
|
|
2013-12-11 03:18:41 +03:00
|
|
|
# Turn on log compression and checksum for the next test
|
2013-12-11 03:11:54 +03:00
|
|
|
$dbh->disconnect();
|
|
|
|
pg_stop($strPgBinPath, "$strTestPath/$strDbDir/common");
|
2013-12-11 03:18:41 +03:00
|
|
|
$strArchiveCommand = archive_command_build($strBackRestBinPath, "$strTestPath/$strArchiveDir", 1, 1);
|
2013-12-11 03:11:54 +03:00
|
|
|
pg_start($strPgBinPath, "$strTestPath/$strDbDir/common", $strPort, $strArchiveCommand);
|
|
|
|
$dbh = DBI->connect("dbi:Pg:dbname=postgres;port=$strPort;host=127.0.0.1", $strUser,
|
|
|
|
'password', {AutoCommit => 1});
|
|
|
|
|
|
|
|
# Write another value into the test table
|
2013-11-23 07:24:37 +03:00
|
|
|
pg_execute($dbh, "insert into test values (3)");
|
|
|
|
pg_execute($dbh, "select pg_switch_xlog()");
|
2013-11-23 01:29:01 +03:00
|
|
|
|
2013-12-11 03:11:54 +03:00
|
|
|
# Test for archive log file 000000010000000000000003
|
2014-01-04 05:19:41 +03:00
|
|
|
wait_for_file("$strTestPath/$strArchiveDir/0000000100000000", "^000000010000000000000003-([a-f]|[0-9]){40}\\.gz\$", 5);
|
2013-12-11 03:11:54 +03:00
|
|
|
|
2013-11-24 04:05:04 +03:00
|
|
|
$dbh->disconnect();
|
|
|
|
|
|
|
|
################################################################################
|
|
|
|
# Stop the server
|
|
|
|
################################################################################
|
2013-12-14 21:14:59 +03:00
|
|
|
#pg_stop($strPgBinPath, "$strTestPath/$strDbDir/common");
|
2013-12-11 04:16:43 +03:00
|
|
|
|
|
|
|
################################################################################
|
|
|
|
# Start an offline backup
|
|
|
|
################################################################################
|
2014-01-12 09:46:27 +03:00
|
|
|
#pgbr_backup($strBackRestBinPath, "db");
|