2015-09-02 01:05:10 +02:00
|
|
|
####################################################################################################################################
|
2015-10-28 11:10:36 +02:00
|
|
|
# ExpireCommonTest.pm - Common code for expire tests
|
2015-09-02 01:05:10 +02:00
|
|
|
####################################################################################################################################
|
2017-05-12 22:43:04 +02:00
|
|
|
package pgBackRestTest::Env::ExpireEnvTest;
|
2016-12-23 15:22:59 +02:00
|
|
|
use parent 'pgBackRestTest::Common::RunTest';
|
2015-09-02 01:05:10 +02:00
|
|
|
|
|
|
|
####################################################################################################################################
|
|
|
|
# Perl includes
|
|
|
|
####################################################################################################################################
|
|
|
|
use strict;
|
|
|
|
use warnings FATAL => qw(all);
|
|
|
|
use Carp qw(confess);
|
|
|
|
|
2017-06-09 23:51:41 +02:00
|
|
|
use File::Basename qw(basename);
|
|
|
|
|
2017-06-21 14:02:21 +02:00
|
|
|
use pgBackRest::Archive::Info;
|
2017-05-15 22:01:00 +02:00
|
|
|
use pgBackRest::Backup::Common;
|
|
|
|
use pgBackRest::Backup::Info;
|
2016-04-14 15:30:54 +02:00
|
|
|
use pgBackRest::Common::Ini;
|
|
|
|
use pgBackRest::Common::Log;
|
|
|
|
use pgBackRest::Config::Config;
|
2016-08-12 04:35:24 +02:00
|
|
|
use pgBackRest::DbVersion;
|
2016-04-14 15:30:54 +02:00
|
|
|
use pgBackRest::Manifest;
|
2017-06-09 23:51:41 +02:00
|
|
|
use pgBackRest::Protocol::Storage::Helper;
|
2017-04-03 16:42:55 +02:00
|
|
|
use pgBackRest::Stanza;
|
2017-06-09 23:51:41 +02:00
|
|
|
use pgBackRest::Storage::Helper;
|
2016-06-27 02:53:45 +02:00
|
|
|
use pgBackRest::Version;
|
2015-09-02 01:05:10 +02:00
|
|
|
|
2017-05-12 22:43:04 +02:00
|
|
|
use pgBackRestTest::Env::HostEnvTest;
|
|
|
|
use pgBackRestTest::Env::Host::HostBaseTest;
|
2016-04-14 15:30:54 +02:00
|
|
|
use pgBackRestTest::Common::ExecuteTest;
|
2016-06-24 14:12:58 +02:00
|
|
|
use pgBackRestTest::Common::FileTest;
|
2017-06-09 23:51:41 +02:00
|
|
|
use pgBackRestTest::Common::RunTest;
|
2015-09-02 01:05:10 +02:00
|
|
|
|
|
|
|
####################################################################################################################################
|
|
|
|
# new
|
|
|
|
####################################################################################################################################
|
|
|
|
sub new
|
|
|
|
{
|
|
|
|
my $class = shift; # Class name
|
|
|
|
|
|
|
|
# Create the class hash
|
|
|
|
my $self = {};
|
|
|
|
bless $self, $class;
|
|
|
|
|
|
|
|
# Assign function parameters, defaults, and log debug info
|
|
|
|
(
|
|
|
|
my $strOperation,
|
2016-06-24 14:12:58 +02:00
|
|
|
$self->{oHostBackup},
|
2016-12-23 15:22:59 +02:00
|
|
|
$self->{strBackRestExe},
|
2017-06-09 23:51:41 +02:00
|
|
|
$self->{oStorageRepo},
|
2017-04-03 16:42:55 +02:00
|
|
|
$self->{oLogTest},
|
|
|
|
$self->{oRunTest},
|
2015-09-02 01:05:10 +02:00
|
|
|
) =
|
|
|
|
logDebugParam
|
|
|
|
(
|
2016-08-11 23:32:28 +02:00
|
|
|
__PACKAGE__ . '->new', \@_,
|
2017-02-05 17:31:29 +02:00
|
|
|
{name => 'oHostBackup', required => false, trace => true},
|
2016-12-23 15:22:59 +02:00
|
|
|
{name => 'strBackRestExe', trace => true},
|
2017-06-09 23:51:41 +02:00
|
|
|
{name => 'oStorageRepo', trace => true},
|
2017-04-03 16:42:55 +02:00
|
|
|
{name => 'oLogTest', required => false, trace => true},
|
|
|
|
{name => 'oRunTest', required => false, trace => true},
|
2015-09-02 01:05:10 +02:00
|
|
|
);
|
|
|
|
|
|
|
|
# Return from function and log return values if any
|
|
|
|
return logDebugReturn
|
|
|
|
(
|
|
|
|
$strOperation,
|
|
|
|
{name => 'self', value => $self}
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
####################################################################################################################################
|
2017-04-03 16:42:55 +02:00
|
|
|
# stanzaSet - set the local stanza object
|
2015-09-02 01:05:10 +02:00
|
|
|
####################################################################################################################################
|
2017-04-03 16:42:55 +02:00
|
|
|
sub stanzaSet
|
2015-09-02 01:05:10 +02:00
|
|
|
{
|
|
|
|
my $self = shift;
|
|
|
|
|
|
|
|
# Assign function parameters, defaults, and log debug info
|
|
|
|
my
|
|
|
|
(
|
|
|
|
$strOperation,
|
|
|
|
$strStanza,
|
2017-04-03 16:42:55 +02:00
|
|
|
$strDbVersion,
|
|
|
|
$bStanzaUpgrade,
|
2015-09-02 01:05:10 +02:00
|
|
|
) =
|
|
|
|
logDebugParam
|
|
|
|
(
|
2017-04-03 16:42:55 +02:00
|
|
|
__PACKAGE__ . '->stanzaSet', \@_,
|
2015-09-02 01:05:10 +02:00
|
|
|
{name => 'strStanza'},
|
2017-04-03 16:42:55 +02:00
|
|
|
{name => 'strDbVersion'},
|
|
|
|
{name => 'bStanzaUpgrade'},
|
2015-09-02 01:05:10 +02:00
|
|
|
);
|
|
|
|
|
|
|
|
# Assign variables
|
|
|
|
my $oStanza = {};
|
2017-04-03 16:42:55 +02:00
|
|
|
|
|
|
|
my $oStanzaCreate = new pgBackRest::Stanza();
|
|
|
|
|
|
|
|
# If we're not upgrading, then create the stanza
|
|
|
|
if (!$bStanzaUpgrade)
|
|
|
|
{
|
|
|
|
$oStanzaCreate->stanzaCreate();
|
|
|
|
}
|
|
|
|
|
|
|
|
# Get the database info for the stanza
|
2015-09-02 01:05:10 +02:00
|
|
|
$$oStanza{strDbVersion} = $strDbVersion;
|
2017-04-03 16:42:55 +02:00
|
|
|
$$oStanza{ullDbSysId} = $oStanzaCreate->{oDb}{ullDbSysId};
|
|
|
|
$$oStanza{iCatalogVersion} = $oStanzaCreate->{oDb}{iCatalogVersion};
|
|
|
|
$$oStanza{iControlVersion} = $oStanzaCreate->{oDb}{iControlVersion};
|
|
|
|
|
2017-11-06 19:51:12 +02:00
|
|
|
my $bEncrypted = defined($self->{oStorageRepo}->cipherType());
|
|
|
|
|
|
|
|
my $oArchiveInfo =
|
|
|
|
new pgBackRest::Archive::Info($self->{oStorageRepo}->pathGet(STORAGE_REPO_ARCHIVE),
|
|
|
|
{strCipherPassSub => $bEncrypted ? ENCRYPTION_KEY_ARCHIVE : undef});
|
|
|
|
my $oBackupInfo =
|
|
|
|
new pgBackRest::Backup::Info($self->{oStorageRepo}->pathGet(STORAGE_REPO_BACKUP),
|
|
|
|
{strCipherPassSub => $bEncrypted ? ENCRYPTION_KEY_MANIFEST : undef});
|
2017-04-03 16:42:55 +02:00
|
|
|
|
|
|
|
if ($bStanzaUpgrade)
|
|
|
|
{
|
|
|
|
# Upgrade the stanza
|
|
|
|
$oArchiveInfo->dbSectionSet($$oStanza{strDbVersion}, $$oStanza{ullDbSysId}, $oArchiveInfo->dbHistoryIdGet() + 1);
|
|
|
|
$oArchiveInfo->save();
|
|
|
|
|
|
|
|
$oBackupInfo->dbSectionSet($$oStanza{strDbVersion}, $$oStanza{iControlVersion}, $$oStanza{iCatalogVersion},
|
|
|
|
$$oStanza{ullDbSysId}, $oBackupInfo->dbHistoryIdGet() + 1);
|
|
|
|
$oBackupInfo->save();
|
|
|
|
}
|
|
|
|
|
|
|
|
# Get the archive and directory paths for the stanza
|
2017-06-09 23:51:41 +02:00
|
|
|
$$oStanza{strArchiveClusterPath} = $self->{oStorageRepo}->pathGet(STORAGE_REPO_ARCHIVE) . '/' . ($oArchiveInfo->archiveId());
|
|
|
|
$$oStanza{strBackupClusterPath} = $self->{oStorageRepo}->pathGet(STORAGE_REPO_BACKUP);
|
|
|
|
storageRepo()->pathCreate($$oStanza{strArchiveClusterPath}, {bCreateParent => true});
|
2017-04-03 16:42:55 +02:00
|
|
|
|
|
|
|
$self->{oStanzaHash}{$strStanza} = $oStanza;
|
|
|
|
|
|
|
|
# Return from function and log return values if any
|
|
|
|
return logDebugReturn($strOperation);
|
|
|
|
}
|
|
|
|
|
|
|
|
####################################################################################################################################
|
|
|
|
# stanzaCreate
|
|
|
|
####################################################################################################################################
|
|
|
|
sub stanzaCreate
|
|
|
|
{
|
|
|
|
my $self = shift;
|
|
|
|
|
|
|
|
# Assign function parameters, defaults, and log debug info
|
|
|
|
my
|
|
|
|
(
|
|
|
|
$strOperation,
|
|
|
|
$strStanza,
|
|
|
|
$strDbVersion,
|
|
|
|
) =
|
|
|
|
logDebugParam
|
|
|
|
(
|
|
|
|
__PACKAGE__ . '->stanzaCreate', \@_,
|
|
|
|
{name => 'strStanza'},
|
|
|
|
{name => 'strDbVersion'},
|
|
|
|
);
|
2015-09-02 01:05:10 +02:00
|
|
|
|
|
|
|
my $strDbVersionTemp = $strDbVersion;
|
|
|
|
$strDbVersionTemp =~ s/\.//;
|
|
|
|
|
2017-08-25 22:47:47 +02:00
|
|
|
my $strDbPath = cfgOption(CFGOPT_DB_PATH);
|
2017-04-03 16:42:55 +02:00
|
|
|
|
|
|
|
# Create the test path for pg_control
|
2017-06-09 23:51:41 +02:00
|
|
|
storageTest()->pathCreate(($strDbPath . '/' . DB_PATH_GLOBAL), {bIgnoreExists => true});
|
2017-04-03 16:42:55 +02:00
|
|
|
|
|
|
|
# Copy pg_control for stanza-create
|
|
|
|
executeTest(
|
|
|
|
'cp ' . $self->{oRunTest}->dataPath() . '/backup.pg_control_' . $strDbVersionTemp . '.bin ' . $strDbPath .
|
|
|
|
'/' . DB_FILE_PGCONTROL);
|
|
|
|
executeTest('sudo chmod 600 ' . $strDbPath . '/' . DB_FILE_PGCONTROL);
|
|
|
|
|
|
|
|
# Create the stanza and set the local stanza object
|
|
|
|
$self->stanzaSet($strStanza, $strDbVersion, false);
|
2015-09-02 01:05:10 +02:00
|
|
|
|
2017-04-03 16:42:55 +02:00
|
|
|
# Return from function and log return values if any
|
|
|
|
return logDebugReturn($strOperation);
|
|
|
|
}
|
2015-09-02 01:05:10 +02:00
|
|
|
|
2017-04-03 16:42:55 +02:00
|
|
|
####################################################################################################################################
|
|
|
|
# stanzaUpgrade
|
|
|
|
####################################################################################################################################
|
|
|
|
sub stanzaUpgrade
|
|
|
|
{
|
|
|
|
my $self = shift;
|
2015-09-02 01:05:10 +02:00
|
|
|
|
2017-04-03 16:42:55 +02:00
|
|
|
# Assign function parameters, defaults, and log debug info
|
|
|
|
my
|
|
|
|
(
|
|
|
|
$strOperation,
|
|
|
|
$strStanza,
|
|
|
|
$strDbVersion,
|
|
|
|
) =
|
|
|
|
logDebugParam
|
|
|
|
(
|
|
|
|
__PACKAGE__ . '->stanzaUpgrade', \@_,
|
|
|
|
{name => 'strStanza'},
|
|
|
|
{name => 'strDbVersion'},
|
|
|
|
);
|
2015-09-02 01:05:10 +02:00
|
|
|
|
2017-04-03 16:42:55 +02:00
|
|
|
my $strDbVersionTemp = $strDbVersion;
|
|
|
|
$strDbVersionTemp =~ s/\.//;
|
2015-09-02 01:05:10 +02:00
|
|
|
|
2017-04-03 16:42:55 +02:00
|
|
|
# Remove pg_control
|
2017-08-25 22:47:47 +02:00
|
|
|
storageTest()->remove(cfgOption(CFGOPT_DB_PATH) . '/' . DB_FILE_PGCONTROL);
|
2015-09-02 01:05:10 +02:00
|
|
|
|
2017-04-03 16:42:55 +02:00
|
|
|
# Copy pg_control for stanza-upgrade
|
|
|
|
executeTest(
|
2017-08-25 22:47:47 +02:00
|
|
|
'cp ' . $self->{oRunTest}->dataPath() . '/backup.pg_control_' . $strDbVersionTemp . '.bin ' . cfgOption(CFGOPT_DB_PATH) .
|
2017-04-03 16:42:55 +02:00
|
|
|
'/' . DB_FILE_PGCONTROL);
|
2017-08-25 22:47:47 +02:00
|
|
|
executeTest('sudo chmod 600 ' . cfgOption(CFGOPT_DB_PATH) . '/' . DB_FILE_PGCONTROL);
|
2015-09-02 01:05:10 +02:00
|
|
|
|
2017-04-03 16:42:55 +02:00
|
|
|
$self->stanzaSet($strStanza, $strDbVersion, true);
|
2015-09-02 01:05:10 +02:00
|
|
|
|
|
|
|
# Return from function and log return values if any
|
2016-08-11 23:32:28 +02:00
|
|
|
return logDebugReturn($strOperation);
|
2015-09-02 01:05:10 +02:00
|
|
|
}
|
|
|
|
####################################################################################################################################
|
|
|
|
# backupCreate
|
|
|
|
####################################################################################################################################
|
|
|
|
sub backupCreate
|
|
|
|
{
|
|
|
|
my $self = shift;
|
|
|
|
|
|
|
|
# Assign function parameters, defaults, and log debug info
|
|
|
|
my
|
|
|
|
(
|
|
|
|
$strOperation,
|
|
|
|
$strStanza,
|
|
|
|
$strType,
|
|
|
|
$lTimestamp,
|
|
|
|
$iArchiveBackupTotal,
|
|
|
|
$iArchiveBetweenTotal
|
|
|
|
) =
|
|
|
|
logDebugParam
|
|
|
|
(
|
2016-08-11 23:32:28 +02:00
|
|
|
__PACKAGE__ . '->backupCreate', \@_,
|
2015-09-02 01:05:10 +02:00
|
|
|
{name => 'strStanza'},
|
|
|
|
{name => 'strType'},
|
|
|
|
{name => 'lTimestamp'},
|
|
|
|
{name => 'iArchiveBackupTotal', default => 3},
|
|
|
|
{name => 'iArchiveBetweenTotal', default => 3}
|
|
|
|
);
|
|
|
|
|
|
|
|
my $oStanza = $self->{oStanzaHash}{$strStanza};
|
|
|
|
|
2017-02-05 17:31:29 +02:00
|
|
|
my ($strArchiveStart, $strArchiveStop);
|
|
|
|
|
|
|
|
if ($iArchiveBackupTotal != -1)
|
|
|
|
{
|
|
|
|
($strArchiveStart, $strArchiveStop) = $self->archiveCreate($strStanza, $iArchiveBackupTotal);
|
|
|
|
}
|
2015-09-02 01:05:10 +02:00
|
|
|
|
|
|
|
# Create the manifest
|
2017-08-25 22:47:47 +02:00
|
|
|
my $oLastManifest = $strType ne CFGOPTVAL_BACKUP_TYPE_FULL ? $$oStanza{oManifest} : undef;
|
2015-09-02 01:05:10 +02:00
|
|
|
|
|
|
|
my $strBackupLabel =
|
|
|
|
backupLabelFormat($strType,
|
|
|
|
defined($oLastManifest) ? $oLastManifest->get(MANIFEST_SECTION_BACKUP, MANIFEST_KEY_LABEL) : undef,
|
|
|
|
$lTimestamp);
|
|
|
|
|
2017-04-10 23:23:39 +02:00
|
|
|
my $strBackupClusterSetPath = "$$oStanza{strBackupClusterPath}/${strBackupLabel}";
|
2017-06-09 23:51:41 +02:00
|
|
|
storageRepo()->pathCreate($strBackupClusterSetPath);
|
2015-09-02 01:05:10 +02:00
|
|
|
|
2016-04-15 04:50:02 +02:00
|
|
|
&log(INFO, "create backup ${strBackupLabel}");
|
|
|
|
|
2017-11-06 19:51:12 +02:00
|
|
|
# Get passphrase (returns undefined if repo not encrypted) to access the manifest
|
|
|
|
my $strCipherPassManifest =
|
|
|
|
(new pgBackRest::Backup::Info($self->{oStorageRepo}->pathGet(STORAGE_REPO_BACKUP)))->cipherPassSub();
|
|
|
|
my $strCipherPassBackupSet;
|
|
|
|
|
|
|
|
# If repo is encrypted then get passphrase for accessing the backup files from the last manifest if it exists provide one
|
|
|
|
if (defined($strCipherPassManifest))
|
|
|
|
{
|
|
|
|
$strCipherPassBackupSet = (defined($oLastManifest)) ? $oLastManifest->cipherPassSub() :
|
|
|
|
ENCRYPTION_KEY_BACKUPSET;
|
|
|
|
}
|
|
|
|
|
2016-04-15 04:50:02 +02:00
|
|
|
my $strManifestFile = "$$oStanza{strBackupClusterPath}/${strBackupLabel}/" . FILE_MANIFEST;
|
2017-11-06 19:51:12 +02:00
|
|
|
|
|
|
|
my $oManifest = new pgBackRest::Manifest($strManifestFile, {bLoad => false, strDbVersion => PG_VERSION_93,
|
|
|
|
strCipherPass => $strCipherPassManifest, strCipherPassSub => $strCipherPassBackupSet});
|
2015-09-02 01:05:10 +02:00
|
|
|
|
|
|
|
# Store information about the backup into the backup section
|
|
|
|
$oManifest->set(MANIFEST_SECTION_BACKUP, MANIFEST_KEY_LABEL, undef, $strBackupLabel);
|
|
|
|
$oManifest->boolSet(MANIFEST_SECTION_BACKUP_OPTION, MANIFEST_KEY_ARCHIVE_CHECK, undef, true);
|
|
|
|
$oManifest->boolSet(MANIFEST_SECTION_BACKUP_OPTION, MANIFEST_KEY_ARCHIVE_COPY, undef, false);
|
2016-08-25 17:25:46 +02:00
|
|
|
$oManifest->boolSet(MANIFEST_SECTION_BACKUP_OPTION, MANIFEST_KEY_BACKUP_STANDBY, undef, false);
|
2015-09-02 01:05:10 +02:00
|
|
|
$oManifest->set(MANIFEST_SECTION_BACKUP, MANIFEST_KEY_ARCHIVE_START, undef, $strArchiveStart);
|
|
|
|
$oManifest->set(MANIFEST_SECTION_BACKUP, MANIFEST_KEY_ARCHIVE_STOP, undef, $strArchiveStop);
|
2016-12-13 01:54:07 +02:00
|
|
|
$oManifest->boolSet(MANIFEST_SECTION_BACKUP_OPTION, MANIFEST_KEY_CHECKSUM_PAGE, undef, true);
|
2015-09-02 01:05:10 +02:00
|
|
|
$oManifest->boolSet(MANIFEST_SECTION_BACKUP_OPTION, MANIFEST_KEY_COMPRESS, undef, true);
|
|
|
|
$oManifest->numericSet(INI_SECTION_BACKREST, INI_KEY_FORMAT, undef, BACKREST_FORMAT);
|
|
|
|
$oManifest->boolSet(MANIFEST_SECTION_BACKUP_OPTION, MANIFEST_KEY_HARDLINK, undef, false);
|
2016-02-20 02:32:02 +02:00
|
|
|
$oManifest->boolSet(MANIFEST_SECTION_BACKUP_OPTION, MANIFEST_KEY_ONLINE, undef, true);
|
2015-09-02 01:05:10 +02:00
|
|
|
$oManifest->numericSet(MANIFEST_SECTION_BACKUP, MANIFEST_KEY_TIMESTAMP_START, undef, $lTimestamp);
|
|
|
|
$oManifest->numericSet(MANIFEST_SECTION_BACKUP, MANIFEST_KEY_TIMESTAMP_STOP, undef, $lTimestamp);
|
|
|
|
$oManifest->set(MANIFEST_SECTION_BACKUP, MANIFEST_KEY_TYPE, undef, $strType);
|
|
|
|
$oManifest->set(INI_SECTION_BACKREST, INI_KEY_VERSION, undef, BACKREST_VERSION);
|
|
|
|
|
2017-08-25 22:47:47 +02:00
|
|
|
if ($strType ne CFGOPTVAL_BACKUP_TYPE_FULL)
|
2015-09-02 01:05:10 +02:00
|
|
|
{
|
|
|
|
if (!defined($oLastManifest))
|
|
|
|
{
|
|
|
|
confess &log(ERROR, "oLastManifest must be defined when strType = ${strType}");
|
|
|
|
}
|
|
|
|
|
|
|
|
push(my @stryReference, $oLastManifest->get(MANIFEST_SECTION_BACKUP, MANIFEST_KEY_LABEL));
|
|
|
|
|
|
|
|
$oManifest->set(MANIFEST_SECTION_BACKUP, MANIFEST_KEY_PRIOR, undef, $stryReference[0]);
|
|
|
|
}
|
|
|
|
|
|
|
|
$oManifest->save();
|
|
|
|
$$oStanza{oManifest} = $oManifest;
|
|
|
|
|
|
|
|
# Add the backup to info
|
2017-05-15 22:01:00 +02:00
|
|
|
my $oBackupInfo = new pgBackRest::Backup::Info($$oStanza{strBackupClusterPath}, false);
|
2015-09-02 01:05:10 +02:00
|
|
|
|
|
|
|
$oBackupInfo->check($$oStanza{strDbVersion}, $$oStanza{iControlVersion}, $$oStanza{iCatalogVersion}, $$oStanza{ullDbSysId});
|
2016-04-15 04:50:02 +02:00
|
|
|
$oBackupInfo->add($oManifest);
|
2015-09-02 01:05:10 +02:00
|
|
|
|
|
|
|
# Create the backup description string
|
|
|
|
if (defined($$oStanza{strBackupDescription}))
|
|
|
|
{
|
|
|
|
$$oStanza{strBackupDescription} .= "\n";
|
|
|
|
}
|
|
|
|
|
|
|
|
$$oStanza{strBackupDescription} .=
|
|
|
|
"* ${strType} backup: label = ${strBackupLabel}" .
|
|
|
|
(defined($oLastManifest) ? ', prior = ' . $oLastManifest->get(MANIFEST_SECTION_BACKUP, MANIFEST_KEY_LABEL) : '') .
|
2017-02-05 17:31:29 +02:00
|
|
|
(defined($strArchiveStart) ? ", start = ${strArchiveStart}, stop = ${strArchiveStop}" : ', not online');
|
2015-09-02 01:05:10 +02:00
|
|
|
|
2017-02-05 17:31:29 +02:00
|
|
|
if ($iArchiveBetweenTotal != -1)
|
|
|
|
{
|
|
|
|
$self->archiveCreate($strStanza, $iArchiveBetweenTotal);
|
|
|
|
}
|
2015-09-02 01:05:10 +02:00
|
|
|
|
|
|
|
# Return from function and log return values if any
|
2016-08-11 23:32:28 +02:00
|
|
|
return logDebugReturn($strOperation);
|
2015-09-02 01:05:10 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
####################################################################################################################################
|
|
|
|
# archiveNext
|
|
|
|
####################################################################################################################################
|
|
|
|
sub archiveNext
|
|
|
|
{
|
|
|
|
my $self = shift;
|
|
|
|
|
|
|
|
# Assign function parameters, defaults, and log debug info
|
|
|
|
my
|
|
|
|
(
|
|
|
|
$strOperation,
|
|
|
|
$strArchive,
|
|
|
|
$bSkipFF
|
|
|
|
) =
|
|
|
|
logDebugParam
|
|
|
|
(
|
2016-08-11 23:32:28 +02:00
|
|
|
__PACKAGE__ . '->archiveNext', \@_,
|
2015-09-02 01:05:10 +02:00
|
|
|
{name => 'strArchive', trace => true},
|
|
|
|
{name => 'bSkipFF', trace => true}
|
|
|
|
);
|
|
|
|
|
|
|
|
# Break archive log into components
|
|
|
|
my $lTimeline = hex(substr($strArchive, 0, 8));
|
|
|
|
my $lMajor = hex(substr($strArchive, 8, 8));
|
|
|
|
my $lMinor = hex(substr($strArchive, 16, 8));
|
|
|
|
|
|
|
|
# Increment the minor component (and major when needed)
|
|
|
|
$lMinor += 1;
|
|
|
|
|
|
|
|
if ($bSkipFF && $lMinor == 255 || !$bSkipFF && $lMinor == 256)
|
|
|
|
{
|
|
|
|
$lMajor += 1;
|
|
|
|
$lMinor = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
# Return from function and log return values if any
|
|
|
|
return logDebugReturn
|
|
|
|
(
|
|
|
|
$strOperation,
|
|
|
|
{name => 'strArchiveNext', value => uc(sprintf("%08x%08x%08x", $lTimeline, $lMajor, $lMinor)), trace => true}
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
####################################################################################################################################
|
|
|
|
# archiveCreate
|
|
|
|
####################################################################################################################################
|
|
|
|
sub archiveCreate
|
|
|
|
{
|
|
|
|
my $self = shift;
|
|
|
|
|
|
|
|
# Assign function parameters, defaults, and log debug info
|
|
|
|
my
|
|
|
|
(
|
|
|
|
$strOperation,
|
|
|
|
$strStanza,
|
|
|
|
$iArchiveTotal
|
|
|
|
) =
|
|
|
|
logDebugParam
|
|
|
|
(
|
2016-08-11 23:32:28 +02:00
|
|
|
__PACKAGE__ . '->archiveCreate', \@_,
|
2015-09-02 01:05:10 +02:00
|
|
|
{name => 'strStanza'},
|
|
|
|
{name => 'iArchiveTotal'}
|
|
|
|
);
|
|
|
|
|
|
|
|
my $oStanza = $self->{oStanzaHash}{$strStanza};
|
|
|
|
my $iArchiveIdx = 0;
|
2016-05-14 16:33:12 +02:00
|
|
|
my $bSkipFF = $$oStanza{strDbVersion} <= PG_VERSION_92;
|
2015-09-02 01:05:10 +02:00
|
|
|
|
|
|
|
my $strArchive = defined($$oStanza{strArchiveLast}) ? $self->archiveNext($$oStanza{strArchiveLast}, $bSkipFF) :
|
|
|
|
'000000010000000000000000';
|
|
|
|
|
2017-11-06 19:51:12 +02:00
|
|
|
# Get passphrase (returns undefined if repo not encrypted) to access the archive files
|
|
|
|
my $strCipherPass =
|
|
|
|
(new pgBackRest::Archive::Info($self->{oStorageRepo}->pathGet(STORAGE_REPO_ARCHIVE)))->cipherPassSub();
|
|
|
|
|
2015-09-02 01:05:10 +02:00
|
|
|
push(my @stryArchive, $strArchive);
|
|
|
|
|
|
|
|
do
|
|
|
|
{
|
|
|
|
my $strPath = "$$oStanza{strArchiveClusterPath}/" . substr($strArchive, 0, 16);
|
2017-06-09 23:51:41 +02:00
|
|
|
storageRepo()->pathCreate($strPath, {bIgnoreExists => true});
|
2015-09-02 01:05:10 +02:00
|
|
|
|
|
|
|
my $strFile = "${strPath}/${strArchive}-0000000000000000000000000000000000000000" . ($iArchiveIdx % 2 == 0 ? '.gz' : '');
|
2017-11-06 19:51:12 +02:00
|
|
|
|
|
|
|
storageRepo()->put($strFile, 'ARCHIVE', {strCipherPass => $strCipherPass});
|
2015-09-02 01:05:10 +02:00
|
|
|
|
|
|
|
$iArchiveIdx++;
|
|
|
|
|
|
|
|
if ($iArchiveIdx < $iArchiveTotal)
|
|
|
|
{
|
|
|
|
$strArchive = $self->archiveNext($strArchive, $bSkipFF);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
while ($iArchiveIdx < $iArchiveTotal);
|
|
|
|
|
|
|
|
push(@stryArchive, $strArchive);
|
|
|
|
$$oStanza{strArchiveLast} = $strArchive;
|
|
|
|
|
|
|
|
# Return from function and log return values if any
|
|
|
|
return logDebugReturn
|
|
|
|
(
|
|
|
|
$strOperation,
|
|
|
|
{name => 'stryArchive', value => \@stryArchive}
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
2016-01-19 14:39:29 +02:00
|
|
|
####################################################################################################################################
|
|
|
|
# supplementalLog
|
|
|
|
####################################################################################################################################
|
|
|
|
sub supplementalLog
|
|
|
|
{
|
|
|
|
my $self = shift;
|
|
|
|
|
|
|
|
# Assign function parameters, defaults, and log debug info
|
|
|
|
my
|
|
|
|
(
|
|
|
|
$strOperation,
|
|
|
|
$strStanza
|
|
|
|
) =
|
|
|
|
logDebugParam
|
|
|
|
(
|
2016-08-11 23:32:28 +02:00
|
|
|
__PACKAGE__ . '->supplementalLog', \@_,
|
2016-01-19 14:39:29 +02:00
|
|
|
{name => 'strStanza'}
|
|
|
|
);
|
|
|
|
|
|
|
|
my $oStanza = $self->{oStanzaHash}{$strStanza};
|
|
|
|
|
|
|
|
if (defined($self->{oLogTest}))
|
|
|
|
{
|
2017-06-09 23:51:41 +02:00
|
|
|
$self->{oLogTest}->supplementalAdd(
|
|
|
|
$self->{oHostBackup}->repoPath() . "/backup/${strStanza}/backup.info", $$oStanza{strBackupDescription},
|
|
|
|
${storageRepo->get($self->{oHostBackup}->repoPath() . "/backup/${strStanza}/backup.info")});
|
|
|
|
|
|
|
|
# Output backup list
|
|
|
|
$self->{oLogTest}->logAdd(
|
|
|
|
'ls ' . $self->{oHostBackup}->repoPath() . "/backup/${strStanza} | grep -v \"backup.*\"", undef,
|
|
|
|
join("\n", grep(!/^backup\.info.*$/i, storageRepo()->list("backup/${strStanza}"))));
|
2016-06-24 14:12:58 +02:00
|
|
|
|
2017-06-09 23:51:41 +02:00
|
|
|
# Output archive manifest
|
|
|
|
my $rhManifest = storageRepo()->manifest(STORAGE_REPO_ARCHIVE);
|
|
|
|
my $strManifest;
|
|
|
|
my $strPrefix = '';
|
|
|
|
|
|
|
|
foreach my $strEntry (sort(keys(%{$rhManifest})))
|
|
|
|
{
|
|
|
|
# Skip files
|
|
|
|
next if $strEntry eq ARCHIVE_INFO_FILE || $strEntry eq ARCHIVE_INFO_FILE . INI_COPY_EXT;
|
|
|
|
|
|
|
|
if ($rhManifest->{$strEntry}->{type} eq 'd')
|
|
|
|
{
|
|
|
|
$strEntry = storageRepo()->pathGet(STORAGE_REPO_ARCHIVE) . ($strEntry eq '.' ? '' : "/${strEntry}");
|
|
|
|
|
|
|
|
# &log(WARN, "DIR $strEntry");
|
|
|
|
$strManifest .= (defined($strManifest) ? "\n" : '') . "${strEntry}:\n";
|
|
|
|
$strPrefix = $strEntry;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
# &log(WARN, "FILE $strEntry");
|
|
|
|
$strManifest .= basename($strEntry) . "\n";
|
|
|
|
}
|
|
|
|
}
|
2016-01-19 14:39:29 +02:00
|
|
|
|
2017-06-09 23:51:41 +02:00
|
|
|
$self->{oLogTest}->logAdd(
|
|
|
|
'ls -R ' . $self->{oHostBackup}->repoPath() . "/archive/${strStanza} | grep -v \"archive.info\"", undef, $strManifest);
|
2016-01-19 14:39:29 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
return logDebugReturn($strOperation);
|
|
|
|
}
|
|
|
|
|
2015-09-02 01:05:10 +02:00
|
|
|
####################################################################################################################################
|
|
|
|
# process
|
|
|
|
####################################################################################################################################
|
|
|
|
sub process
|
|
|
|
{
|
|
|
|
my $self = shift;
|
|
|
|
|
|
|
|
# Assign function parameters, defaults, and log debug info
|
|
|
|
my
|
|
|
|
(
|
|
|
|
$strOperation,
|
|
|
|
$strStanza,
|
|
|
|
$iExpireFull,
|
|
|
|
$iExpireDiff,
|
|
|
|
$strExpireArchiveType,
|
|
|
|
$iExpireArchive,
|
|
|
|
$strDescription
|
|
|
|
) =
|
|
|
|
logDebugParam
|
|
|
|
(
|
2016-08-11 23:32:28 +02:00
|
|
|
__PACKAGE__ . '->process', \@_,
|
2015-09-02 01:05:10 +02:00
|
|
|
{name => 'strStanza'},
|
2016-09-07 14:07:37 +02:00
|
|
|
{name => 'iExpireFull', required => false},
|
|
|
|
{name => 'iExpireDiff', required => false},
|
2015-09-02 01:05:10 +02:00
|
|
|
{name => 'strExpireArchiveType'},
|
2016-09-07 14:07:37 +02:00
|
|
|
{name => 'iExpireArchive', required => false},
|
2015-09-02 01:05:10 +02:00
|
|
|
{name => 'strDescription'}
|
|
|
|
);
|
|
|
|
|
|
|
|
my $oStanza = $self->{oStanzaHash}{$strStanza};
|
|
|
|
|
2016-01-19 14:39:29 +02:00
|
|
|
$self->supplementalLog($strStanza);
|
2015-10-08 17:43:56 +02:00
|
|
|
|
2015-09-02 01:05:10 +02:00
|
|
|
undef($$oStanza{strBackupDescription});
|
|
|
|
|
2016-12-23 15:22:59 +02:00
|
|
|
my $strCommand = $self->{strBackRestExe} .
|
2017-08-25 22:47:47 +02:00
|
|
|
' --' . cfgOptionName(CFGOPT_CONFIG) . '="' . $self->{oHostBackup}->backrestConfig() . '"' .
|
|
|
|
' --' . cfgOptionName(CFGOPT_STANZA) . '=' . $strStanza .
|
|
|
|
' --' . cfgOptionName(CFGOPT_LOG_LEVEL_CONSOLE) . '=' . lc(DETAIL);
|
2015-09-02 01:05:10 +02:00
|
|
|
|
|
|
|
if (defined($iExpireFull))
|
|
|
|
{
|
|
|
|
$strCommand .= ' --retention-full=' . $iExpireFull;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (defined($iExpireDiff))
|
|
|
|
{
|
|
|
|
$strCommand .= ' --retention-diff=' . $iExpireDiff;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (defined($strExpireArchiveType))
|
|
|
|
{
|
2016-09-07 14:07:37 +02:00
|
|
|
if (defined($iExpireArchive))
|
|
|
|
{
|
|
|
|
$strCommand .= ' --retention-archive-type=' . $strExpireArchiveType .
|
|
|
|
' --retention-archive=' . $iExpireArchive;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
$strCommand .= ' --retention-archive-type=' . $strExpireArchiveType;
|
|
|
|
}
|
2015-09-02 01:05:10 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
$strCommand .= ' expire';
|
|
|
|
|
2016-06-24 14:12:58 +02:00
|
|
|
$self->{oHostBackup}->executeSimple($strCommand, {strComment => $strDescription, oLogTest => $self->{oLogTest}});
|
2015-10-08 17:43:56 +02:00
|
|
|
|
2016-01-19 14:39:29 +02:00
|
|
|
$self->supplementalLog($strStanza);
|
2015-09-02 01:05:10 +02:00
|
|
|
|
|
|
|
# Return from function and log return values if any
|
2016-01-19 14:39:29 +02:00
|
|
|
return logDebugReturn($strOperation);
|
2015-09-02 01:05:10 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
1;
|