mirror of
https://github.com/pgbackrest/pgbackrest.git
synced 2024-12-14 10:13:05 +02:00
148836fe44
* Includes updating the manifest to format 4. It turns out the manifest and .info files were not very good for providing information. A format update was required anyway so worked through the backlog of changes that would require a format change. * Multiple database versions are now supported in the archive. Does't actually work yet but the structure should be good. * Tests use more constants now that test logs can catch name regressions.
141 lines
5.4 KiB
Perl
141 lines
5.4 KiB
Perl
####################################################################################################################################
|
|
# BACKUP FILE MODULE
|
|
####################################################################################################################################
|
|
package BackRest::BackupFile;
|
|
|
|
use threads;
|
|
use Thread::Queue;
|
|
use strict;
|
|
use warnings FATAL => qw(all);
|
|
use Carp qw(confess);
|
|
|
|
use Exporter qw(import);
|
|
use File::Basename qw(dirname);
|
|
|
|
use lib dirname($0);
|
|
use BackRest::Exception;
|
|
use BackRest::File;
|
|
use BackRest::Manifest;
|
|
use BackRest::Utility;
|
|
|
|
####################################################################################################################################
|
|
# backupFile
|
|
####################################################################################################################################
|
|
sub backupFile
|
|
{
|
|
my $oFile = shift; # File object
|
|
my $strSourceFile = shift; # Source file to backup
|
|
my $strDestinationFile = shift; # Destination backup file
|
|
my $bDestinationCompress = shift; # Compress destination file
|
|
my $strChecksum = shift; # File checksum to be checked
|
|
my $lModificationTime = shift; # File modification time
|
|
my $lSizeFile = shift; # File size
|
|
my $lSizeTotal = shift; # Total size of the files to be copied
|
|
my $lSizeCurrent = shift; # Size of files copied so far
|
|
|
|
my $bCopyResult; # Copy result
|
|
my $strCopyChecksum; # Copy checksum
|
|
my $lCopySize; # Copy Size
|
|
|
|
# Add the size of the current file to keep track of percent complete
|
|
$lSizeCurrent += $lSizeFile;
|
|
|
|
# If checksum is defined then the file already exists but needs to be checked
|
|
my $bCopy = true;
|
|
|
|
if (defined($strChecksum))
|
|
{
|
|
($strCopyChecksum, $lCopySize) = $oFile->hash_size(PATH_BACKUP_TMP, $strDestinationFile);
|
|
|
|
$bCopy = !($strCopyChecksum eq $strChecksum && $lCopySize == $lSizeFile);
|
|
|
|
if ($bCopy)
|
|
{
|
|
&log(WARN, "resumed backup file ${strDestinationFile} should have checksum ${strChecksum} but " .
|
|
"actually has checksum ${strCopyChecksum}. The file will be recopied and backup will " .
|
|
"continue but this may be an issue unless the backup temp path is known to be corrupted.");
|
|
}
|
|
}
|
|
|
|
if ($bCopy)
|
|
{
|
|
# Copy the file from the database to the backup (will return false if the source file is missing)
|
|
($bCopyResult, $strCopyChecksum, $lCopySize) =
|
|
$oFile->copy(PATH_DB_ABSOLUTE, $strSourceFile,
|
|
PATH_BACKUP_TMP, $strDestinationFile .
|
|
($bDestinationCompress ? '.' . $oFile->{strCompressExtension} : ''),
|
|
false, # Source is not compressed since it is the db directory
|
|
$bDestinationCompress, # Destination should be compressed based on backup settings
|
|
true, # Ignore missing files
|
|
$lModificationTime, # Set modification time - this is required for resume
|
|
undef, # Do not set original mode
|
|
true); # Create the destination directory if it does not exist
|
|
|
|
if (!$bCopyResult)
|
|
{
|
|
# If file is missing assume the database removed it (else corruption and nothing we can do!)
|
|
&log(INFO, "skip file removed by database: " . $strSourceFile);
|
|
|
|
return false, $lSizeCurrent, undef, undef;
|
|
}
|
|
}
|
|
|
|
# Ouput log
|
|
&log(INFO, (defined($strChecksum) && !$bCopy ? 'checksum resumed file' : 'backup file') .
|
|
" $strSourceFile (" . file_size_format($lCopySize) .
|
|
($lSizeTotal > 0 ? ', ' . int($lSizeCurrent * 100 / $lSizeTotal) . '%' : '') . ')' .
|
|
($lCopySize != 0 ? " checksum ${strCopyChecksum}" : ''));
|
|
|
|
return true, $lSizeCurrent, $lCopySize, $strCopyChecksum;
|
|
}
|
|
|
|
our @EXPORT = qw(backupFile);
|
|
|
|
####################################################################################################################################
|
|
# backupManifestUpdate
|
|
####################################################################################################################################
|
|
sub backupManifestUpdate
|
|
{
|
|
my $oManifest = shift;
|
|
my $strSection = shift;
|
|
my $strFile = shift;
|
|
my $bCopied = shift;
|
|
my $lSize = shift;
|
|
my $strChecksum = shift;
|
|
my $lManifestSaveSize = shift;
|
|
my $lManifestSaveCurrent = shift;
|
|
|
|
# If copy was successful store the checksum and size
|
|
if ($bCopied)
|
|
{
|
|
$oManifest->set($strSection, $strFile, MANIFEST_SUBKEY_SIZE, $lSize + 0);
|
|
|
|
if ($lSize > 0)
|
|
{
|
|
$oManifest->set($strSection, $strFile, MANIFEST_SUBKEY_CHECKSUM, $strChecksum);
|
|
}
|
|
|
|
# Determine whether to save the manifest
|
|
$lManifestSaveCurrent += $lSize;
|
|
|
|
if ($lManifestSaveCurrent >= $lManifestSaveSize)
|
|
{
|
|
$oManifest->save();
|
|
&log(DEBUG, 'manifest saved');
|
|
|
|
$lManifestSaveCurrent = 0;
|
|
}
|
|
}
|
|
# Else the file was removed during backup so remove from manifest
|
|
else
|
|
{
|
|
$oManifest->remove($strSection, $strFile);
|
|
}
|
|
|
|
return $lManifestSaveCurrent;
|
|
}
|
|
|
|
push @EXPORT, qw(backupManifestUpdate);
|
|
|
|
1;
|