mirror of
https://github.com/pgbackrest/pgbackrest.git
synced 2024-12-14 10:13:05 +02:00
Working on restore options and integration with unit tests.
This commit is contained in:
parent
a96b83beb8
commit
9f8f33f957
@ -17,6 +17,7 @@ use Pod::Usage;
|
||||
use lib dirname($0) . '/../lib';
|
||||
use BackRest::Utility;
|
||||
use BackRest::Config;
|
||||
use BackRest::Remote;
|
||||
use BackRest::File;
|
||||
use BackRest::Backup;
|
||||
use BackRest::Restore;
|
||||
@ -38,6 +39,7 @@ pg_backrest.pl [options] [operation]
|
||||
archive-get retrieve an archive file from backup
|
||||
archive-push push an archive file to backup
|
||||
backup backup a cluster
|
||||
restore restore a cluster
|
||||
expire expire old backups (automatically run after backup)
|
||||
|
||||
General Options:
|
||||
@ -50,7 +52,14 @@ pg_backrest.pl [options] [operation]
|
||||
--type type of backup to perform (full, diff, incr)
|
||||
--no-start-stop do not call pg_start/stop_backup(). Postmaster should not be running.
|
||||
--force force backup when --no-start-stop passed and postmaster.pid exists.
|
||||
Use with extreme caution as this will produce an inconsistent backup!
|
||||
Use with extreme caution as this will probably produce an inconsistent backup!
|
||||
|
||||
Restore Options:
|
||||
--set backup set to restore (defaults to latest set).
|
||||
--remap remaps the base or a tablespace to another path.
|
||||
--thread # of threads to use for restore (defaults to 1).
|
||||
--force force restore when destination paths are not empty.
|
||||
Use with extreme caution as this will delete data in those paths!
|
||||
=cut
|
||||
|
||||
####################################################################################################################################
|
||||
@ -64,12 +73,12 @@ my $strRemote; # Defines which side is remote, DB or BACKUP
|
||||
####################################################################################################################################
|
||||
sub remote_get
|
||||
{
|
||||
if (!defined($oRemote) && $strRemote ne REMOTE_NONE)
|
||||
if (!defined($oRemote) && $strRemote ne NONE)
|
||||
{
|
||||
$oRemote = new BackRest::Remote
|
||||
(
|
||||
config_key_load($strRemote eq REMOTE_DB ? CONFIG_SECTION_STANZA : CONFIG_SECTION_BACKUP, CONFIG_KEY_HOST, true),
|
||||
config_key_load($strRemote eq REMOTE_DB ? CONFIG_SECTION_STANZA : CONFIG_SECTION_BACKUP, CONFIG_KEY_USER, true),
|
||||
config_key_load($strRemote eq DB ? CONFIG_SECTION_STANZA : CONFIG_SECTION_BACKUP, CONFIG_KEY_HOST, true),
|
||||
config_key_load($strRemote eq DB ? CONFIG_SECTION_STANZA : CONFIG_SECTION_BACKUP, CONFIG_KEY_USER, true),
|
||||
config_key_load(CONFIG_SECTION_COMMAND, CONFIG_KEY_REMOTE, true)
|
||||
);
|
||||
}
|
||||
@ -145,7 +154,7 @@ if (param_get(PARAM_HELP))
|
||||
# First check if backup is remote
|
||||
if (defined(config_key_load(CONFIG_SECTION_BACKUP, CONFIG_KEY_HOST)))
|
||||
{
|
||||
$strRemote = REMOTE_BACKUP;
|
||||
$strRemote = BACKUP;
|
||||
}
|
||||
# Else check if db is remote
|
||||
elsif (defined(config_key_load(CONFIG_SECTION_STANZA, CONFIG_KEY_HOST)))
|
||||
@ -156,11 +165,11 @@ elsif (defined(config_key_load(CONFIG_SECTION_STANZA, CONFIG_KEY_HOST)))
|
||||
confess &log(ERROR, 'db and backup cannot both be configured as remote');
|
||||
}
|
||||
|
||||
$strRemote = REMOTE_DB;
|
||||
$strRemote = DB;
|
||||
}
|
||||
else
|
||||
{
|
||||
$strRemote = REMOTE_NONE;
|
||||
$strRemote = NONE;
|
||||
}
|
||||
|
||||
####################################################################################################################################
|
||||
@ -169,7 +178,7 @@ else
|
||||
if (operation_get() eq OP_ARCHIVE_PUSH)
|
||||
{
|
||||
# Make sure the archive push operation happens on the db side
|
||||
if ($strRemote eq REMOTE_DB)
|
||||
if ($strRemote eq DB)
|
||||
{
|
||||
confess &log(ERROR, 'archive-push operation must run on the db host');
|
||||
}
|
||||
@ -219,7 +228,7 @@ if (operation_get() eq OP_ARCHIVE_PUSH)
|
||||
(
|
||||
param_get(PARAM_STANZA),
|
||||
config_key_load($strSection, CONFIG_KEY_PATH, true),
|
||||
$bArchiveLocal ? REMOTE_NONE : $strRemote,
|
||||
$bArchiveLocal ? NONE : $strRemote,
|
||||
$bArchiveLocal ? undef : remote_get()
|
||||
);
|
||||
|
||||
@ -428,22 +437,26 @@ my $oFile = new BackRest::File
|
||||
####################################################################################################################################
|
||||
if (operation_get() eq OP_RESTORE)
|
||||
{
|
||||
if ($strRemote eq REMOTE_DB)
|
||||
if ($strRemote eq DB)
|
||||
{
|
||||
confess &log(ASSERT, 'restore operation must be performed locally on the db server');
|
||||
}
|
||||
|
||||
# Open the log file
|
||||
log_file_set(config_key_load(CONFIG_SECTION_BACKUP, CONFIG_KEY_PATH, true) . '/log/' . param_get(PARAM_STANZA) . '-restore');
|
||||
log_file_set(config_key_load(CONFIG_SECTION_RESTORE, CONFIG_KEY_PATH, true) . '/log/' . param_get(PARAM_STANZA) . '-restore');
|
||||
|
||||
# Set the lock path
|
||||
my $strLockPath = config_key_load(CONFIG_SECTION_RESTORE, CONFIG_KEY_PATH, true) . '/lock/' .
|
||||
param_get(PARAM_STANZA) . '-' . operation_get() . '.lock';
|
||||
|
||||
# Do the restore
|
||||
new BackRest::Restore
|
||||
(
|
||||
config_key_load(CONFIG_SECTION_STANZA, CONFIG_KEY_PATH),
|
||||
undef,
|
||||
param_get(PARAM_SET),
|
||||
param_get(PARAM_REMAP),
|
||||
$oFile,
|
||||
4,
|
||||
param_get(PARAM_THREAD),
|
||||
param_get(PARAM_FORCE)
|
||||
)->restore;
|
||||
|
||||
@ -457,7 +470,7 @@ if (operation_get() eq OP_RESTORE)
|
||||
log_file_set(config_key_load(CONFIG_SECTION_BACKUP, CONFIG_KEY_PATH, true) . '/log/' . param_get(PARAM_STANZA));
|
||||
|
||||
# Make sure backup and expire operations happen on the backup side
|
||||
if ($strRemote eq REMOTE_BACKUP)
|
||||
if ($strRemote eq BACKUP)
|
||||
{
|
||||
confess &log(ERROR, 'backup and expire operations must run on the backup host');
|
||||
}
|
||||
|
@ -25,11 +25,11 @@ our @EXPORT = qw(config_load config_key_load operation_get operation_set param_g
|
||||
|
||||
BACKUP_TYPE_FULL BACKUP_TYPE_DIFF BACKUP_TYPE_INCR
|
||||
|
||||
PARAM_CONFIG PARAM_STANZA PARAM_TYPE PARAM_REMAP PARAM_NO_START_STOP PARAM_FORCE PARAM_VERSION PARAM_HELP
|
||||
PARAM_TEST PARAM_TEST_DELAY PARAM_TEST_NO_FORK
|
||||
PARAM_CONFIG PARAM_STANZA PARAM_TYPE PARAM_REMAP PARAM_SET PARAM_NO_START_STOP PARAM_THREAD PARAM_FORCE
|
||||
PARAM_VERSION PARAM_HELP PARAM_TEST PARAM_TEST_DELAY PARAM_TEST_NO_FORK
|
||||
|
||||
CONFIG_SECTION_COMMAND CONFIG_SECTION_COMMAND_OPTION CONFIG_SECTION_LOG CONFIG_SECTION_BACKUP
|
||||
CONFIG_SECTION_ARCHIVE CONFIG_SECTION_RETENTION CONFIG_SECTION_STANZA
|
||||
CONFIG_SECTION_RESTORE CONFIG_SECTION_ARCHIVE CONFIG_SECTION_RETENTION CONFIG_SECTION_STANZA
|
||||
|
||||
CONFIG_KEY_USER CONFIG_KEY_HOST CONFIG_KEY_PATH
|
||||
|
||||
@ -87,6 +87,8 @@ use constant
|
||||
PARAM_TYPE => 'type',
|
||||
PARAM_NO_START_STOP => 'no-start-stop',
|
||||
PARAM_REMAP => 'remap',
|
||||
PARAM_SET => 'set',
|
||||
PARAM_THREAD => 'thread',
|
||||
PARAM_FORCE => 'force',
|
||||
PARAM_VERSION => 'version',
|
||||
PARAM_HELP => 'help',
|
||||
@ -105,6 +107,7 @@ use constant
|
||||
CONFIG_SECTION_COMMAND_OPTION => 'command:option',
|
||||
CONFIG_SECTION_LOG => 'log',
|
||||
CONFIG_SECTION_BACKUP => 'backup',
|
||||
CONFIG_SECTION_RESTORE => 'restore',
|
||||
CONFIG_SECTION_ARCHIVE => 'archive',
|
||||
CONFIG_SECTION_RETENTION => 'retention',
|
||||
CONFIG_SECTION_STANZA => 'stanza',
|
||||
@ -163,8 +166,8 @@ sub config_load
|
||||
param_set(PARAM_TEST_DELAY, 5); # Seconds to delay after a test point (default is not enough for manual tests)
|
||||
|
||||
# Get command line parameters
|
||||
GetOptions (\%oParam, PARAM_CONFIG . '=s', PARAM_STANZA . '=s', PARAM_TYPE . '=s', PARAM_REMAP . '=s%', PARAM_NO_START_STOP,
|
||||
PARAM_FORCE, PARAM_VERSION, PARAM_HELP,
|
||||
GetOptions (\%oParam, PARAM_CONFIG . '=s', PARAM_STANZA . '=s', PARAM_TYPE . '=s', PARAM_REMAP . '=s%', PARAM_SET . '=s',
|
||||
PARAM_THREAD . '=s', PARAM_NO_START_STOP, PARAM_FORCE, PARAM_VERSION, PARAM_HELP,
|
||||
PARAM_TEST, PARAM_TEST_DELAY . '=s', PARAM_TEST_NO_FORK)
|
||||
or pod2usage(2);
|
||||
|
||||
@ -205,6 +208,13 @@ sub config_load
|
||||
}
|
||||
}
|
||||
|
||||
# Validate thread parameter
|
||||
if (defined(param_get(PARAM_THREAD)) && !(param_get(PARAM_THREAD) >= 1))
|
||||
{
|
||||
confess &log(ERROR, 'thread parameter should be >= 1');
|
||||
}
|
||||
|
||||
# Get configuration parameter and load it
|
||||
if (!defined(param_get(PARAM_CONFIG)))
|
||||
{
|
||||
param_set(PARAM_CONFIG, '/etc/pg_backrest.conf');
|
||||
@ -218,6 +228,17 @@ sub config_load
|
||||
confess 'a backup stanza must be specified';
|
||||
}
|
||||
|
||||
# If this is a restore, then try to default config
|
||||
if (!defined(config_key_load(CONFIG_SECTION_RESTORE, CONFIG_KEY_PATH)))
|
||||
{
|
||||
$oConfig{'global:restore'}{path} = config_key_load(CONFIG_SECTION_BACKUP, CONFIG_KEY_PATH);
|
||||
|
||||
if (!defined(config_key_load(CONFIG_SECTION_RESTORE, CONFIG_KEY_PATH)))
|
||||
{
|
||||
$oConfig{'global:restore'}{path} = config_key_load(CONFIG_SECTION_ARCHIVE, CONFIG_KEY_PATH);
|
||||
}
|
||||
}
|
||||
|
||||
# Set the log levels
|
||||
log_level_set(uc(config_key_load(CONFIG_SECTION_LOG, CONFIG_KEY_LEVEL_FILE, true, INFO)),
|
||||
uc(config_key_load(CONFIG_SECTION_LOG, CONFIG_KEY_LEVEL_CONSOLE, true, ERROR)));
|
||||
|
@ -35,8 +35,6 @@ our @EXPORT = qw(PATH_ABSOLUTE PATH_DB PATH_DB_ABSOLUTE PATH_BACKUP PATH_BACKUP_
|
||||
|
||||
PIPE_STDIN PIPE_STDOUT PIPE_STDERR
|
||||
|
||||
REMOTE_DB REMOTE_BACKUP REMOTE_NONE
|
||||
|
||||
OP_FILE_LIST OP_FILE_EXISTS OP_FILE_HASH OP_FILE_REMOVE OP_FILE_MANIFEST OP_FILE_COMPRESS
|
||||
OP_FILE_MOVE OP_FILE_COPY OP_FILE_COPY_OUT OP_FILE_COPY_IN OP_FILE_PATH_CREATE);
|
||||
|
||||
@ -80,16 +78,6 @@ use constant
|
||||
PIPE_STDERR => '<STDERR>'
|
||||
};
|
||||
|
||||
####################################################################################################################################
|
||||
# Remote Types
|
||||
####################################################################################################################################
|
||||
use constant
|
||||
{
|
||||
REMOTE_DB => PATH_DB,
|
||||
REMOTE_BACKUP => PATH_BACKUP,
|
||||
REMOTE_NONE => 'none'
|
||||
};
|
||||
|
||||
####################################################################################################################################
|
||||
# Operation constants
|
||||
####################################################################################################################################
|
||||
@ -142,12 +130,12 @@ sub new
|
||||
$self->{iThreadIdx} = $iThreadIdx;
|
||||
|
||||
# If remote is defined check parameters and open session
|
||||
if (defined($self->{strRemote}) && $self->{strRemote} ne REMOTE_NONE)
|
||||
if (defined($self->{strRemote}) && $self->{strRemote} ne NONE)
|
||||
{
|
||||
# Make sure remote is valid
|
||||
if ($self->{strRemote} ne REMOTE_DB && $self->{strRemote} ne REMOTE_BACKUP)
|
||||
if ($self->{strRemote} ne DB && $self->{strRemote} ne BACKUP)
|
||||
{
|
||||
confess &log(ASSERT, 'strRemote must be "' . REMOTE_DB . '" or "' . REMOTE_BACKUP .
|
||||
confess &log(ASSERT, 'strRemote must be "' . DB . '" or "' . BACKUP .
|
||||
"\", $self->{strRemote} was passed");
|
||||
}
|
||||
|
||||
|
@ -19,6 +19,19 @@ use BackRest::Exception;
|
||||
use BackRest::Utility;
|
||||
use BackRest::ProcessAsync;
|
||||
|
||||
use Exporter qw(import);
|
||||
our @EXPORT = qw(DB BACKUP NONE);
|
||||
|
||||
####################################################################################################################################
|
||||
# DB/BACKUP Constants
|
||||
####################################################################################################################################
|
||||
use constant
|
||||
{
|
||||
DB => 'db',
|
||||
BACKUP => 'backup',
|
||||
NONE => 'none'
|
||||
};
|
||||
|
||||
####################################################################################################################################
|
||||
# Remote xfer default block size constant
|
||||
####################################################################################################################################
|
||||
|
@ -38,7 +38,7 @@ sub new
|
||||
# Initialize variables
|
||||
$self->{strDbClusterPath} = $strDbClusterPath;
|
||||
$self->{oFile} = $oFile;
|
||||
$self->{thread_total} = $iThreadTotal;
|
||||
$self->{thread_total} = defined($iThreadTotal) ? $iThreadTotal : 1;
|
||||
$self->{bForce} = $bForce;
|
||||
$self->{oRemapRef} = $oRemapRef;
|
||||
|
||||
@ -292,6 +292,9 @@ sub restore
|
||||
confess &log(ERROR, 'unable to restore while Postgres is running');
|
||||
}
|
||||
|
||||
# Log the backup set to restore
|
||||
&log(INFO, "Restoring backup set " . $self->{strBackupPath});
|
||||
|
||||
# Make sure the backup path is valid and load the manifest
|
||||
my %oManifest;
|
||||
$self->manifest_load(\%oManifest);
|
||||
|
@ -809,7 +809,7 @@ sub BackRestTestBackup_Test
|
||||
}
|
||||
|
||||
BackRestTestCommon_ConfigCreate('db',
|
||||
($bRemote ? REMOTE_BACKUP : undef),
|
||||
($bRemote ? BACKUP : undef),
|
||||
$bCompress,
|
||||
$bChecksum, # checksum
|
||||
undef, # hardlink
|
||||
@ -938,7 +938,7 @@ sub BackRestTestBackup_Test
|
||||
}
|
||||
|
||||
BackRestTestCommon_ConfigCreate('db', # local
|
||||
($bRemote ? REMOTE_BACKUP : undef), # remote
|
||||
($bRemote ? BACKUP : undef), # remote
|
||||
$bCompress, # compress
|
||||
$bChecksum, # checksum
|
||||
undef, # hardlink
|
||||
@ -1100,11 +1100,11 @@ sub BackRestTestBackup_Test
|
||||
|
||||
# Create db config
|
||||
BackRestTestCommon_ConfigCreate('db', # local
|
||||
$bRemote ? REMOTE_BACKUP : undef, # remote
|
||||
$bRemote ? BACKUP : undef, # remote
|
||||
$bCompress, # compress
|
||||
$bChecksum, # checksum
|
||||
$bRemote ? undef : $bHardlink, # hardlink
|
||||
$bRemote ? undef : $iThreadMax, # thread-max
|
||||
$iThreadMax, # thread-max
|
||||
undef, # archive-async
|
||||
undef); # compress-async
|
||||
|
||||
@ -1112,7 +1112,7 @@ sub BackRestTestBackup_Test
|
||||
if ($bRemote)
|
||||
{
|
||||
BackRestTestCommon_ConfigCreate('backup', # local
|
||||
$bRemote ? REMOTE_DB : undef, # remote
|
||||
$bRemote ? DB : undef, # remote
|
||||
$bCompress, # compress
|
||||
$bChecksum, # checksum
|
||||
$bHardlink, # hardlink
|
||||
@ -1390,11 +1390,11 @@ sub BackRestTestBackup_Test
|
||||
|
||||
# Create db config
|
||||
BackRestTestCommon_ConfigCreate('db', # local
|
||||
$bRemote ? REMOTE_BACKUP : undef, # remote
|
||||
$bRemote ? BACKUP : undef, # remote
|
||||
false, # compress
|
||||
false, # checksum
|
||||
$bRemote ? undef : true, # hardlink
|
||||
$bRemote ? undef : $iThreadMax, # thread-max
|
||||
$iThreadMax, # thread-max
|
||||
$bArchiveAsync, # archive-async
|
||||
undef); # compress-async
|
||||
|
||||
@ -1402,7 +1402,7 @@ sub BackRestTestBackup_Test
|
||||
if ($bRemote)
|
||||
{
|
||||
BackRestTestCommon_ConfigCreate('backup', # local
|
||||
$bRemote ? REMOTE_DB : undef, # remote
|
||||
$bRemote ? DB : undef, # remote
|
||||
false, # compress
|
||||
false, # checksum
|
||||
true, # hardlink
|
||||
|
@ -20,6 +20,7 @@ use IO::Select;
|
||||
|
||||
use lib dirname($0) . '/../lib';
|
||||
use BackRest::Utility;
|
||||
use BackRest::Remote;
|
||||
use BackRest::File;
|
||||
|
||||
use Exporter qw(import);
|
||||
@ -387,12 +388,12 @@ sub BackRestTestCommon_ConfigCreate
|
||||
|
||||
$oParamHash{'global:command'}{'psql'} = $strCommonCommandPsql;
|
||||
|
||||
if (defined($strRemote) && $strRemote eq REMOTE_BACKUP)
|
||||
if (defined($strRemote) && $strRemote eq BACKUP)
|
||||
{
|
||||
$oParamHash{'global:backup'}{'host'} = $strCommonHost;
|
||||
$oParamHash{'global:backup'}{'user'} = $strCommonUserBackRest;
|
||||
}
|
||||
elsif (defined($strRemote) && $strRemote eq REMOTE_DB)
|
||||
elsif (defined($strRemote) && $strRemote eq DB)
|
||||
{
|
||||
$oParamHash{$strCommonStanza}{'host'} = $strCommonHost;
|
||||
$oParamHash{$strCommonStanza}{'user'} = $strCommonUser;
|
||||
@ -401,19 +402,21 @@ sub BackRestTestCommon_ConfigCreate
|
||||
$oParamHash{'global:log'}{'level-console'} = 'error';
|
||||
$oParamHash{'global:log'}{'level-file'} = 'trace';
|
||||
|
||||
if (defined($bHardlink) && !$bHardlink)
|
||||
{
|
||||
$oParamHash{'global:backup'}{'hardlink'} = 'n';
|
||||
}
|
||||
|
||||
if ($strLocal eq REMOTE_BACKUP)
|
||||
if ($strLocal eq BACKUP)
|
||||
{
|
||||
}
|
||||
elsif ($strLocal eq REMOTE_DB)
|
||||
elsif ($strLocal eq DB)
|
||||
{
|
||||
if (defined($strRemote))
|
||||
{
|
||||
$oParamHash{'global:log'}{'level-console'} = 'trace';
|
||||
|
||||
if (!$bArchiveLocal)
|
||||
{
|
||||
$oParamHash{'global:restore'}{path} = BackRestTestCommon_ArchivePathGet();
|
||||
}
|
||||
|
||||
$oParamHash{'global:restore'}{'thread-max'} = $iThreadMax;
|
||||
}
|
||||
|
||||
if ($bArchiveLocal)
|
||||
@ -431,9 +434,15 @@ sub BackRestTestCommon_ConfigCreate
|
||||
confess "invalid local type ${strLocal}";
|
||||
}
|
||||
|
||||
if (($strLocal eq REMOTE_BACKUP) || ($strLocal eq REMOTE_DB && !defined($strRemote)))
|
||||
if (($strLocal eq BACKUP) || ($strLocal eq DB && !defined($strRemote)))
|
||||
{
|
||||
$oParamHash{'db:command:option'}{'psql'} = "--port=${iCommonDbPort}";
|
||||
$oParamHash{'global:backup'}{'thread-max'} = $iThreadMax;
|
||||
|
||||
if (defined($bHardlink) && !$bHardlink)
|
||||
{
|
||||
$oParamHash{'global:backup'}{'hardlink'} = 'n';
|
||||
}
|
||||
}
|
||||
|
||||
if (defined($bCompress) && !$bCompress)
|
||||
@ -449,11 +458,6 @@ sub BackRestTestCommon_ConfigCreate
|
||||
$oParamHash{$strCommonStanza}{'path'} = $strCommonDbCommonPath;
|
||||
$oParamHash{'global:backup'}{'path'} = $strCommonBackupPath;
|
||||
|
||||
if (defined($iThreadMax))
|
||||
{
|
||||
$oParamHash{'global:backup'}{'thread-max'} = $iThreadMax;
|
||||
}
|
||||
|
||||
# Write out the configuration file
|
||||
my $strFile = BackRestTestCommon_TestPathGet() . '/pg_backrest.conf';
|
||||
ini_save($strFile, \%oParamHash);
|
||||
|
Loading…
Reference in New Issue
Block a user