mirror of
https://github.com/pgbackrest/pgbackrest.git
synced 2024-12-14 10:13:05 +02:00
7248795b91
Replaced IPC::System::Simple and Net::OpenSSH with IPC::Open3 to eliminate CPAN dependency for multiple distros. Using open3 will also be used for local processes so it make sense to switch now.
331 lines
13 KiB
Perl
Executable File
331 lines
13 KiB
Perl
Executable File
#!/usr/bin/perl
|
|
####################################################################################################################################
|
|
# pg_backrest.pl - Simple Postgres Backup and Restore
|
|
####################################################################################################################################
|
|
|
|
####################################################################################################################################
|
|
# Perl includes
|
|
####################################################################################################################################
|
|
use strict;
|
|
use warnings FATAL => qw(all);
|
|
use Carp qw(confess);
|
|
|
|
$SIG{__DIE__} = sub { Carp::confess @_ };
|
|
|
|
use File::Basename qw(dirname);
|
|
use Scalar::Util qw(blessed);
|
|
|
|
use lib dirname($0) . '/../lib';
|
|
use BackRest::Backup;
|
|
use BackRest::Archive;
|
|
use BackRest::Config;
|
|
use BackRest::Db;
|
|
use BackRest::Exception;
|
|
use BackRest::File;
|
|
use BackRest::Info;
|
|
use BackRest::Lock;
|
|
use BackRest::Protocol qw(DB BACKUP NONE);
|
|
use BackRest::Remote;
|
|
use BackRest::Restore;
|
|
use BackRest::ThreadGroup;
|
|
use BackRest::Utility;
|
|
|
|
####################################################################################################################################
|
|
# Usage
|
|
####################################################################################################################################
|
|
|
|
=head1 NAME
|
|
|
|
pg_backrest.pl - Simple Postgres Backup and Restore
|
|
|
|
=head1 SYNOPSIS
|
|
|
|
pg_backrest.pl [options] [command]
|
|
|
|
Commands:
|
|
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:
|
|
--stanza stanza (cluster) to operate on
|
|
--config alternate path for pg_backrest.conf
|
|
(defaults to /etc/pg_backrest.conf)
|
|
--version display version and exit
|
|
--help display usage and exit
|
|
|
|
Backup Options:
|
|
--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 probably produce an inconsistent backup!
|
|
|
|
Restore Options:
|
|
--set backup set to restore (defaults to latest set).
|
|
--delta perform a delta restore.
|
|
--force force a restore and overwrite all existing files.
|
|
with --delta forces size/timestamp deltas.
|
|
|
|
Recovery Options:
|
|
--type type of recovery:
|
|
default - recover to end of archive log stream
|
|
name - restore point target
|
|
time - timestamp target
|
|
xid - transaction id target
|
|
preserve - preserve the existing recovery.conf
|
|
none - no recovery.conf generated
|
|
--target recovery target if type is name, time, or xid.
|
|
--target-exclusive stop just before the recovery target
|
|
(default is inclusive).
|
|
--target-resume do not pause after recovery (default is to pause).
|
|
--target-timeline recover into specified timeline
|
|
(default is current timeline).
|
|
|
|
Output Options:
|
|
--log-level-console console log level (defaults to warn):
|
|
off - No logging at all (not recommended)
|
|
error - Log only errors
|
|
warn - Log warnings and errors
|
|
info - Log info, warnings, and errors
|
|
debug - Log debug, info, warnings, and errors
|
|
trace - Log trace (very verbose debugging), debug,
|
|
info, warnings, and errors
|
|
--log-level-file file log level (defaults to info). Same options as
|
|
--log-level-console.
|
|
|
|
=cut
|
|
|
|
####################################################################################################################################
|
|
# SAFE_EXIT - terminate all threads and SSH connections when the script is terminated
|
|
####################################################################################################################################
|
|
sub safe_exit
|
|
{
|
|
my $iExitCode = shift;
|
|
|
|
&log(DEBUG, "safe exit called, terminating threads");
|
|
|
|
my $iTotal = threadGroupDestroy();
|
|
protocolDestroy();
|
|
|
|
if (defined($iExitCode))
|
|
{
|
|
exit $iExitCode;
|
|
}
|
|
|
|
&log(ERROR, "process terminated on signal or exception, ${iTotal} threads stopped");
|
|
}
|
|
|
|
$SIG{TERM} = \&safe_exit;
|
|
$SIG{HUP} = \&safe_exit;
|
|
$SIG{INT} = \&safe_exit;
|
|
|
|
####################################################################################################################################
|
|
# START EVAL BLOCK TO CATCH ERRORS AND STOP THREADS
|
|
####################################################################################################################################
|
|
eval
|
|
{
|
|
################################################################################################################################
|
|
# Load command line parameters and config
|
|
################################################################################################################################
|
|
configLoad();
|
|
|
|
################################################################################################################################
|
|
# Process remote commands
|
|
################################################################################################################################
|
|
if (commandTest(CMD_REMOTE))
|
|
{
|
|
# Turn all logging off
|
|
log_level_set(OFF, OFF);
|
|
|
|
# Create the remote object
|
|
my $oRemote = new BackRest::Remote
|
|
(
|
|
undef, # Host
|
|
undef, # User
|
|
'remote', # Command
|
|
optionGet(OPTION_BUFFER_SIZE),
|
|
optionGet(OPTION_COMPRESS_LEVEL),
|
|
optionGet(OPTION_COMPRESS_LEVEL_NETWORK)
|
|
);
|
|
|
|
# Process remote requests
|
|
safe_exit($oRemote->process());
|
|
}
|
|
|
|
# Set the log levels
|
|
log_level_set(optionGet(OPTION_LOG_LEVEL_FILE), optionGet(OPTION_LOG_LEVEL_CONSOLE));
|
|
|
|
# Set test options
|
|
!optionGet(OPTION_TEST) or test_set(optionGet(OPTION_TEST), optionGet(OPTION_TEST_DELAY));
|
|
|
|
################################################################################################################################
|
|
# Process archive commands
|
|
################################################################################################################################
|
|
if (commandTest(CMD_ARCHIVE_PUSH) || commandTest(CMD_ARCHIVE_GET))
|
|
{
|
|
safe_exit(new BackRest::Archive()->process());
|
|
}
|
|
|
|
################################################################################################################################
|
|
# Process info command
|
|
################################################################################################################################
|
|
if (commandTest(CMD_INFO))
|
|
{
|
|
safe_exit(new BackRest::Info()->info());
|
|
}
|
|
|
|
################################################################################################################################
|
|
# Acquire the command lock
|
|
################################################################################################################################
|
|
lockAcquire(commandGet());
|
|
|
|
################################################################################################################################
|
|
# Open the log file
|
|
################################################################################################################################
|
|
log_file_set(optionGet(OPTION_REPO_PATH) . '/log/' . optionGet(OPTION_STANZA) . '-' . lc(commandGet()));
|
|
|
|
################################################################################################################################
|
|
# Create the thread group that will be used for parallel processing
|
|
################################################################################################################################
|
|
threadGroupCreate();
|
|
|
|
################################################################################################################################
|
|
# Initialize the default file object
|
|
################################################################################################################################
|
|
my $oFile = new BackRest::File
|
|
(
|
|
optionGet(OPTION_STANZA),
|
|
optionRemoteTypeTest(BACKUP) ? optionGet(OPTION_REPO_REMOTE_PATH) : optionGet(OPTION_REPO_PATH),
|
|
optionRemoteType(),
|
|
protocolGet()
|
|
);
|
|
|
|
################################################################################################################################
|
|
# RESTORE
|
|
################################################################################################################################
|
|
if (commandTest(CMD_RESTORE))
|
|
{
|
|
if (optionRemoteTypeTest(DB))
|
|
{
|
|
confess &log(ASSERT, 'restore command must be performed locally on the db server');
|
|
}
|
|
|
|
# Do the restore
|
|
new BackRest::Restore
|
|
(
|
|
optionGet(OPTION_DB_PATH),
|
|
optionGet(OPTION_SET),
|
|
optionGet(OPTION_RESTORE_TABLESPACE_MAP, false),
|
|
$oFile,
|
|
optionGet(OPTION_THREAD_MAX),
|
|
optionGet(OPTION_DELTA),
|
|
optionGet(OPTION_FORCE),
|
|
optionGet(OPTION_TYPE),
|
|
optionGet(OPTION_TARGET, false),
|
|
optionGet(OPTION_TARGET_EXCLUSIVE, false),
|
|
optionGet(OPTION_TARGET_RESUME, false),
|
|
optionGet(OPTION_TARGET_TIMELINE, false),
|
|
optionGet(OPTION_RESTORE_RECOVERY_SETTING, false),
|
|
optionGet(OPTION_STANZA),
|
|
$0,
|
|
optionGet(OPTION_CONFIG)
|
|
)->restore;
|
|
|
|
safe_exit(0);
|
|
}
|
|
|
|
################################################################################################################################
|
|
# GET MORE CONFIG INFO
|
|
################################################################################################################################
|
|
# Make sure backup and expire command happen on the backup side
|
|
if (optionRemoteTypeTest(BACKUP))
|
|
{
|
|
confess &log(ERROR, 'backup and expire commands must run on the backup host');
|
|
}
|
|
|
|
# Initialize the db object
|
|
my $oDb;
|
|
|
|
if (commandTest(CMD_BACKUP))
|
|
{
|
|
$oDb = new BackRest::Db();
|
|
|
|
# Run backup_init - parameters required for backup and restore commands
|
|
backup_init
|
|
(
|
|
$oDb,
|
|
$oFile,
|
|
optionGet(OPTION_TYPE),
|
|
optionGet(OPTION_COMPRESS),
|
|
optionGet(OPTION_HARDLINK),
|
|
optionGet(OPTION_THREAD_MAX),
|
|
optionGet(OPTION_THREAD_TIMEOUT, false),
|
|
optionGet(OPTION_NO_START_STOP),
|
|
optionTest(OPTION_FORCE)
|
|
);
|
|
}
|
|
|
|
################################################################################################################################
|
|
# BACKUP
|
|
################################################################################################################################
|
|
if (commandTest(CMD_BACKUP))
|
|
{
|
|
backup(optionGet(OPTION_DB_PATH), optionGet(OPTION_START_FAST));
|
|
|
|
commandSet(CMD_EXPIRE);
|
|
}
|
|
|
|
################################################################################################################################
|
|
# EXPIRE
|
|
################################################################################################################################
|
|
if (commandTest(CMD_EXPIRE))
|
|
{
|
|
if (!defined($oDb))
|
|
{
|
|
backup_init
|
|
(
|
|
undef,
|
|
$oFile
|
|
);
|
|
}
|
|
|
|
backup_expire
|
|
(
|
|
$oFile->path_get(PATH_BACKUP_CLUSTER),
|
|
optionGet(OPTION_RETENTION_FULL, false),
|
|
optionGet(OPTION_RETENTION_DIFF, false),
|
|
optionGet(OPTION_RETENTION_ARCHIVE_TYPE, false),
|
|
optionGet(OPTION_RETENTION_ARCHIVE, false)
|
|
);
|
|
}
|
|
|
|
# Cleanup backup (should be removed when backup becomes an object)
|
|
backup_cleanup();
|
|
|
|
# Release the command lock
|
|
lockRelease();
|
|
|
|
safe_exit(0);
|
|
};
|
|
|
|
####################################################################################################################################
|
|
# CHECK FOR ERRORS AND STOP THREADS
|
|
####################################################################################################################################
|
|
if ($@)
|
|
{
|
|
my $oMessage = $@;
|
|
|
|
# If a backrest exception then return the code - don't confess
|
|
if (blessed($oMessage) && $oMessage->isa('BackRest::Exception'))
|
|
{
|
|
safe_exit($oMessage->code());
|
|
}
|
|
|
|
safe_exit();
|
|
confess $oMessage;
|
|
}
|