diff --git a/pg_backrest.pl b/pg_backrest.pl index 91623dbcc..029482eba 100755 --- a/pg_backrest.pl +++ b/pg_backrest.pl @@ -12,6 +12,7 @@ use lib dirname($0); use pg_backrest_utility; use pg_backrest_file; use pg_backrest_backup; +use pg_backrest_db; # Command line parameters my $strConfigFile; @@ -148,6 +149,7 @@ if ($strOperation eq "archive-push") backup_init ( + undef, $oFile ); @@ -193,9 +195,17 @@ my $oFile = pg_backrest_file->new strCommandPsql => config_load("command", "psql") ); +my $oDb = pg_backrest_db->new +( + strDbUser => config_load("stanza", "user"), + strDbHost => config_load("stanza", "host"), + strCommandPsql => config_load("command", "psql") +); + # Run backup_init - parameters required for backup and restore operations backup_init ( + $oDb, $oFile, $strType, $bHardLink, diff --git a/pg_backrest_backup.pm b/pg_backrest_backup.pm index 63baf5301..58ed03059 100644 --- a/pg_backrest_backup.pm +++ b/pg_backrest_backup.pm @@ -16,11 +16,13 @@ use Scalar::Util qw(looks_like_number); use lib dirname($0); use pg_backrest_utility; use pg_backrest_file; +use pg_backrest_db; use Exporter qw(import); our @EXPORT = qw(backup_init archive_push backup backup_expire); +my $oDb; my $oFile; my $strType = "incremental"; # Type of backup: full, differential (diff), incremental (incr) my $bHardLink; @@ -31,11 +33,13 @@ my $bNoChecksum; #################################################################################################################################### sub backup_init { + my $oDbParam = shift; my $oFileParam = shift; my $strTypeParam = shift; my $bHardLinkParam = shift; my $bNoChecksumParam = shift; + $oDb = $oDbParam; $oFile = $oFileParam; $strType = $strTypeParam; $bHardLink = $bHardLinkParam; @@ -151,7 +155,7 @@ sub tablespace_map_get { my $strCommandPsql = shift; - my %oTablespaceMap = data_hash_build("oid\tname\n" . $oFile->psql_execute( + my %oTablespaceMap = data_hash_build("oid\tname\n" . $oDb->psql_execute( "copy (select oid, spcname from pg_tablespace) to stdout"), "\t"); return %oTablespaceMap; @@ -563,7 +567,7 @@ sub backup my $strLabel = $strBackupPath; ${oBackupManifest}{common}{backup}{label} = $strLabel; - my $strArchiveStart = trim($oFile->psql_execute( + my $strArchiveStart = trim($oDb->psql_execute( "set client_min_messages = 'warning';" . "copy (select pg_xlogfile_name(xlog) from pg_start_backup('${strLabel}') as xlog) to stdout")); @@ -582,7 +586,7 @@ sub backup backup_file($strBackupPath, $strDbClusterPath, \%oBackupManifest); # Stop backup - my $strArchiveStop = trim($oFile->psql_execute( + my $strArchiveStop = trim($oDb->psql_execute( "set client_min_messages = 'warning';" . "copy (select pg_xlogfile_name(xlog) from pg_stop_backup() as xlog) to stdout")); diff --git a/pg_backrest_db.pm b/pg_backrest_db.pm new file mode 100644 index 000000000..6ec426b71 --- /dev/null +++ b/pg_backrest_db.pm @@ -0,0 +1,87 @@ +#################################################################################################################################### +# FILE MODULE +#################################################################################################################################### +package pg_backrest_db; + +use Moose; +use strict; +use warnings; +use Carp; +use Net::OpenSSH; +use File::Basename; +use IPC::System::Simple qw(capture); + +use lib dirname($0); +use pg_backrest_utility; + +#use Exporter qw(import); +#our @EXPORT = qw(PATH_DB PATH_DB_ABSOLUTE PATH_BACKUP PATH_BACKUP_ABSOLUTE PATH_BACKUP_CLUSTER PATH_BACKUP_TMP PATH_BACKUP_ARCHIVE); + +# Command strings +has strCommandPsql => (is => 'bare'); # PSQL command + +# Module variables +has strDbUser => (is => 'ro'); # Database user +has strDbHost => (is => 'ro'); # Database host +has oDbSSH => (is => 'bare'); # Database SSH object + +sub BUILD +{ + my $self = shift; + + # Connect SSH object if db host is defined + if (defined($self->{strDbHost})) + { + &log(INFO, "connecting to database ssh host $self->{strDbHost}"); + + # !!! This could be improved by redirecting stderr to a file to get a better error message + $self->{oDbSSH} = Net::OpenSSH->new($self->{strDbHost}, master_stderr_discard => true, user => $self->{strDbUser}); + $self->{oDbSSH}->error and confess &log(ERROR, "unable to connect to $self->{strDbHost}: " . $self->{oDbSSH}->error); + } +} + +#################################################################################################################################### +# IS_REMOTE +# +# Determine whether database operations are remote. +#################################################################################################################################### +sub is_remote +{ + my $self = shift; + + # If the SSH object is defined then db is remote + return defined($self->{oDbSSH}) ? true : false; +} + +#################################################################################################################################### +# PSQL_EXECUTE +#################################################################################################################################### +sub psql_execute +{ + my $self = shift; + my $strScript = shift; # psql script to execute + + # Get the user-defined command for psql + my $strCommand = $self->{strCommandPsql} . " -c \"${strScript}\" postgres"; + my $strResult; + + # Run remotely + if ($self->is_remote()) + { + &log(DEBUG, " psql execute: remote ${strScript}"); + + $strResult = $self->{oDbSSH}->capture($strCommand) + or confess &log(ERROR, "unable to execute remote psql command '${strCommand}'"); + } + # Else run locally + else + { + &log(DEBUG, " psql execute: ${strScript}"); + $strResult = capture($strCommand) or confess &log(ERROR, "unable to execute local psql command '${strCommand}'"); + } + + return $strResult; +} + +no Moose; + __PACKAGE__->meta->make_immutable; \ No newline at end of file diff --git a/pg_backrest_file.pm b/pg_backrest_file.pm index 336350a6a..a4b224b60 100644 --- a/pg_backrest_file.pm +++ b/pg_backrest_file.pm @@ -29,7 +29,6 @@ has strCommandCompress => (is => 'bare'); has strCommandDecompress => (is => 'bare'); has strCommandCat => (is => 'bare', default => 'cat %file%'); has strCommandManifest => (is => 'bare'); -has strCommandPsql => (is => 'bare'); # Module variables has strDbUser => (is => 'bare'); # Database user @@ -722,35 +721,5 @@ sub manifest_get $strManifest, "\t", "."); } -#################################################################################################################################### -# PSQL_EXECUTE -#################################################################################################################################### -sub psql_execute -{ - my $self = shift; - my $strScript = shift; # psql script to execute - - # Get the user-defined command for psql - my $strCommand = $self->{strCommandPsql} . " -c \"${strScript}\" postgres"; - my $strResult; - - # Run remotely - if ($self->is_remote(PATH_DB)) - { - &log(DEBUG, " psql execute: remote ${strScript}"); - - my $oSSH = $self->remote_get(PATH_DB); - $strResult = $oSSH->capture($strCommand) or confess &log(ERROR, "unable to execute remote psql command '${strCommand}'"); - } - # Run locally - else - { - &log(DEBUG, " psql execute: ${strScript}"); - $strResult = capture($strCommand) or confess &log(ERROR, "unable to execute local psql command '${strCommand}'"); - } - - return $strResult; -} - no Moose; __PACKAGE__->meta->make_immutable; \ No newline at end of file