1
0
mirror of https://github.com/pgbackrest/pgbackrest.git synced 2025-07-17 01:12:23 +02:00

Recovery is working for none and default, but unit tests are not complete.

This commit is contained in:
David Steele
2015-01-27 11:44:23 -05:00
parent f59aae101d
commit 13544d51bf
7 changed files with 312 additions and 118 deletions

View File

@ -459,7 +459,10 @@ if (operation_get() eq OP_RESTORE)
param_get(PARAM_TARGET_EXCLUSIVE), param_get(PARAM_TARGET_EXCLUSIVE),
param_get(PARAM_TARGET_RESUME), param_get(PARAM_TARGET_RESUME),
param_get(PARAM_TARGET_TIMELINE), param_get(PARAM_TARGET_TIMELINE),
config_section_load(CONFIG_SECTION_RECOVERY) config_section_load(CONFIG_SECTION_RECOVERY),
param_get(PARAM_STANZA),
$0,
param_get(PARAM_CONFIG)
)->restore; )->restore;
remote_exit(0); remote_exit(0);

View File

@ -15,6 +15,7 @@ use Thread::Queue;
use lib dirname($0); use lib dirname($0);
use BackRest::Utility; use BackRest::Utility;
use BackRest::Exception;
use BackRest::Config; use BackRest::Config;
use BackRest::Manifest; use BackRest::Manifest;
use BackRest::File; use BackRest::File;
@ -69,6 +70,7 @@ sub backup_init
$bCompress = $bCompressParam; $bCompress = $bCompressParam;
$bHardLink = $bHardLinkParam; $bHardLink = $bHardLinkParam;
$bNoChecksum = $bNoChecksumParam; $bNoChecksum = $bNoChecksumParam;
$bArchiveRequired = $bArchiveRequiredParam;
$iThreadMax = $iThreadMaxParam; $iThreadMax = $iThreadMaxParam;
$iThreadTimeout = $iThreadTimeoutParam; $iThreadTimeout = $iThreadTimeoutParam;
$bNoStartStop = $bNoStartStopParam; $bNoStartStop = $bNoStartStopParam;
@ -1635,6 +1637,9 @@ sub backup
# Save the backup manifest a second time - before getting archive logs in case that fails # Save the backup manifest a second time - before getting archive logs in case that fails
$oBackupManifest->save(); $oBackupManifest->save();
# Create the modification time for the archive logs
my $lModificationTime = time();
# After the backup has been stopped, need to make a copy of the archive logs need to make the db consistent # After the backup has been stopped, need to make a copy of the archive logs need to make the db consistent
&log(DEBUG, "retrieving archive logs ${strArchiveStart}:${strArchiveStop}"); &log(DEBUG, "retrieving archive logs ${strArchiveStart}:${strArchiveStop}");
my @stryArchive = archive_list_get($strArchiveStart, $strArchiveStop, $oDb->db_version_get() < 9.3); my @stryArchive = archive_list_get($strArchiveStart, $strArchiveStop, $oDb->db_version_get() < 9.3);
@ -1655,10 +1660,39 @@ sub backup
&log(DEBUG, "archiving: ${strArchive} (${stryArchiveFile[0]})"); &log(DEBUG, "archiving: ${strArchive} (${stryArchiveFile[0]})");
# Copy the log file from the archive repo to the backup
my $strDestinationFile = "base/pg_xlog/${strArchive}" . ($bCompress ? ".$oFile->{strCompressExtension}" : '');
$oFile->copy(PATH_BACKUP_ARCHIVE, $stryArchiveFile[0], $oFile->copy(PATH_BACKUP_ARCHIVE, $stryArchiveFile[0],
PATH_BACKUP_TMP, "base/pg_xlog/${strArchive}" . ($bCompress ? ".$oFile->{strCompressExtension}" : ''), PATH_BACKUP_TMP, $strDestinationFile,
$stryArchiveFile[0] =~ "^.*\.$oFile->{strCompressExtension}\$", $stryArchiveFile[0] =~ "^.*\.$oFile->{strCompressExtension}\$",
$bCompress); $bCompress, undef, $lModificationTime);
# Add the archive file to the manifest so it can be part of the restore and checked in validation
my $strPathSection = 'base:path';
my $strPathLog = 'pg_xlog';
my $strFileSection = 'base:file';
my $strFileLog = "pg_xlog/${strArchive}";
# Get the checksum and compare against the one already on log log file (if there is one)
my $strChecksum = $oFile->hash(PATH_BACKUP_TMP, $strDestinationFile, $bCompress);
if ($stryArchiveFile[0] =~ "^${strArchive}-[0-f]+(\\.$oFile->{strCompressExtension}){0,1}\$" &&
$stryArchiveFile[0] !~ "^${strArchive}-${strChecksum}(\\.$oFile->{strCompressExtension}){0,1}\$")
{
confess &log(ERROR, "error copying log '$stryArchiveFile[0]' to backup - checksum recored with file does " .
"not match actual checksum of '${strChecksum}'", ERROR_CHECKSUM);
}
# Set manifest values
$oBackupManifest->set($strFileSection, $strFileLog, MANIFEST_SUBKEY_USER,
$oBackupManifest->get($strPathSection, $strPathLog, MANIFEST_SUBKEY_USER));
$oBackupManifest->set($strFileSection, $strFileLog, MANIFEST_SUBKEY_GROUP,
$oBackupManifest->get($strPathSection, $strPathLog, MANIFEST_SUBKEY_GROUP));
$oBackupManifest->set($strFileSection, $strFileLog, MANIFEST_SUBKEY_MODE, '0700');
$oBackupManifest->set($strFileSection, $strFileLog, MANIFEST_SUBKEY_MODIFICATION_TIME, $lModificationTime);
$oBackupManifest->set($strFileSection, $strFileLog, MANIFEST_SUBKEY_SIZE, 16777216);
$oBackupManifest->set($strFileSection, $strFileLog, MANIFEST_SUBKEY_CHECKSUM, $strChecksum);
} }
} }

