1
0
mirror of https://github.com/pgbackrest/pgbackrest.git synced 2025-03-03 14:52:21 +02:00

Working on recovery options.

This commit is contained in:
David Steele 2015-01-25 17:27:46 -05:00
parent 6db49e1083
commit eeffd62a12
4 changed files with 191 additions and 53 deletions

View File

@ -394,6 +394,21 @@ Number of backups worth of archive log to keep. If not defined, then `full-rete
required: n
example: archive-retention=2
```
### restore section
?????
### restore:option section
`Archive Recovery` and `Standby Server` `restore.conf` options can be specified here. See http://www.postgresql.org/docs/X.X/static/recovery-config.html for details on `restore.conf` options (replace `X.X` with your database version).
Note: `restore_command` will automatically be generated unless overridden in this section. Be careful about specifying your own `restore_command` as PgBackRest is designed to handle this for you.
'Target Recovery` options are specified on the command-line since they end to change from restore to restore (or not be needed at all in the case of a standby server).
Since PgBackRest does not start PostgreSQL after writing the recovery.conf file, it is always possible to edit/check the file before manually restarting.
### stanza sections
A stanza defines a backup for a specific database. The stanza section must define the base database path and host/user if the database is remote. Also, any global configuration sections can be overridden to define stanza-specific settings.

View File

@ -59,6 +59,14 @@ pg_backrest.pl [options] [operation]
--delta perform a delta restore using checksums when available.
--force force a restore and overwrite all existing files.
with --delta forces size/timestamp delta even if checksums are present.
Recovery Options:
--type type of restore (name, time, xid, preserve, none).
--target target to restore if name, time, or xid specified for type.
--target-exclusive stop just before the recovery target (default is inclusive).
--target-resume do not pause after recovery to target.
--target-timeline recover into the specified timeline.
=cut
####################################################################################################################################

View File

