2015-06-14 00:25:49 +02:00
|
|
|
####################################################################################################################################
|
|
|
|
# BACKUP COMMON MODULE
|
|
|
|
####################################################################################################################################
|
2016-04-14 15:30:54 +02:00
|
|
|
package pgBackRest::BackupCommon;
|
2015-06-14 00:25:49 +02:00
|
|
|
|
|
|
|
use strict;
|
|
|
|
use warnings FATAL => qw(all);
|
|
|
|
use Carp qw(confess);
|
|
|
|
|
|
|
|
use Exporter qw(import);
|
2015-08-29 20:20:46 +02:00
|
|
|
our @EXPORT = qw();
|
2015-06-14 00:25:49 +02:00
|
|
|
use File::Basename;
|
|
|
|
|
2016-04-14 15:30:54 +02:00
|
|
|
use pgBackRest::Common::Log;
|
|
|
|
use pgBackRest::Common::String;
|
2017-04-05 16:16:16 +02:00
|
|
|
use pgBackRest::Common::Wait;
|
2016-04-14 15:30:54 +02:00
|
|
|
use pgBackRest::Config::Config;
|
2017-04-05 16:16:16 +02:00
|
|
|
use pgBackRest::File;
|
|
|
|
use pgBackRest::FileCommon;
|
|
|
|
use pgBackRest::Manifest;
|
2015-06-14 00:25:49 +02:00
|
|
|
|
2016-12-03 17:23:26 +02:00
|
|
|
####################################################################################################################################
|
|
|
|
# Latest backup link constant
|
|
|
|
####################################################################################################################################
|
|
|
|
use constant LINK_LATEST => OPTION_DEFAULT_RESTORE_SET;
|
|
|
|
push @EXPORT, qw(LINK_LATEST);
|
|
|
|
|
2015-08-29 20:20:46 +02:00
|
|
|
####################################################################################################################################
|
2016-12-23 18:43:26 +02:00
|
|
|
# backupRegExpGet
|
|
|
|
#
|
|
|
|
# Generate a regexp depending on the backups that need to be found.
|
2015-08-29 20:20:46 +02:00
|
|
|
####################################################################################################################################
|
2015-06-14 00:25:49 +02:00
|
|
|
sub backupRegExpGet
|
|
|
|
{
|
2015-08-29 20:20:46 +02:00
|
|
|
# Assign function parameters, defaults, and log debug info
|
|
|
|
my
|
|
|
|
(
|
|
|
|
$strOperation,
|
|
|
|
$bFull,
|
|
|
|
$bDifferential,
|
2016-04-15 04:50:02 +02:00
|
|
|
$bIncremental,
|
|
|
|
$bAnchor
|
2015-08-29 20:20:46 +02:00
|
|
|
) =
|
|
|
|
logDebugParam
|
|
|
|
(
|
2016-08-11 23:32:28 +02:00
|
|
|
__PACKAGE__ . '::backupRegExpGet', \@_,
|
2015-08-29 20:20:46 +02:00
|
|
|
{name => 'bFull', default => false},
|
|
|
|
{name => 'bDifferential', default => false},
|
2016-04-15 04:50:02 +02:00
|
|
|
{name => 'bIncremental', default => false},
|
|
|
|
{name => 'bAnchor', default => true}
|
2015-08-29 20:20:46 +02:00
|
|
|
);
|
2015-06-14 00:25:49 +02:00
|
|
|
|
2016-12-23 18:43:26 +02:00
|
|
|
# One of the types must be selected
|
|
|
|
if (!($bFull || $bDifferential || $bIncremental))
|
2015-06-14 00:25:49 +02:00
|
|
|
{
|
2016-12-23 18:43:26 +02:00
|
|
|
confess &log(ASSERT, 'at least one backup type must be selected');
|
2015-06-14 00:25:49 +02:00
|
|
|
}
|
|
|
|
|
2016-12-23 18:43:26 +02:00
|
|
|
# Standard regexp to match date and time formattting
|
2015-06-14 00:25:49 +02:00
|
|
|
my $strDateTimeRegExp = "[0-9]{8}\\-[0-9]{6}";
|
2016-12-23 18:43:26 +02:00
|
|
|
# Start the expression with the anchor if requested, date/time regexp and full backup indicator
|
|
|
|
my $strRegExp = ($bAnchor ? '^' : '') . $strDateTimeRegExp . 'F';
|
2015-06-14 00:25:49 +02:00
|
|
|
|
2016-12-23 18:43:26 +02:00
|
|
|
# Add the diff and/or incr expressions if requested
|
2015-06-14 00:25:49 +02:00
|
|
|
if ($bDifferential || $bIncremental)
|
|
|
|
{
|
2016-12-23 18:43:26 +02:00
|
|
|
# If full requested then diff/incr is optional
|
2015-06-14 00:25:49 +02:00
|
|
|
if ($bFull)
|
|
|
|
{
|
|
|
|
$strRegExp .= "(\\_";
|
|
|
|
}
|
2016-12-23 18:43:26 +02:00
|
|
|
# Else diff/incr is required
|
2015-06-14 00:25:49 +02:00
|
|
|
else
|
|
|
|
{
|
|
|
|
$strRegExp .= "\\_";
|
|
|
|
}
|
|
|
|
|
2016-12-23 18:43:26 +02:00
|
|
|
# Append date/time regexp for diff/incr
|
2015-06-14 00:25:49 +02:00
|
|
|
$strRegExp .= $strDateTimeRegExp;
|
|
|
|
|
2016-12-23 18:43:26 +02:00
|
|
|
# Filter on both diff/incr
|
2015-06-14 00:25:49 +02:00
|
|
|
if ($bDifferential && $bIncremental)
|
|
|
|
{
|
|
|
|
$strRegExp .= '(D|I)';
|
|
|
|
}
|
2016-12-23 18:43:26 +02:00
|
|
|
# Else just diff
|
2015-06-14 00:25:49 +02:00
|
|
|
elsif ($bDifferential)
|
|
|
|
{
|
|
|
|
$strRegExp .= 'D';
|
|
|
|
}
|
2016-12-23 18:43:26 +02:00
|
|
|
# Else just incr
|
2015-06-14 00:25:49 +02:00
|
|
|
else
|
|
|
|
{
|
|
|
|
$strRegExp .= 'I';
|
|
|
|
}
|
|
|
|
|
2016-12-23 18:43:26 +02:00
|
|
|
# If full requested then diff/incr is optional
|
2015-06-14 00:25:49 +02:00
|
|
|
if ($bFull)
|
|
|
|
{
|
|
|
|
$strRegExp .= '){0,1}';
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-12-23 18:43:26 +02:00
|
|
|
# Append the end anchor if requested
|
2016-04-15 04:50:02 +02:00
|
|
|
$strRegExp .= $bAnchor ? "\$" : '';
|
2015-06-14 00:25:49 +02:00
|
|
|
|
2015-08-29 20:20:46 +02:00
|
|
|
# Return from function and log return values if any
|
|
|
|
return logDebugReturn
|
|
|
|
(
|
|
|
|
$strOperation,
|
|
|
|
{name => 'strRegExp', value => $strRegExp}
|
|
|
|
);
|
2015-06-14 00:25:49 +02:00
|
|
|
}
|
|
|
|
|
2015-08-29 20:20:46 +02:00
|
|
|
push @EXPORT, qw(backupRegExpGet);
|
|
|
|
|
2015-09-02 01:05:10 +02:00
|
|
|
####################################################################################################################################
|
|
|
|
# backupLabelFormat
|
2016-12-23 18:43:26 +02:00
|
|
|
#
|
|
|
|
# Format the label for a backup.
|
2015-09-02 01:05:10 +02:00
|
|
|
####################################################################################################################################
|
|
|
|
sub backupLabelFormat
|
|
|
|
{
|
|
|
|
# Assign function parameters, defaults, and log debug info
|
|
|
|
my
|
|
|
|
(
|
|
|
|
$strOperation,
|
|
|
|
$strType,
|
|
|
|
$strBackupLabelLast,
|
|
|
|
$lTimestampStop
|
|
|
|
) =
|
|
|
|
logDebugParam
|
|
|
|
(
|
2016-08-11 23:32:28 +02:00
|
|
|
__PACKAGE__ . '::backupLabelFormat', \@_,
|
2015-09-02 01:05:10 +02:00
|
|
|
{name => 'strType', trace => true},
|
|
|
|
{name => 'strBackupLabelLast', required => false, trace => true},
|
|
|
|
{name => 'lTimestampStop', trace => true}
|
|
|
|
);
|
|
|
|
|
2016-12-23 18:43:26 +02:00
|
|
|
# Full backup label
|
2015-09-02 01:05:10 +02:00
|
|
|
my $strBackupLabel;
|
|
|
|
|
|
|
|
if ($strType eq BACKUP_TYPE_FULL)
|
|
|
|
{
|
2016-12-23 18:43:26 +02:00
|
|
|
# Last backup label must not be defined
|
2015-09-02 01:05:10 +02:00
|
|
|
if (defined($strBackupLabelLast))
|
|
|
|
{
|
2016-12-23 18:43:26 +02:00
|
|
|
confess &log(ASSERT, "strBackupLabelLast must not be defined when strType = '${strType}'");
|
2015-09-02 01:05:10 +02:00
|
|
|
}
|
|
|
|
|
2016-12-23 18:43:26 +02:00
|
|
|
# Format the timestamp and add the full indicator
|
2015-09-02 01:05:10 +02:00
|
|
|
$strBackupLabel = timestampFileFormat(undef, $lTimestampStop) . 'F';
|
|
|
|
}
|
2016-12-23 18:43:26 +02:00
|
|
|
# Else diff or incr label
|
2015-09-02 01:05:10 +02:00
|
|
|
else
|
|
|
|
{
|
2016-12-23 18:43:26 +02:00
|
|
|
# Last backup label must be defined
|
2015-09-02 01:05:10 +02:00
|
|
|
if (!defined($strBackupLabelLast))
|
|
|
|
{
|
2016-12-23 18:43:26 +02:00
|
|
|
confess &log(ASSERT, "strBackupLabelLast must be defined when strType = '${strType}'");
|
2015-09-02 01:05:10 +02:00
|
|
|
}
|
|
|
|
|
2016-12-23 18:43:26 +02:00
|
|
|
# Get the full backup portion of the last backup label
|
2015-09-02 01:05:10 +02:00
|
|
|
$strBackupLabel = substr($strBackupLabelLast, 0, 16);
|
|
|
|
|
2016-12-23 18:43:26 +02:00
|
|
|
# Format the timestamp
|
2015-09-02 01:05:10 +02:00
|
|
|
$strBackupLabel .= '_' . timestampFileFormat(undef, $lTimestampStop);
|
|
|
|
|
2016-12-23 18:43:26 +02:00
|
|
|
# Add the diff indicator
|
2015-09-02 01:05:10 +02:00
|
|
|
if ($strType eq BACKUP_TYPE_DIFF)
|
|
|
|
{
|
|
|
|
$strBackupLabel .= 'D';
|
|
|
|
}
|
2016-12-23 18:43:26 +02:00
|
|
|
# Else incr indicator
|
2015-09-02 01:05:10 +02:00
|
|
|
else
|
|
|
|
{
|
|
|
|
$strBackupLabel .= 'I';
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
# Return from function and log return values if any
|
|
|
|
return logDebugReturn
|
|
|
|
(
|
|
|
|
$strOperation,
|
|
|
|
{name => 'strBackupLabel', value => $strBackupLabel, trace => true}
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
push @EXPORT, qw(backupLabelFormat);
|
|
|
|
|
2017-04-05 16:16:16 +02:00
|
|
|
####################################################################################################################################
|
|
|
|
# backupLabel
|
|
|
|
#
|
|
|
|
# Get unique backup label.
|
|
|
|
####################################################################################################################################
|
|
|
|
sub backupLabel
|
|
|
|
{
|
|
|
|
# Assign function parameters, defaults, and log debug info
|
|
|
|
my
|
|
|
|
(
|
|
|
|
$strOperation,
|
|
|
|
$oFile,
|
|
|
|
$strType,
|
|
|
|
$strBackupLabelLast,
|
|
|
|
$lTimestampStop
|
|
|
|
) =
|
|
|
|
logDebugParam
|
|
|
|
(
|
|
|
|
__PACKAGE__ . '::backupLabelFormat', \@_,
|
|
|
|
{name => 'oFile', trace => true},
|
|
|
|
{name => 'strType', trace => true},
|
|
|
|
{name => 'strBackupLabelLast', required => false, trace => true},
|
|
|
|
{name => 'lTimestampStop', trace => true}
|
|
|
|
);
|
|
|
|
|
|
|
|
# Create backup label
|
|
|
|
my $strBackupLabel = backupLabelFormat($strType, $strBackupLabelLast, $lTimestampStop);
|
|
|
|
|
|
|
|
# Make sure that the timestamp has not already been used by a prior backup. This is unlikely for online backups since there is
|
|
|
|
# already a wait after the manifest is built but it's still possible if the remote and local systems don't have synchronized
|
|
|
|
# clocks. In practice this is most useful for making offline testing faster since it allows the wait after manifest build to
|
|
|
|
# be skipped by dealing with any backup label collisions here.
|
|
|
|
if (fileList($oFile->pathGet(PATH_BACKUP_CLUSTER),
|
|
|
|
{strExpression =>
|
|
|
|
($strType eq BACKUP_TYPE_FULL ? '^' : '_') . timestampFileFormat(undef, $lTimestampStop) .
|
|
|
|
($strType eq BACKUP_TYPE_FULL ? 'F' : '(D|I)$')}) ||
|
|
|
|
fileList($oFile->pathGet(PATH_BACKUP_CLUSTER, PATH_BACKUP_HISTORY . '/' . timestampFormat('%4d', $lTimestampStop)),
|
|
|
|
{strExpression =>
|
|
|
|
($strType eq BACKUP_TYPE_FULL ? '^' : '_') . timestampFileFormat(undef, $lTimestampStop) .
|
|
|
|
($strType eq BACKUP_TYPE_FULL ? 'F' : '(D|I)\.manifest\.' . $oFile->{strCompressExtension}),
|
|
|
|
bIgnoreMissing => true}))
|
|
|
|
{
|
|
|
|
waitRemainder();
|
|
|
|
$strBackupLabel = backupLabelFormat($strType, $strBackupLabelLast, time());
|
|
|
|
}
|
|
|
|
|
|
|
|
# Return from function and log return values if any
|
|
|
|
return logDebugReturn
|
|
|
|
(
|
|
|
|
$strOperation,
|
|
|
|
{name => 'strBackupLabel', value => $strBackupLabel, trace => true}
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
push @EXPORT, qw(backupLabel);
|
|
|
|
|
2015-06-14 00:25:49 +02:00
|
|
|
1;
|