1
0
mirror of https://github.com/pgbackrest/pgbackrest.git synced 2024-12-14 10:13:05 +02:00
pgbackrest/bin/pg_backrest

230 lines
9.1 KiB
Perl
Executable File

#!/usr/bin/perl
####################################################################################################################################
# pgBackRest - Simple PostgreSQL Backup and Restore
####################################################################################################################################
####################################################################################################################################
# Perl includes
####################################################################################################################################
use strict;
use warnings FATAL => qw(all);
use Carp qw(confess);
# Convert die to confess to capture the stack trace
$SIG{__DIE__} = sub { Carp::confess @_ };
use File::Basename qw(dirname);
use Scalar::Util qw(blessed);
use lib dirname($0) . '/../lib';
use BackRest::Archive;
use BackRest::Backup;
use BackRest::Common::Exception;
use BackRest::Common::Lock;
use BackRest::Common::Log;
use BackRest::Config;
use BackRest::Expire;
use BackRest::File;
use BackRest::Info;
use BackRest::Protocol::RemoteMinion;
use BackRest::Protocol::ThreadGroup;
use BackRest::Restore;
####################################################################################################################################
# Operation constants
####################################################################################################################################
use constant OP_MAIN => 'Main';
use constant OP_MAIN_SAFE_EXIT => OP_MAIN . '::safeExit';
####################################################################################################################################
# safeExit
#
# Terminate all threads and SSH connections when the script is terminated.
####################################################################################################################################
sub safeExit
{
# Assign function parameters, defaults, and log debug info
my
(
$strOperation,
$iExitCode
) =
logDebugParam
(
OP_MAIN_SAFE_EXIT, \@_,
{name => 'iExitCode', required => false}
);
commandStop();
my $iTotal = threadGroupDestroy();
protocolDestroy();
if (defined($iExitCode))
{
exit $iExitCode;
}
&log(ERROR, "process terminated on signal or exception, ${iTotal} threads stopped");
}
$SIG{TERM} = \&safeExit;
$SIG{HUP} = \&safeExit;
$SIG{INT} = \&safeExit;
####################################################################################################################################
# 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
logLevelSet(OFF, OFF);
# Create the remote object
my $oRemote = new BackRest::Protocol::RemoteMinion
(
optionGet(OPTION_BUFFER_SIZE),
optionGet(OPTION_COMPRESS_LEVEL),
optionGet(OPTION_COMPRESS_LEVEL_NETWORK)
);
# Process remote requests
safeExit($oRemote->process());
}
# Set the log levels
logLevelSet(optionGet(OPTION_LOG_LEVEL_FILE), optionGet(OPTION_LOG_LEVEL_CONSOLE));
# Set test options
!optionGet(OPTION_TEST) or testSet(optionGet(OPTION_TEST), optionGet(OPTION_TEST_DELAY));
# Log the command start
commandStart();
################################################################################################################################
# Process archive commands
################################################################################################################################
if (commandTest(CMD_ARCHIVE_PUSH) || commandTest(CMD_ARCHIVE_GET))
{
safeExit(new BackRest::Archive()->process());
}
################################################################################################################################
# Process info command
################################################################################################################################
if (commandTest(CMD_INFO))
{
safeExit(new BackRest::Info()->process());
}
################################################################################################################################
# Acquire the command lock
################################################################################################################################
lockAcquire(commandGet());
################################################################################################################################
# Open the log file
################################################################################################################################
logFileSet(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
(
$oFile
)->process;
safeExit(0);
}
################################################################################################################################
# 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');
}
################################################################################################################################
# BACKUP
################################################################################################################################
if (commandTest(CMD_BACKUP))
{
new BackRest::Backup
(
$oFile
)->process();
commandSet(CMD_EXPIRE);
}
################################################################################################################################
# EXPIRE
################################################################################################################################
if (commandTest(CMD_EXPIRE))
{
new BackRest::Expire
(
$oFile
)->process();
}
# Release the command lock
lockRelease();
safeExit(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::Common::Exception'))
{
safeExit($oMessage->code());
}
safeExit();
confess $oMessage;
}