@ -13,6 +13,7 @@ use File::Basename;
use Getopt::Long;
use lib dirname($0) . '/../lib';
use BackRest::Exception;
use BackRest::Utility;
use Exporter qw(import);
@ -79,24 +80,42 @@ use constant
BACKUP_TYPE_INCR => 'incr'
};
####################################################################################################################################
# RESTORE Type Constants
####################################################################################################################################
use constant
{
RESTORE_TYPE_NAME => 'name',
RESTORE_TYPE_TIME => 'time',
RESTORE_TYPE_XID => 'xid',
RESTORE_TYPE_PRESERVE => 'preserve',
RESTORE_TYPE_NONE => 'none',
RESTORE_TYPE_DEFAULT => 'default'
};
####################################################################################################################################
# Parameter constants
####################################################################################################################################
use constant
{
PARAM_CONFIG => 'config',
PARAM_STANZA => 'stanza',
PARAM_TYPE => 'type',
PARAM_NO_START_STOP => 'no-start-stop',
PARAM_DELTA => 'delta',
PARAM_SET => 'set',
PARAM_FORCE => 'force',
PARAM_VERSION => 'version',
PARAM_HELP => 'help',
PARAM_CONFIG => 'config',
PARAM_STANZA => 'stanza',
PARAM_TYPE => 'type',
PARAM_NO_START_STOP => 'no-start-stop',
PARAM_DELTA => 'delta',
PARAM_SET => 'set',
PARAM_FORCE => 'force',
PARAM_VERSION => 'version',
PARAM_HELP => 'help',
PARAM_TEST => 'test',
PARAM_TEST_DELAY => 'test-delay',
PARAM_TEST_NO_FORK => 'no-fork'
PARAM_TARGET => 'target',
PARAM_TARGET_EXCLUSIVE => 'target-exclusive',
PARAM_TARGET_RESUME => 'target-resume',
PARAM_TARGET_TIMELINE => 'target-timeline',
PARAM_TEST => 'test',
PARAM_TEST_DELAY => 'test-delay',
PARAM_TEST_NO_FORK => 'no-fork'
};
####################################################################################################################################
@ -109,6 +128,7 @@ use constant
CONFIG_SECTION_LOG => 'log',
CONFIG_SECTION_BACKUP => 'backup',
CONFIG_SECTION_RESTORE => 'restore',
CONFIG_SECTION_RESTORE_OPTION => 'restore:option',
CONFIG_SECTION_TABLESPACE_MAP => 'tablespace:map',
CONFIG_SECTION_ARCHIVE => 'archive',
CONFIG_SECTION_RETENTION => 'retention',
@ -169,7 +189,8 @@ sub config_load
# Get command line parameters
GetOptions (\%oParam, PARAM_CONFIG . '=s', PARAM_STANZA . '=s', PARAM_TYPE . '=s', PARAM_DELTA, PARAM_SET . '=s',
PARAM_NO_START_STOP, PARAM_FORCE, PARAM_VERSION, PARAM_HELP,
PARAM_NO_START_STOP, PARAM_FORCE, PARAM_TARGET . '=s', PARAM_TARGET_EXCLUSIVE, PARAM_TARGET_RESUME,
PARAM_TARGET_TIMELINE . '=s', PARAM_VERSION, PARAM_HELP,
PARAM_TEST, PARAM_TEST_DELAY . '=s', PARAM_TEST_NO_FORK)
or pod2usage(2);
@ -193,40 +214,22 @@ sub config_load
# Get and validate the operation
$strOperation = $ARGV[0];
if (!defined($strOperation))
{
confess &log(ERROR, 'operation is not defined');
}
if ($strOperation ne OP_ARCHIVE_GET &&
$strOperation ne OP_ARCHIVE_PUSH &&
$strOperation ne OP_BACKUP &&
$strOperation ne OP_RESTORE &&
$strOperation ne OP_EXPIRE)
{
confess &log(ERROR, "invalid operation ${strOperation}");
}
# Type should only be specified for backups
if (defined(param_get(PARAM_TYPE)) && $strOperation ne OP_BACKUP)
{
confess &log(ERROR, 'type can only be specified for the backup operation')
}
param_valid();
# Set the backup type
if ($strOperation ne OP_BACKUP)
{
if (!defined(param_get(PARAM_TYPE)))
{
param_set(PARAM_TYPE, BACKUP_TYPE_INCR);
}
elsif (param_get(PARAM_TYPE) ne BACKUP_TYPE_FULL && param_get(PARAM_TYPE) ne BACKUP_TYPE_DIFF &&
param_get(PARAM_TYPE) ne BACKUP_TYPE_INCR)
{
confess &log(ERROR, 'backup type must be full, diff (differential), incr (incremental)');
}
}
# if ($strOperation ne OP_BACKUP)
# {
# if (!defined(param_get(PARAM_TYPE)))
# {
# param_set(PARAM_TYPE, BACKUP_TYPE_INCR);
# }
# elsif (param_get(PARAM_TYPE) ne BACKUP_TYPE_FULL && param_get(PARAM_TYPE) ne BACKUP_TYPE_DIFF &&
# param_get(PARAM_TYPE) ne BACKUP_TYPE_INCR)
# {
# confess &log(ERROR, 'backup type must be full, diff (differential), incr (incremental)');
# }
# }
# # Validate thread parameter
# if (defined(param_get(PARAM_THREAD)) && !(param_get(PARAM_THREAD) >= 1))
@ -242,12 +245,6 @@ sub config_load
ini_load(param_get(PARAM_CONFIG), \%oConfig);
# Load and check the cluster
if (!defined(param_get(PARAM_STANZA)))
{
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)))
{
@ -338,6 +335,111 @@ sub config_key_load
return $strValue;
}
####################################################################################################################################
# PARAM_VALID
#
# Make sure the command-line parameters are valid.
####################################################################################################################################
sub param_valid
{
# Check the stanza
if (!defined(param_get(PARAM_STANZA)))
{
confess 'a backup stanza must be specified';
}
# Check that the operation is present and valid
if (!defined($strOperation))
{
confess &log(ERROR, "operation must be specified", ERROR_PARAM);
}
if ($strOperation ne OP_ARCHIVE_GET &&
$strOperation ne OP_ARCHIVE_PUSH &&
$strOperation ne OP_BACKUP &&
$strOperation ne OP_RESTORE &&
$strOperation ne OP_EXPIRE)
{
confess &log(ERROR, "invalid operation ${strOperation}");
}
# Check type param
my $strParam = PARAM_TYPE;
my $strType = param_get($strParam);
# Type is only valid for backup and restore operations
if (operation_test(OP_BACKUP) || operation_test(OP_RESTORE))
{
# Check types for backup
if (operation_test(OP_BACKUP))
{
# If type is not defined set to incr
if (!defined($strType))
{
$strType = BACKUP_TYPE_INCR;
}
# Check that type is in valid list
if (!($strType eq BACKUP_TYPE_FULL || $strType eq BACKUP_TYPE_DIFF || $strType eq BACKUP_TYPE_INCR))
{
confess &log(ERROR, "invalid type '${strType}' for ${strOperation}, must be: '" . BACKUP_TYPE_FULL . "', '" .
BACKUP_TYPE_DIFF . "', '" . BACKUP_TYPE_INCR . "'", ERROR_PARAM);
}
}
# Check types for restore
elsif (operation_test(OP_RESTORE))
{
# If type is not defined set to default
if (!defined($strType))
{
$strType = RESTORE_TYPE_DEFAULT;
}
if (!($strType eq RESTORE_TYPE_NAME || $strType eq RESTORE_TYPE_TIME || $strType eq RESTORE_TYPE_XID ||
$strType eq RESTORE_TYPE_PRESERVE || $strType eq RESTORE_TYPE_NONE || $strType eq RESTORE_TYPE_DEFAULT))
{
confess &log(ERROR, "invalid type '${strType}' for ${strOperation}, must be: '" . RESTORE_TYPE_NAME .
"', '" . RESTORE_TYPE_TIME . "', '" . RESTORE_TYPE_XID . "', '" . RESTORE_TYPE_PRESERVE .
"', '" . RESTORE_TYPE_NONE . "', '" . RESTORE_TYPE_DEFAULT . "'", ERROR_PARAM);
}
}
}
else
{
if (defined($strType))
{
confess &log(ERROR, PARAM_TYPE . ' is only valid for '. OP_BACKUP . ' and ' . OP_RESTORE . ' operations', ERROR_PARAM);
}
}
# Check target param
$strParam = PARAM_TARGET;
my $strTarget = param_get($strParam);
my $strTargetMessage = 'for ' . OP_RESTORE . " operations where type is '" . RESTORE_TYPE_NAME .
"', '" . RESTORE_TYPE_TIME . "', or '" . RESTORE_TYPE_XID . "'";
if (operation_test(OP_RESTORE) &&
($strType eq RESTORE_TYPE_NAME || $strType eq RESTORE_TYPE_TIME || $strType eq RESTORE_TYPE_XID))
{
if (!defined($strTarget))
{
confess &log(ERROR, PARAM_TARGET . ' is required ' . $strTargetMessage, ERROR_PARAM);
}
}
elsif (defined($strTarget))
{
confess &log(ERROR, PARAM_TARGET . ' is only required ' . $strTargetMessage, ERROR_PARAM);
}
# Check target-exclusive, target-resume, target-timeline parameters
if ((defined(PARAM_TARGET_EXCLUSIVE) || defined(PARAM_TARGET_RESUME) || defined(PARAM_TARGET_TIMELINE)) && !defined($strTarget))
{
confess &log(ERROR, PARAM_TARGET_EXCLUSIVE . ', ' . PARAM_TARGET_RESUME . ', and ' . PARAM_TARGET_TIMELINE .
' are only valid when target is specified');
}
}
####################################################################################################################################
# OPERATION_GET
#
@ -348,6 +450,18 @@ sub operation_get
return $strOperation;
}
####################################################################################################################################
# OPERATION_TEST
#
# Test the current operation.
####################################################################################################################################
sub operation_test
{
my $strOperationTest = shift;
return $strOperationTest eq $strOperation;
}
####################################################################################################################################
# OPERATION_SET
#

View File

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