View File

@ -12,15 +12,16 @@ use Carp;
# Exports # Exports
#################################################################################################################################### ####################################################################################################################################
use Exporter qw(import); use Exporter qw(import);
our @EXPORT = qw(ERROR_RESTORE_PATH_NOT_EMPTY ERROR_PARAM); our @EXPORT = qw(ERROR_CHECKSUM ERROR_PARAM ERROR_RESTORE_PATH_NOT_EMPTY);
#################################################################################################################################### ####################################################################################################################################
# Exception Codes # Exception Codes
#################################################################################################################################### ####################################################################################################################################
use constant use constant
{ {
ERROR_RESTORE_PATH_NOT_EMPTY => 100, ERROR_CHECKSUM => 100,
ERROR_PARAM => 101 ERROR_PARAM => 101,
ERROR_RESTORE_PATH_NOT_EMPTY => 102
}; };
#################################################################################################################################### ####################################################################################################################################

View File

@ -8,7 +8,6 @@ use strict;
use warnings; use warnings;
use Carp; use Carp;
use POSIX qw(ceil);
use Net::OpenSSH; use Net::OpenSSH;
use File::Basename qw(dirname basename); use File::Basename qw(dirname basename);
use File::Copy qw(cp); use File::Copy qw(cp);
@ -19,7 +18,6 @@ use Fcntl ':mode';
use IO::Compress::Gzip qw(gzip $GzipError); use IO::Compress::Gzip qw(gzip $GzipError);
use IO::Uncompress::Gunzip qw(gunzip $GunzipError); use IO::Uncompress::Gunzip qw(gunzip $GunzipError);
use IO::String; use IO::String;
use Time::HiRes qw(gettimeofday usleep);
use lib dirname($0) . '/../lib'; use lib dirname($0) . '/../lib';
use BackRest::Exception; use BackRest::Exception;
@ -1052,14 +1050,7 @@ sub wait
else else
{ {
# Wait the remainder of the current second # Wait the remainder of the current second
$lTimeBegin = gettimeofday(); $lTimeBegin = wait_remainder();
my $lSleepMs = ceil(((int($lTimeBegin) + 1) - $lTimeBegin) * 1000);
usleep($lSleepMs * 1000);
&log(TRACE, "${strOperation}: slept ${lSleepMs}ms: begin ${lTimeBegin}, end " . gettimeofday());
$lTimeBegin = int($lTimeBegin);
} }
return $lTimeBegin; return $lTimeBegin;

View File

@ -40,6 +40,9 @@ sub new
my $bTargetResume = shift; # Target resume option my $bTargetResume = shift; # Target resume option
my $bTargetTimeline = shift; # Target timeline option my $bTargetTimeline = shift; # Target timeline option
my $oRecoveryRef = shift; # Other recovery options my $oRecoveryRef = shift; # Other recovery options
my $strStanza = shift; # Restore stanza
my $strBackRestBin = shift; # Absolute backrest filename
my $strConfigFile = shift; # Absolute config filename (optional)
# Create the class hash # Create the class hash
my $self = {}; my $self = {};
@ -58,6 +61,9 @@ sub new
$self->{bTargetResume} = $bTargetResume; $self->{bTargetResume} = $bTargetResume;
$self->{bTargetTimeline} = $bTargetTimeline; $self->{bTargetTimeline} = $bTargetTimeline;
$self->{oRecoveryRef} = $oRecoveryRef; $self->{oRecoveryRef} = $oRecoveryRef;
$self->{strStanza} = $strStanza;
$self->{strBackRestBin} = $strBackRestBin;
$self->{strConfigFile} = $strConfigFile;
# If backup path is not specified then default to latest # If backup path is not specified then default to latest
if (defined($strBackupPath)) if (defined($strBackupPath))
@ -481,37 +487,40 @@ sub recovery
} }
} }
# If RECOVERY_TYPE_DEFAULT then return # Write the restore command
if ($self->{strType} eq RECOVERY_TYPE_DEFAULT) $strRecovery .= "restore_command = '$self->{strBackRestBin} --stanza=$self->{strStanza}" .
{ (defined($self->{strConfigFile}) ? " --config=$self->{strConfigFile}" : '') .
return; " archive-get %f \"%p\"'\n";
}
# Write the recovery target # If RECOVERY_TYPE_DEFAULT do not write target options
$strRecovery .= "recovery_target_$self->{strType} = $self->{strTarget}\n"; if ($self->{strType} ne RECOVERY_TYPE_DEFAULT)
# Write recovery_target_inclusive
if ($self->{bTargetExclusive})
{ {
$strRecovery .= "recovery_target_inclusive = false\n"; # Write the recovery target
} $strRecovery .= "recovery_target_$self->{strType} = $self->{strTarget}\n";
# Write recovery_target_inclusive # Write recovery_target_inclusive
if ($self->{bTargetExclusive}) if ($self->{bTargetExclusive})
{ {
$strRecovery .= "recovery_target_inclusive = false\n"; $strRecovery .= "recovery_target_inclusive = false\n";
} }
# Write pause_at_recovery_target # Write recovery_target_inclusive
if ($self->{bTargetResult}) if ($self->{bTargetExclusive})
{ {
$strRecovery .= "pause_at_recovery_target = false\n"; $strRecovery .= "recovery_target_inclusive = false\n";
} }
# Write recovery_target_timeline # Write pause_at_recovery_target
if (defined($self->{strTargetTimeline})) if ($self->{bTargetResult})
{ {
$strRecovery .= "recovery_target_timeline = $self->{strTargetTimeline}\n"; $strRecovery .= "pause_at_recovery_target = false\n";
}
# Write recovery_target_timeline
if (defined($self->{strTargetTimeline}))
{
$strRecovery .= "recovery_target_timeline = $self->{strTargetTimeline}\n";
}
} }
# Write recovery.conf # Write recovery.conf

