diff --git a/README.md b/README.md index 7ae69adc8..41a55076e 100644 --- a/README.md +++ b/README.md @@ -6,12 +6,20 @@ Simple Postgres Backup and Restore release notes ============= -v0.15: Added archive-get [THIS IS PLANNED FUNCTIONALITY FOR THIS RELEASE] +v0.15: Added archive-get [PLANNED FUNCTIONALITY FOR THIS RELEASE] * Added archive-get functionality to aid in restores. * Default restore.conf is written to each backup. +* Added option to force a checkpoint when starting the backup. + +* Now throws ERROR when unable to get lock during backup or export. + +* Able to set timeout on ssh connection in config file. + +------------- + v0.10: Backup and archiving are functional This version has been put into production at Resonate, so it does work, but there are a number of major caveats. diff --git a/pg_backrest.pl b/pg_backrest.pl index e4bd173ea..8e65429c3 100755 --- a/pg_backrest.pl +++ b/pg_backrest.pl @@ -1,7 +1,7 @@ +#!/usr/bin/perl #################################################################################################################################### # pg_backrest.pl - Simple Postgres Backup and Restore #################################################################################################################################### -#!/usr/bin/perl #################################################################################################################################### # Perl includes @@ -26,10 +26,11 @@ use pg_backrest_db; #################################################################################################################################### use constant { + OP_ARCHIVE_GET => "archive-get", OP_ARCHIVE_PUSH => "archive-push", OP_ARCHIVE_PULL => "archive-pull", OP_BACKUP => "backup", - OP_EXPIRE => "expire", + OP_EXPIRE => "expire" }; #################################################################################################################################### @@ -168,7 +169,8 @@ if (!defined($strOperation)) confess &log(ERROR, "operation is not defined"); } -if ($strOperation ne OP_ARCHIVE_PUSH && +if ($strOperation ne OP_ARCHIVE_GET && + $strOperation ne OP_ARCHIVE_PUSH && $strOperation ne OP_ARCHIVE_PULL && $strOperation ne OP_BACKUP && $strOperation ne OP_EXPIRE) @@ -203,7 +205,51 @@ log_level_set(uc(config_load(CONFIG_SECTION_LOG, CONFIG_KEY_LEVEL_FILE, true, "I uc(config_load(CONFIG_SECTION_LOG, CONFIG_KEY_LEVEL_CONSOLE, true, "ERROR"))); #################################################################################################################################### -# ARCHIVE-PUSH Command +# ARCHIVE-GET Command +#################################################################################################################################### +if ($strOperation eq OP_ARCHIVE_GET) +{ + # Make sure the archive file is defined + if (!defined($ARGV[1])) + { + confess &log(ERROR, "archive file not provided - show usage"); + } + + # Make sure the destination file is defined + if (!defined($ARGV[2])) + { + confess &log(ERROR, "destination file not provided - show usage"); + } + + # Init the file object + my $oFile = pg_backrest_file->new + ( + strStanza => $strStanza, + bNoCompression => true, + strBackupUser => config_load(CONFIG_SECTION_BACKUP, CONFIG_KEY_USER), + strBackupHost => config_load(CONFIG_SECTION_BACKUP, CONFIG_KEY_HOST), + strBackupPath => config_load(CONFIG_SECTION_BACKUP, CONFIG_KEY_PATH, true), + strCommandDecompress => config_load(CONFIG_SECTION_COMMAND, CONFIG_KEY_DECOMPRESS, true) + ); + + # Init the backup object + backup_init + ( + undef, + $oFile + ); + + # Info for the Postgres log + &log(INFO, "getting archive log " . $ARGV[1]); + + # Get the archive file + archive_get($ARGV[1], $ARGV[2]); + + exit 0; +} + +#################################################################################################################################### +# ARCHIVE-PUSH and ARCHIVE-PULL Commands #################################################################################################################################### if ($strOperation eq OP_ARCHIVE_PUSH || $strOperation eq OP_ARCHIVE_PULL) { diff --git a/pg_backrest_file.pm b/pg_backrest_file.pm index 59477484f..8ff2ac972 100644 --- a/pg_backrest_file.pm +++ b/pg_backrest_file.pm @@ -738,7 +738,7 @@ sub file_compress if (!defined($self->{strCommandCompress})) { - confess &log(ASSERT, "\$strCommandChecksum not defined"); + confess &log(ASSERT, "\$strCommandCompress not defined"); } my $strPath = $self->path_get($strPathType, $strFile); @@ -762,39 +762,66 @@ sub file_list_get my $strExpression = shift; my $strSortOrder = shift; - # For now this operation is not supported remotely. Not currently needed. + # Get the root path for the manifest + my $strPathList = $self->path_get($strPathType, $strPath); + + # Builds the exists command + my $strCommand = "ls ${strPathList} | egrep \"$strExpression\" 2> /dev/null"; + + # Run the file exists command + my $strExists = ""; + + # Run remotely if ($self->is_remote($strPathType)) { - confess &log(ASSERT, "remote operation not supported"); + &log(TRACE, "file_exists: remote ${strPathType}:${strPathExists}"); + + my $oSSH = $self->remote_get($strPathType); + $strExists = $oSSH->capture($strCommand); } - - my $strPathList = $self->path_get($strPathType, $strPath); - my $hDir; - - opendir $hDir, $strPathList or confess &log(ERROR, "unable to open path ${strPathList}"); - my @stryFileAll = readdir $hDir or confess &log(ERROR, "unable to get files for path ${strPathList}, expression ${strExpression}"); - close $hDir; - - my @stryFile; - - if (@stryFileAll) + # Run locally + else { - @stryFile = grep(/$strExpression/i, @stryFileAll) + &log(TRACE, "file_exists: local ${strPathType}:${strPathExists}"); + $strExists = capture($strCommand); } - if (@stryFile) - { - if (defined($strSortOrder) && $strSortOrder eq "reverse") - { - return sort {$b cmp $a} @stryFile; - } - else - { - return sort @stryFile; - } - } + # If the return from ls eq strPathExists then true + return ($strExists eq $strPathExists); - return @stryFile; + # # For now this operation is not supported remotely. Not currently needed. + # if ($self->is_remote($strPathType)) + # { + # confess &log(ASSERT, "remote operation not supported"); + # } + # + # my $strPathList = $self->path_get($strPathType, $strPath); + # my $hDir; + # + # opendir $hDir, $strPathList or confess &log(ERROR, "unable to open path ${strPathList}"); + # my @stryFileAll = readdir $hDir or confess &log(ERROR, "unable to get files for path ${strPathList}, expression ${strExpression}"); + # close $hDir; + # + # my @stryFile; + # + # if (@stryFileAll) + # { + # @stryFile = grep(/$strExpression/i, @stryFileAll) + # } + # + # if (@stryFile) + # { + # if (defined($strSortOrder) && $strSortOrder eq "reverse") + # { + # return sort {$b cmp $a} @stryFile; + # } + # else + # { + # return sort @stryFile; + # } + # } + # + # return @stryFile; } #################################################################################################################################### @@ -892,7 +919,7 @@ sub manifest_get # Builds the manifest command my $strCommand = $self->{strCommandManifest}; $strCommand =~ s/\%path\%/${strPathManifest}/g; - $strCommand .= " 2> /dev/null"; + $strCommand .= " 2> /dev/null"; # Run the manifest command my $strManifest;