You've already forked pgbackrest
							
							
				mirror of
				https://github.com/pgbackrest/pgbackrest.git
				synced 2025-10-30 23:37:45 +02:00 
			
		
		
		
	* Major refactoring of the protocol layer to support this work. * Fixed protocol issue that was preventing ssh errors (especially connect) from being logged.
		
			
				
	
	
		
			258 lines
		
	
	
		
			10 KiB
		
	
	
	
		
			Perl
		
	
	
		
			Executable File
		
	
	
	
	
			
		
		
	
	
			258 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);
 | |
| 
 | |
| $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::RemoteMinion;
 | |
| use BackRest::Restore;
 | |
| use BackRest::ThreadGroup;
 | |
| use BackRest::Utility;
 | |
| 
 | |
| ####################################################################################################################################
 | |
| # 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::Protocol::RemoteMinion
 | |
|         (
 | |
|             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;
 | |
| }
 |