View File

@ -10,7 +10,8 @@ use Carp qw(confess longmess);
use Fcntl qw(:DEFAULT :flock); use Fcntl qw(:DEFAULT :flock);
use File::Path qw(remove_tree); use File::Path qw(remove_tree);
use Time::HiRes qw(usleep); use Time::HiRes qw(gettimeofday usleep);
use POSIX qw(ceil);
use File::Basename; use File::Basename;
use JSON; use JSON;
@ -22,7 +23,7 @@ use Exporter qw(import);
our @EXPORT = qw(version_get our @EXPORT = qw(version_get
data_hash_build trim common_prefix wait_for_file file_size_format execute data_hash_build trim common_prefix wait_for_file file_size_format execute
log log_file_set log_level_set test_set test_get test_check log log_file_set log_level_set test_set test_get test_check
lock_file_create lock_file_remove hsleep lock_file_create lock_file_remove hsleep wait_remainder
ini_save ini_load timestamp_string_get timestamp_file_string_get ini_save ini_load timestamp_string_get timestamp_file_string_get
TRACE DEBUG ERROR ASSERT WARN INFO OFF true false TRACE DEBUG ERROR ASSERT WARN INFO OFF true false
TEST TEST_ENCLOSE TEST_MANIFEST_BUILD TEST_BACKUP_RESUME TEST_BACKUP_NORESUME); TEST TEST_ENCLOSE TEST_MANIFEST_BUILD TEST_BACKUP_RESUME TEST_BACKUP_NORESUME);
@ -159,6 +160,21 @@ sub lock_file_remove
} }
} }
####################################################################################################################################
# WAIT_REMAINDER - Wait the remainder of the current second
####################################################################################################################################
sub wait_remainder
{
my $lTimeBegin = gettimeofday();
my $lSleepMs = ceil(((int($lTimeBegin) + 1) - $lTimeBegin) * 1000);
usleep($lSleepMs * 1000);
&log(TRACE, "WAIT_REMAINDER: slept ${lSleepMs}ms: begin ${lTimeBegin}, end " . gettimeofday());
return int($lTimeBegin);
}
#################################################################################################################################### ####################################################################################################################################
# DATA_HASH_BUILD - Hash a delimited file with header # DATA_HASH_BUILD - Hash a delimited file with header
#################################################################################################################################### ####################################################################################################################################

View File

