1
0
mirror of https://github.com/pgbackrest/pgbackrest.git synced 2026-05-22 10:15:16 +02:00
Files
pgbackrest/bin/pgbackrest
T
David Steele f54145c0cc Fixed timeout issues.
* Fixed an issue where local processes were not disconnecting when complete and could later timeout. (Reported by Todd Vernick.)
* Fixed an issue where the protocol layer could timeout while waiting for WAL segments to arrive in the archive. (Reported by Todd Vernick.)
2016-09-14 16:37:07 -05:00

256 lines
10 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);
use English '-no_match_vars';
# Convert die to confess to capture the stack trace
$SIG{__DIE__} = sub { Carp::confess @_ };
use File::Basename qw(dirname);
use lib dirname($0) . '/../lib';
use pgBackRest::Archive;
use pgBackRest::Common::Exception;
use pgBackRest::Common::Exit;
use pgBackRest::Common::Lock;
use pgBackRest::Common::Log;
use pgBackRest::Config::Config;
use pgBackRest::File;
use pgBackRest::Protocol::Common;
use pgBackRest::Protocol::Protocol;
####################################################################################################################################
# Run in eval block to catch errors
####################################################################################################################################
local $EVAL_ERROR = undef; eval
{
################################################################################################################################
# Load command line parameters and config
################################################################################################################################
my $bConfigResult = configLoad();
# Display help and version
if (commandTest(CMD_HELP) || commandTest(CMD_VERSION))
{
# Load module dynamically
require pgBackRest::Config::ConfigHelp;
pgBackRest::Config::ConfigHelp->import();
# Generate help and exit
configHelp($ARGV[1], $ARGV[2], commandTest(CMD_VERSION), $bConfigResult);
exitSafe(0);
}
# Set test options
if (optionTest(OPTION_TEST) && optionGet(OPTION_TEST))
{
testSet(optionGet(OPTION_TEST), optionGet(OPTION_TEST_DELAY), optionGet(OPTION_TEST_POINT, false));
}
################################################################################################################################
# Process remote commands
################################################################################################################################
if (commandTest(CMD_REMOTE))
{
# Set log levels
logLevelSet(OFF, REMOTE);
# Check that the repo path exists if this is a backup remote
if (optionTest(OPTION_TYPE, BACKUP) && !-e optionGet(OPTION_REPO_PATH))
{
confess &log(ERROR, 'repo-path \'' . optionGet(OPTION_REPO_PATH) . '\' does not exist', ERROR_PATH_MISSING);
}
# Load module dynamically
require pgBackRest::Protocol::RemoteMinion;
pgBackRest::Protocol::RemoteMinion->import();
# Create the remote object
my $oRemote = new pgBackRest::Protocol::RemoteMinion
(
optionGet(OPTION_COMMAND),
optionGet(OPTION_BUFFER_SIZE),
optionGet(OPTION_COMPRESS_LEVEL),
optionGet(OPTION_COMPRESS_LEVEL_NETWORK),
optionGet(OPTION_PROTOCOL_TIMEOUT)
);
# Acquire a remote lock
lockAcquire(optionGet(OPTION_COMMAND), undef, true, optionGet(OPTION_PROCESS, false));
# Process remote requests
exitSafe($oRemote->process());
}
################################################################################################################################
# Process local commands
################################################################################################################################
if (commandTest(CMD_LOCAL))
{
# Set log levels
logLevelSet(OFF, REMOTE);
# Load module dynamically
require pgBackRest::Protocol::LocalMinion;
pgBackRest::Protocol::LocalMinion->import();
# Create the local object
my $oLocal = new pgBackRest::Protocol::LocalMinion(optionGet(OPTION_COMMAND));
# Acquire a local lock
lockAcquire(optionGet(OPTION_COMMAND), undef, true, optionGet(OPTION_PROCESS, false));
# Process local requests
exitSafe($oLocal->process());
}
# Log the command start
commandStart();
# Check that the repo path exists
if (isRepoLocal() && !-e optionGet(OPTION_REPO_PATH))
{
confess &log(ERROR, 'repo-path \'' . optionGet(OPTION_REPO_PATH) . '\' does not exist', ERROR_PATH_MISSING);
}
################################################################################################################################
# Process archive commands
################################################################################################################################
if (commandTest(CMD_ARCHIVE_PUSH) || commandTest(CMD_ARCHIVE_GET))
{
if (!isDbLocal())
{
confess &log(ERROR, commandGet() . ' command must be run on the db host', ERROR_HOST_INVALID);
}
exitSafe(new pgBackRest::Archive()->process());
}
################################################################################################################################
# Process check command
################################################################################################################################
if (commandTest(CMD_CHECK))
{
exitSafe(new pgBackRest::Archive()->check());
}
################################################################################################################################
# Process start/stop commands
################################################################################################################################
if (commandTest(CMD_START))
{
lockStart();
exitSafe(0);
}
elsif (commandTest(CMD_STOP))
{
lockStop();
exitSafe(0);
}
################################################################################################################################
# Process info command
################################################################################################################################
if (commandTest(CMD_INFO))
{
# Load module dynamically
require pgBackRest::Info;
pgBackRest::Info->import();
exitSafe(new pgBackRest::Info()->process());
}
################################################################################################################################
# Acquire the command lock
################################################################################################################################
lockAcquire(commandGet());
################################################################################################################################
# Open the log file
################################################################################################################################
logFileSet(optionGet(OPTION_LOG_PATH) . '/' . optionGet(OPTION_STANZA) . '-' . lc(commandGet()));
################################################################################################################################
# RESTORE
################################################################################################################################
if (commandTest(CMD_RESTORE))
{
if (!isDbLocal())
{
confess &log(ERROR, 'restore command must be run on the db host', ERROR_HOST_INVALID);
}
# Load module dynamically
require pgBackRest::Restore;
pgBackRest::Restore->import();
# Do the restore
new pgBackRest::Restore()->process();
exitSafe(0);
}
else
{
############################################################################################################################
# Make sure backup and expire commands happen on the backup side
############################################################################################################################
if (!isRepoLocal())
{
confess &log(ERROR, 'backup and expire commands must be run on the backup host', ERROR_HOST_INVALID);
}
############################################################################################################################
# BACKUP
############################################################################################################################
if (commandTest(CMD_BACKUP))
{
# Load module dynamically
require pgBackRest::Backup;
pgBackRest::Backup->import();
new pgBackRest::Backup()->process();
commandSet(CMD_EXPIRE);
}
############################################################################################################################
# EXPIRE
############################################################################################################################
if (commandTest(CMD_EXPIRE))
{
# Load module dynamically
require pgBackRest::Expire;
pgBackRest::Expire->import();
new pgBackRest::Expire()->process();
}
}
lockRelease();
exitSafe(0);
# It shouldn't be possible to get here
&log(ASSERT, 'execution reached invalid location in ' . __FILE__ . ', line ' . __LINE__);
exit ERROR_ASSERT;
}
####################################################################################################################################
# Check for errors
####################################################################################################################################
or do
{
exitSafe(undef, $EVAL_ERROR);
};
# It shouldn't be possible to get here
&log(ASSERT, 'execution reached invalid location in ' . __FILE__ . ', line ' . __LINE__);
exit ERROR_ASSERT;