diff --git a/README.md b/README.md index 93e19ca90..24086ef5a 100644 --- a/README.md +++ b/README.md @@ -14,6 +14,10 @@ Simple Postgres Backup and Restore ## release notes +### v0.18: Return soft error from archive-get when file is missing + +* The archive-get function returns a 1 when the archive file is missing to differentiate from hard errors (ssh connection failure, file copy error, etc.) This lets Postgres know that that the archive stream has terminated normally. However, this does not take into account possible holes in the archive stream. + ### v0.17: Warn when archive directories cannot be deleted * If an archive directory which should be empty could not be deleted backrest was throwing an error. There's a good fix for that coming, but for the time being it has been changed to a warning so processing can continue. This was impacting backups as sometimes the final archive file would not get pushed if the first archive file had been in a different directory (plus some bad luck). diff --git a/pg_backrest.pl b/pg_backrest.pl index 1e537ace9..ff6ee561a 100755 --- a/pg_backrest.pl +++ b/pg_backrest.pl @@ -244,9 +244,7 @@ if ($strOperation eq OP_ARCHIVE_GET) &log(INFO, "getting archive log " . $ARGV[1]); # Get the archive file - archive_get($ARGV[1], $ARGV[2]); - - exit 0; + exit archive_get($ARGV[1], $ARGV[2]); } #################################################################################################################################### diff --git a/pg_backrest_backup.pm b/pg_backrest_backup.pm index 3366eddfa..4a887b130 100644 --- a/pg_backrest_backup.pm +++ b/pg_backrest_backup.pm @@ -220,19 +220,36 @@ sub archive_get my $strSourceArchive = shift; my $strDestinationFile = shift; + # Determine the path where the requested archive file is located my $strArchivePath = dirname($oFile->path_get(PATH_BACKUP_ARCHIVE, $strSourceArchive)); + # Get the name of the requested archive file (may have hash info and compression extension) my @stryArchiveFile = $oFile->file_list_get(PATH_BACKUP_ABSOLUTE, $strArchivePath, "^${strSourceArchive}(-[0-f]+){0,1}(\\.$oFile->{strCompressExtension}){0,1}\$"); - if (scalar @stryArchiveFile != 1) + # If there is more than one matching archive file then there is a serious issue - likely a bug in the archiver + if (scalar @stryArchiveFile > 1) { - confess &log(ERROR, (scalar @stryArchiveFile) . " archive file(s) found for ${strSourceArchive}"); + confess &log(ASSERT, (scalar @stryArchiveFile) . " archive files found for ${strSourceArchive}."); + } + + # If there are no matching archive files then there are two possibilities: + # 1) The end of the archive stream has been reached, this is normal and a 1 will be returned + # 2) There is a hole in the archive stream so return a hard error (!!! However if turns out that due to race conditions this + # is harder than it looks. Postponed and added to the backlog. For now treated as case #1.) + elsif (scalar @stryArchiveFile == 0) + { + &log(INFO, "${strSourceArchive} was not found in the archive repository"); + + return 1; } &log(DEBUG, "archive_get: cp ${stryArchiveFile[0]} ${strDestinationFile}"); + # Copy the archive file to the requested location $oFile->file_copy(PATH_BACKUP_ARCHIVE, $stryArchiveFile[0], PATH_DB_ABSOLUTE, $strDestinationFile); + + return 0; } ####################################################################################################################################