@ -21,6 +21,7 @@ use DBI;
use lib dirname($0) . '/../lib'; use lib dirname($0) . '/../lib';
use BackRest::Exception; use BackRest::Exception;
use BackRest::Utility; use BackRest::Utility;
use BackRest::Config;
use BackRest::File; use BackRest::File;
use BackRest::Remote; use BackRest::Remote;
@ -49,7 +50,7 @@ sub BackRestTestBackup_PgConnect
';host=' . BackRestTestCommon_DbPathGet(), ';host=' . BackRestTestCommon_DbPathGet(),
BackRestTestCommon_UserGet(), BackRestTestCommon_UserGet(),
undef, undef,
{AutoCommit => 1, RaiseError => 1}); {AutoCommit => 0, RaiseError => 1});
} }
#################################################################################################################################### ####################################################################################################################################
@ -72,6 +73,10 @@ sub BackRestTestBackup_PgExecute
{ {
my $strSql = shift; my $strSql = shift;
my $bCheckpoint = shift; my $bCheckpoint = shift;
my $bCommit = shift;
# Set defaults
$bCommit = defined($bCommit) ? $bCommit : true;
# Log and execute the statement # Log and execute the statement
&log(DEBUG, "SQL: ${strSql}"); &log(DEBUG, "SQL: ${strSql}");
@ -82,6 +87,11 @@ sub BackRestTestBackup_PgExecute
$hStatement->finish(); $hStatement->finish();
if ($bCommit)
{
BackRestTestBackup_PgExecute('commit', false, false);
}
# Perform a checkpoint if requested # Perform a checkpoint if requested
if (defined($bCheckpoint) && $bCheckpoint) if (defined($bCheckpoint) && $bCheckpoint)
{ {
@ -89,6 +99,39 @@ sub BackRestTestBackup_PgExecute
} }
} }
####################################################################################################################################
# BackRestTestBackup_PgSelect
####################################################################################################################################
sub BackRestTestBackup_PgSelect
{
my $strSql = shift;
# Log and execute the statement
&log(DEBUG, "SQL: ${strSql}");
my $hStatement = $hDb->prepare($strSql);
$hStatement = $hDb->prepare($strSql);
$hStatement->execute() or
confess &log(ERROR, "Unable to execute: ${strSql}");
my @oyRow = $hStatement->fetchrow_array();
$hStatement->finish();
return @oyRow;
}
####################################################################################################################################
# BackRestTestBackup_PgSelectOne
####################################################################################################################################
sub BackRestTestBackup_PgSelectOne
{
my $strSql = shift;
return (BackRestTestBackup_PgSelect($strSql))[0];
}
#################################################################################################################################### ####################################################################################################################################
# BackRestTestBackup_ClusterStop # BackRestTestBackup_ClusterStop
#################################################################################################################################### ####################################################################################################################################
@ -96,6 +139,9 @@ sub BackRestTestBackup_ClusterStop
{ {
my $strPath = shift; my $strPath = shift;
# Set default
$strPath = defined($strPath) ? $strPath : BackRestTestCommon_DbCommonPathGet();
# Disconnect user session # Disconnect user session
BackRestTestBackup_PgDisconnect(); BackRestTestBackup_PgDisconnect();
@ -106,6 +152,39 @@ sub BackRestTestBackup_ClusterStop
} }
} }
####################################################################################################################################
# BackRestTestBackup_ClusterStart
####################################################################################################################################
sub BackRestTestBackup_ClusterStart
{
my $strPath = shift;
my $iPort = shift;
# Set default
$iPort = defined($iPort) ? $iPort : BackRestTestCommon_DbPortGet();
$strPath = defined($strPath) ? $strPath : BackRestTestCommon_DbCommonPathGet();
# Make sure postgres is not running
if (-e $strPath . '/postmaster.pid')
{
confess 'postmaster.pid exists';
}
# Creat the archive command
my $strArchive = BackRestTestCommon_CommandMainGet() . ' --stanza=' . BackRestTestCommon_StanzaGet() .
' --config=' . BackRestTestCommon_DbPathGet() . '/pg_backrest.conf archive-push %p';
# Start the cluster
BackRestTestCommon_Execute(BackRestTestCommon_PgSqlBinPathGet() . "/pg_ctl start -o \"-c port=${iPort} -c " .
"checkpoint_segments=1 -c wal_level=archive -c archive_mode=on -c archive_command='${strArchive}' " .
"-c unix_socket_directories='" . BackRestTestCommon_DbPathGet() . "'\" " .
"-D ${strPath} -l ${strPath}/postgresql.log -w -s");
# Connect user session
BackRestTestBackup_PgConnect();
}
#################################################################################################################################### ####################################################################################################################################
# BackRestTestBackup_ClusterRestart # BackRestTestBackup_ClusterRestart
#################################################################################################################################### ####################################################################################################################################
@ -134,14 +213,9 @@ sub BackRestTestBackup_ClusterCreate
my $strPath = shift; my $strPath = shift;
my $iPort = shift; my $iPort = shift;
my $strArchive = BackRestTestCommon_CommandMainGet() . ' --stanza=' . BackRestTestCommon_StanzaGet() .
' --config=' . BackRestTestCommon_DbPathGet() . '/pg_backrest.conf archive-push %p';
BackRestTestCommon_Execute(BackRestTestCommon_PgSqlBinPathGet() . "/initdb -D ${strPath} -A trust"); BackRestTestCommon_Execute(BackRestTestCommon_PgSqlBinPathGet() . "/initdb -D ${strPath} -A trust");
BackRestTestCommon_Execute(BackRestTestCommon_PgSqlBinPathGet() . "/pg_ctl start -o \"-c port=${iPort} -c " .
"checkpoint_segments=1 -c wal_level=archive -c archive_mode=on -c archive_command='${strArchive}' " . BackRestTestBackup_ClusterStart($strPath, $iPort);
"-c unix_socket_directories='" . BackRestTestCommon_DbPathGet() . "'\" " .
"-D ${strPath} -l ${strPath}/postgresql.log -w -s");
# Connect user session # Connect user session
BackRestTestBackup_PgConnect(); BackRestTestBackup_PgConnect();
@ -669,6 +743,7 @@ sub BackRestTestBackup_BackupBegin
my $strStanza = shift; my $strStanza = shift;
my $bRemote = shift; my $bRemote = shift;
my $strComment = shift; my $strComment = shift;
my $bSynthetic = shift;
my $bTestPoint = shift; my $bTestPoint = shift;
my $fTestDelay = shift; my $fTestDelay = shift;
@ -680,7 +755,8 @@ sub BackRestTestBackup_BackupBegin
BackRestTestCommon_ExecuteBegin(BackRestTestCommon_CommandMainGet() . ' --config=' . BackRestTestCommon_ExecuteBegin(BackRestTestCommon_CommandMainGet() . ' --config=' .
($bRemote ? BackRestTestCommon_BackupPathGet() : BackRestTestCommon_DbPathGet()) . ($bRemote ? BackRestTestCommon_BackupPathGet() : BackRestTestCommon_DbPathGet()) .
"/pg_backrest.conf --no-start-stop" . ($strType ne 'incr' ? " --type=${strType}" : '') . "/pg_backrest.conf" . ($bSynthetic ? " --no-start-stop" : '') .
($strType ne 'incr' ? " --type=${strType}" : '') .
" --stanza=${strStanza} backup" . ($bTestPoint ? " --test --test-delay=${fTestDelay}": ''), " --stanza=${strStanza} backup" . ($bTestPoint ? " --test --test-delay=${fTestDelay}": ''),
$bRemote); $bRemote);
} }
@ -695,6 +771,7 @@ sub BackRestTestBackup_BackupEnd
my $bRemote = shift; my $bRemote = shift;
my $strBackup = shift; my $strBackup = shift;
my $oExpectedManifestRef = shift; my $oExpectedManifestRef = shift;
my $bSynthetic = shift;
my $iExpectedExitStatus = shift; my $iExpectedExitStatus = shift;
my $iExitStatus = BackRestTestCommon_ExecuteEnd(undef, undef, undef, $iExpectedExitStatus); my $iExitStatus = BackRestTestCommon_ExecuteEnd(undef, undef, undef, $iExpectedExitStatus);
@ -711,15 +788,18 @@ sub BackRestTestBackup_BackupEnd
$strBackup = BackRestTestBackup_LastBackup($oFile); $strBackup = BackRestTestBackup_LastBackup($oFile);
} }
BackRestTestBackup_BackupCompare($oFile, $bRemote, $strBackup, $oExpectedManifestRef); if ($bSynthetic)
{
BackRestTestBackup_BackupCompare($oFile, $bRemote, $strBackup, $oExpectedManifestRef);
}
return $strBackup; return $strBackup;
} }
#################################################################################################################################### ####################################################################################################################################
# BackRestTestBackup_Backup # BackRestTestBackup_BackupSynthetic
#################################################################################################################################### ####################################################################################################################################
sub BackRestTestBackup_Backup sub BackRestTestBackup_BackupSynthetic
{ {
my $strType = shift; my $strType = shift;
my $strStanza = shift; my $strStanza = shift;
@ -731,14 +811,38 @@ sub BackRestTestBackup_Backup
my $fTestDelay = shift; my $fTestDelay = shift;
my $iExpectedExitStatus = shift; my $iExpectedExitStatus = shift;
BackRestTestBackup_BackupBegin($strType, $strStanza, $bRemote, $strComment, defined($strTestPoint), $fTestDelay); BackRestTestBackup_BackupBegin($strType, $strStanza, $bRemote, $strComment, true, defined($strTestPoint), $fTestDelay);
if (defined($strTestPoint)) if (defined($strTestPoint))
{ {
BackRestTestCommon_ExecuteEnd($strTestPoint); BackRestTestCommon_ExecuteEnd($strTestPoint);
} }
return BackRestTestBackup_BackupEnd($strType, $oFile, $bRemote, undef, $oExpectedManifestRef, $iExpectedExitStatus); return BackRestTestBackup_BackupEnd($strType, $oFile, $bRemote, undef, $oExpectedManifestRef, true, $iExpectedExitStatus);
}
####################################################################################################################################
# BackRestTestBackup_Backup
####################################################################################################################################
sub BackRestTestBackup_Backup
{
my $strType = shift;
my $strStanza = shift;
my $bRemote = shift;
my $oFile = shift;
my $strComment = shift;
my $strTestPoint = shift;
my $fTestDelay = shift;
my $iExpectedExitStatus = shift;
BackRestTestBackup_BackupBegin($strType, $strStanza, $bRemote, $strComment, false, defined($strTestPoint), $fTestDelay);
if (defined($strTestPoint))
{
BackRestTestCommon_ExecuteEnd($strTestPoint);
}
return BackRestTestBackup_BackupEnd($strType, $oFile, $bRemote, undef, undef, false, $iExpectedExitStatus);
} }
#################################################################################################################################### ####################################################################################################################################
@ -844,6 +948,7 @@ sub BackRestTestBackup_Restore
$bForce = defined($bForce) ? $bForce : false; $bForce = defined($bForce) ? $bForce : false;
&log(INFO, ' ' . ($bDelta ? 'delta ' : '') . ($bForce ? 'force ' : '') . &log(INFO, ' ' . ($bDelta ? 'delta ' : '') . ($bForce ? 'force ' : '') .
($strType ? "type '${strType}' " : '') .
(defined($oRemapHashRef) ? 'remap ' : '') . 'restore' . (defined($oRemapHashRef) ? 'remap ' : '') . 'restore' .
(defined($strComment) ? " (${strComment})" : '')); (defined($strComment) ? " (${strComment})" : ''));
@ -855,7 +960,9 @@ sub BackRestTestBackup_Restore
# Create the backup command # Create the backup command
BackRestTestCommon_Execute(BackRestTestCommon_CommandMainGet() . ' --config=' . BackRestTestCommon_DbPathGet() . BackRestTestCommon_Execute(BackRestTestCommon_CommandMainGet() . ' --config=' . BackRestTestCommon_DbPathGet() .
'/pg_backrest.conf' . (defined($bDelta) && $bDelta ? ' --delta' : '') . '/pg_backrest.conf' . (defined($bDelta) && $bDelta ? ' --delta' : '') .
(defined($bForce) && $bForce ? ' --force' : '') . " --stanza=${strStanza} restore", (defined($bForce) && $bForce ? ' --force' : '') .
(defined($strType) && $strType ne RECOVERY_TYPE_DEFAULT ? " --type=${strType}" : '') .
" --stanza=${strStanza} restore",
undef, undef, undef, $iExpectedExitStatus); undef, undef, undef, $iExpectedExitStatus);
} }
@ -1258,7 +1365,7 @@ sub BackRestTestBackup_Test
BackRestTestBackup_ManifestLinkCreate(\%oManifest, 'base', 'link-test', '/test'); BackRestTestBackup_ManifestLinkCreate(\%oManifest, 'base', 'link-test', '/test');
BackRestTestBackup_ManifestPathCreate(\%oManifest, 'base', 'path-test'); BackRestTestBackup_ManifestPathCreate(\%oManifest, 'base', 'path-test');
my $strFullBackup = BackRestTestBackup_Backup($strType, $strStanza, $bRemote, $oFile, \%oManifest); my $strFullBackup = BackRestTestBackup_BackupSynthetic($strType, $strStanza, $bRemote, $oFile, \%oManifest);
# Resume Full Backup # Resume Full Backup
#----------------------------------------------------------------------------------------------------------------------- #-----------------------------------------------------------------------------------------------------------------------
@ -1269,8 +1376,8 @@ sub BackRestTestBackup_Test
BackRestTestCommon_PathMove(BackRestTestCommon_BackupPathGet() . "/backup/${strStanza}/${strFullBackup}", BackRestTestCommon_PathMove(BackRestTestCommon_BackupPathGet() . "/backup/${strStanza}/${strFullBackup}",
$strTmpPath, $bRemote); $strTmpPath, $bRemote);
$strFullBackup = BackRestTestBackup_Backup($strType, $strStanza, $bRemote, $oFile, \%oManifest, $strFullBackup = BackRestTestBackup_BackupSynthetic($strType, $strStanza, $bRemote, $oFile, \%oManifest,
'resume', TEST_BACKUP_RESUME); 'resume', TEST_BACKUP_RESUME);
# Restore - tests various permissions, extra files/paths, missing files/paths # Restore - tests various permissions, extra files/paths, missing files/paths
#----------------------------------------------------------------------------------------------------------------------- #-----------------------------------------------------------------------------------------------------------------------
@ -1309,7 +1416,8 @@ sub BackRestTestBackup_Test
$bChecksum ? 'd85de07d6421d90aa9191c11c889bfde43680f0f' : undef, $lTime); $bChecksum ? 'd85de07d6421d90aa9191c11c889bfde43680f0f' : undef, $lTime);
my $strBackup = BackRestTestBackup_Backup($strType, $strStanza, $bRemote, $oFile, \%oManifest, 'add tablespace 1'); my $strBackup = BackRestTestBackup_BackupSynthetic($strType, $strStanza, $bRemote, $oFile, \%oManifest,
'add tablespace 1');
# Resume Incr Backup # Resume Incr Backup
#----------------------------------------------------------------------------------------------------------------------- #-----------------------------------------------------------------------------------------------------------------------
@ -1327,8 +1435,8 @@ sub BackRestTestBackup_Test
BackRestTestBackup_ManifestFileCreate(\%oManifest, "tablespace:2", 'tablespace2.txt', 'TBLSPC2', BackRestTestBackup_ManifestFileCreate(\%oManifest, "tablespace:2", 'tablespace2.txt', 'TBLSPC2',
$bChecksum ? 'dc7f76e43c46101b47acc55ae4d593a9e6983578' : undef, $lTime); $bChecksum ? 'dc7f76e43c46101b47acc55ae4d593a9e6983578' : undef, $lTime);
$strBackup = BackRestTestBackup_Backup($strType, $strStanza, $bRemote, $oFile, \%oManifest, $strBackup = BackRestTestBackup_BackupSynthetic($strType, $strStanza, $bRemote, $oFile, \%oManifest,
'resume and add tablespace 2', TEST_BACKUP_RESUME); 'resume and add tablespace 2', TEST_BACKUP_RESUME);
# Resume Diff Backup # Resume Diff Backup
#----------------------------------------------------------------------------------------------------------------------- #-----------------------------------------------------------------------------------------------------------------------
@ -1339,8 +1447,8 @@ sub BackRestTestBackup_Test
BackRestTestCommon_PathMove(BackRestTestCommon_BackupPathGet() . "/backup/${strStanza}/${strBackup}", BackRestTestCommon_PathMove(BackRestTestCommon_BackupPathGet() . "/backup/${strStanza}/${strBackup}",
$strTmpPath, $bRemote); $strTmpPath, $bRemote);
$strBackup = BackRestTestBackup_Backup($strType, $strStanza, $bRemote, $oFile, \%oManifest, $strBackup = BackRestTestBackup_BackupSynthetic($strType, $strStanza, $bRemote, $oFile, \%oManifest,
'resume - fail', TEST_BACKUP_NORESUME); 'resume - fail', TEST_BACKUP_NORESUME);
# Restore - # Restore -
#----------------------------------------------------------------------------------------------------------------------- #-----------------------------------------------------------------------------------------------------------------------
@ -1373,8 +1481,8 @@ sub BackRestTestBackup_Test
BackRestTestBackup_ManifestFileCreate(\%oManifest, "tablespace:2", 'tablespace2b.txt', 'TBLSPC2B', BackRestTestBackup_ManifestFileCreate(\%oManifest, "tablespace:2", 'tablespace2b.txt', 'TBLSPC2B',
$bChecksum ? 'e324463005236d83e6e54795dbddd20a74533bf3' : undef, $lTime); $bChecksum ? 'e324463005236d83e6e54795dbddd20a74533bf3' : undef, $lTime);
$strBackup = BackRestTestBackup_Backup($strType, $strStanza, $bRemote, $oFile, \%oManifest, $strBackup = BackRestTestBackup_BackupSynthetic($strType, $strStanza, $bRemote, $oFile, \%oManifest,
'add files and remove tablespace 2'); 'add files and remove tablespace 2');
# Incr Backup # Incr Backup
#----------------------------------------------------------------------------------------------------------------------- #-----------------------------------------------------------------------------------------------------------------------
@ -1384,26 +1492,27 @@ sub BackRestTestBackup_Test
BackRestTestBackup_ManifestFileCreate(\%oManifest, 'base', 'base/base1.txt', 'BASEUPDT', BackRestTestBackup_ManifestFileCreate(\%oManifest, 'base', 'base/base1.txt', 'BASEUPDT',
$bChecksum ? '9a53d532e27785e681766c98516a5e93f096a501' : undef, $lTime); $bChecksum ? '9a53d532e27785e681766c98516a5e93f096a501' : undef, $lTime);
$strBackup = BackRestTestBackup_Backup($strType, $strStanza, $bRemote, $oFile, \%oManifest, 'update files'); $strBackup = BackRestTestBackup_BackupSynthetic($strType, $strStanza, $bRemote, $oFile, \%oManifest, 'update files');
# Diff Backup # Diff Backup
#----------------------------------------------------------------------------------------------------------------------- #-----------------------------------------------------------------------------------------------------------------------
$strType = 'diff'; $strType = 'diff';
BackRestTestBackup_ManifestReference(\%oManifest, $strFullBackup, true); BackRestTestBackup_ManifestReference(\%oManifest, $strFullBackup, true);
$strBackup = BackRestTestBackup_Backup($strType, $strStanza, $bRemote, $oFile, \%oManifest, 'no updates'); $strBackup = BackRestTestBackup_BackupSynthetic($strType, $strStanza, $bRemote, $oFile, \%oManifest, 'no updates');
# Incr Backup # Incr Backup
#----------------------------------------------------------------------------------------------------------------------- #-----------------------------------------------------------------------------------------------------------------------
$strType = 'incr'; $strType = 'incr';
BackRestTestBackup_ManifestReference(\%oManifest, $strBackup); BackRestTestBackup_ManifestReference(\%oManifest, $strBackup);
BackRestTestBackup_BackupBegin($strType, $strStanza, $bRemote, "remove files - but won't affect manifest", true, 1); BackRestTestBackup_BackupBegin($strType, $strStanza, $bRemote, "remove files - but won't affect manifest",
true, true, 1);
BackRestTestCommon_ExecuteEnd(TEST_MANIFEST_BUILD); BackRestTestCommon_ExecuteEnd(TEST_MANIFEST_BUILD);
BackRestTestBackup_FileRemove(\%oManifest, 'base', 'base/base1.txt'); BackRestTestBackup_FileRemove(\%oManifest, 'base', 'base/base1.txt');
$strBackup = BackRestTestBackup_BackupEnd($strType, $oFile, $bRemote, undef, \%oManifest); $strBackup = BackRestTestBackup_BackupEnd($strType, $oFile, $bRemote, undef, \%oManifest, true);
# Diff Backup # Diff Backup
#----------------------------------------------------------------------------------------------------------------------- #-----------------------------------------------------------------------------------------------------------------------
@ -1417,12 +1526,12 @@ sub BackRestTestBackup_Test
BackRestTestBackup_ManifestFileCreate(\%oManifest, "tablespace:2", 'tablespace2c.txt', 'TBLSPC2C', BackRestTestBackup_ManifestFileCreate(\%oManifest, "tablespace:2", 'tablespace2c.txt', 'TBLSPC2C',
$bChecksum ? 'ad7df329ab97a1e7d35f1ff0351c079319121836' : undef, $lTime); $bChecksum ? 'ad7df329ab97a1e7d35f1ff0351c079319121836' : undef, $lTime);
BackRestTestBackup_BackupBegin($strType, $strStanza, $bRemote, "remove files during backup", true, 1); BackRestTestBackup_BackupBegin($strType, $strStanza, $bRemote, "remove files during backup", true, true, 1);
BackRestTestCommon_ExecuteEnd(TEST_MANIFEST_BUILD); BackRestTestCommon_ExecuteEnd(TEST_MANIFEST_BUILD);
BackRestTestBackup_ManifestFileRemove(\%oManifest, 'base', 'base/base2.txt', true); BackRestTestBackup_ManifestFileRemove(\%oManifest, 'base', 'base/base2.txt', true);
$strBackup = BackRestTestBackup_BackupEnd($strType, $oFile, $bRemote, undef, \%oManifest); $strBackup = BackRestTestBackup_BackupEnd($strType, $oFile, $bRemote, undef, \%oManifest, true);
# Full Backup # Full Backup
#----------------------------------------------------------------------------------------------------------------------- #-----------------------------------------------------------------------------------------------------------------------
@ -1432,7 +1541,7 @@ sub BackRestTestBackup_Test
BackRestTestBackup_ManifestFileCreate(\%oManifest, 'base', 'base/base1.txt', 'BASEUPDT2', BackRestTestBackup_ManifestFileCreate(\%oManifest, 'base', 'base/base1.txt', 'BASEUPDT2',
$bChecksum ? '7579ada0808d7f98087a0a586d0df9de009cdc33' : undef, $lTime); $bChecksum ? '7579ada0808d7f98087a0a586d0df9de009cdc33' : undef, $lTime);
$strFullBackup = BackRestTestBackup_Backup($strType, $strStanza, $bRemote, $oFile, \%oManifest); $strFullBackup = BackRestTestBackup_BackupSynthetic($strType, $strStanza, $bRemote, $oFile, \%oManifest);
# Diff Backup # Diff Backup
#----------------------------------------------------------------------------------------------------------------------- #-----------------------------------------------------------------------------------------------------------------------
@ -1442,7 +1551,7 @@ sub BackRestTestBackup_Test
BackRestTestBackup_ManifestFileCreate(\%oManifest, 'base', 'base/base2.txt', 'BASE2UPDT', BackRestTestBackup_ManifestFileCreate(\%oManifest, 'base', 'base/base2.txt', 'BASE2UPDT',
$bChecksum ? 'cafac3c59553f2cfde41ce2e62e7662295f108c0' : undef, $lTime); $bChecksum ? 'cafac3c59553f2cfde41ce2e62e7662295f108c0' : undef, $lTime);
$strBackup = BackRestTestBackup_Backup($strType, $strStanza, $bRemote, $oFile, \%oManifest, 'add files'); $strBackup = BackRestTestBackup_BackupSynthetic($strType, $strStanza, $bRemote, $oFile, \%oManifest, 'add files');
} }
} }
} }
@ -1455,12 +1564,6 @@ sub BackRestTestBackup_Test
} }
} }
#-------------------------------------------------------------------------------------------------------------------------------
# Test aborted
#
# Check the aborted backup functionality using synthetic data.
#-------------------------------------------------------------------------------------------------------------------------------
#------------------------------------------------------------------------------------------------------------------------------- #-------------------------------------------------------------------------------------------------------------------------------
# Test full # Test full
# #
@ -1482,6 +1585,15 @@ sub BackRestTestBackup_Test
if (!BackRestTestCommon_Run(++$iRun, if (!BackRestTestCommon_Run(++$iRun,
"rmt ${bRemote}, arc_async ${bArchiveAsync}")) {next} "rmt ${bRemote}, arc_async ${bArchiveAsync}")) {next}
# Create the file object
my $oFile = new BackRest::File
(
$strStanza,
BackRestTestCommon_BackupPathGet(),
$bRemote ? 'backup' : undef,
$bRemote ? $oRemote : undef
);
# Create the test directory # Create the test directory
if ($bCreate) if ($bCreate)
{ {
@ -1493,7 +1605,7 @@ sub BackRestTestBackup_Test
BackRestTestCommon_ConfigCreate('db', # local BackRestTestCommon_ConfigCreate('db', # local
$bRemote ? BACKUP : undef, # remote $bRemote ? BACKUP : undef, # remote
false, # compress false, # compress
false, # checksum true, # checksum
$bRemote ? undef : true, # hardlink $bRemote ? undef : true, # hardlink
$iThreadMax, # thread-max $iThreadMax, # thread-max
$bArchiveAsync, # archive-async $bArchiveAsync, # archive-async
@ -1505,54 +1617,82 @@ sub BackRestTestBackup_Test
BackRestTestCommon_ConfigCreate('backup', # local BackRestTestCommon_ConfigCreate('backup', # local
$bRemote ? DB : undef, # remote $bRemote ? DB : undef, # remote
false, # compress false, # compress
false, # checksum true, # checksum
true, # hardlink true, # hardlink
$iThreadMax, # thread-max $iThreadMax, # thread-max
undef, # archive-async undef, # archive-async
undef); # compress-async undef); # compress-async
} }
# Create the backup command my $bDelta = true;
my $strCommand = BackRestTestCommon_CommandMainGet() . ' --config=' . my $bForce = false;
($bRemote ? BackRestTestCommon_BackupPathGet() : BackRestTestCommon_DbPathGet()) . my $strType;
"/pg_backrest.conf --test --type=incr --stanza=${strStanza} backup";
# Run the full/incremental tests my $strFullMessage = 'full_backup';
for (my $iFull = 1; $iFull <= 1; $iFull++) my $strTimeMessage = 'time_pitr';
{
for (my $iIncr = 0; $iIncr <= 2; $iIncr++) # Full backup
{ #-----------------------------------------------------------------------------------------------------------------------
&log(INFO, ' ' . ($iIncr == 0 ? ('full ' . sprintf('%02d', $iFull)) : BackRestTestBackup_PgExecute("create table test (message text not null)");
(' incr ' . sprintf('%02d', $iIncr)))); BackRestTestBackup_PgExecute("insert into test values ('$strFullMessage')");
# Create tablespace my $strFullBackup = BackRestTestBackup_Backup('full', $strStanza, $bRemote, $oFile);
if ($iIncr == 0)
{
BackRestTestBackup_PgExecute("create tablespace ts1 location '" .
BackRestTestCommon_DbTablespacePathGet() . "/ts1'", true);
}
# Create a table in each backup to check references # Setup the time target
BackRestTestBackup_PgExecute("create table test_backup_${iIncr} (id int)", true); #-----------------------------------------------------------------------------------------------------------------------
BackRestTestBackup_PgExecute("update test set message = '$strTimeMessage'", false, false);
my $strTimeTarget = BackRestTestBackup_PgSelectOne("select to_char(current_timestamp, 'YYYY-MM-DD HH24:MI:SS')");
BackRestTestBackup_PgExecute("commit", true, false);
# Create a table to be dropped to test missing file code # Restore to full (restore type = none)
BackRestTestBackup_PgExecute('create table test_drop (id int)'); #-----------------------------------------------------------------------------------------------------------------------
$strType = RECOVERY_TYPE_DEFAULT;
BackRestTestCommon_ExecuteBegin($strCommand, $bRemote); BackRestTestBackup_ClusterStop();
if (BackRestTestCommon_ExecuteEnd(TEST_MANIFEST_BUILD)) BackRestTestBackup_Restore($oFile, $strFullBackup, $strStanza, $bRemote, undef, undef, $bDelta, $bForce,
{ $strType, undef, undef, undef, undef, undef,
BackRestTestBackup_PgExecute('drop table test_drop', true); 'restore to full');
BackRestTestCommon_ExecuteEnd(); BackRestTestBackup_ClusterStart();
} # BackRestTestBackup_ClusterStop();
else
{ # # Run the full/incremental tests
confess &log(ERROR, 'test point ' . TEST_MANIFEST_BUILD . ' was not found'); # for (my $iFull = 1; $iFull <= 1; $iFull++)
} # {
} #
} # for (my $iIncr = 0; $iIncr <= 2; $iIncr++)
# {
# &log(INFO, ' ' . ($iIncr == 0 ? ('full ' . sprintf('%02d', $iFull)) :
# (' incr ' . sprintf('%02d', $iIncr))));
#
# # Create tablespace
# if ($iIncr == 0)
# {
# BackRestTestBackup_PgExecute("create tablespace ts1 location '" .
# BackRestTestCommon_DbTablespacePathGet() . "/ts1'", true);
# }
#
# # Create a table in each backup to check references
# BackRestTestBackup_PgExecute("create table test_backup_${iIncr} (id int)", true);
#
# # Create a table to be dropped to test missing file code
# BackRestTestBackup_PgExecute('create table test_drop (id int)');
#
# BackRestTestCommon_ExecuteBegin($strCommand, $bRemote);
#
# if (BackRestTestCommon_ExecuteEnd(TEST_MANIFEST_BUILD))
# {
# BackRestTestBackup_PgExecute('drop table test_drop', true);
#
# BackRestTestCommon_ExecuteEnd();
# }
# else
# {
# confess &log(ERROR, 'test point ' . TEST_MANIFEST_BUILD . ' was not found');
# }
# }
# }
$bCreate = true; $bCreate = true;
} }