2016-12-23 15:22:59 +02:00
|
|
|
####################################################################################################################################
|
2017-06-20 00:55:00 +02:00
|
|
|
# Test All Commands on Mock Data
|
2016-12-23 15:22:59 +02:00
|
|
|
####################################################################################################################################
|
2017-06-20 00:55:00 +02:00
|
|
|
package pgBackRestTest::Module::Mock::MockAllTest;
|
2017-05-12 22:43:04 +02:00
|
|
|
use parent 'pgBackRestTest::Env::HostEnvTest';
|
2016-12-23 15:22:59 +02:00
|
|
|
|
|
|
|
####################################################################################################################################
|
|
|
|
# Perl includes
|
|
|
|
####################################################################################################################################
|
|
|
|
use strict;
|
|
|
|
use warnings FATAL => qw(all);
|
|
|
|
use Carp qw(confess);
|
|
|
|
|
2017-04-10 19:24:45 +02:00
|
|
|
use File::Basename qw(basename dirname);
|
2016-12-23 15:22:59 +02:00
|
|
|
|
2020-03-10 21:41:56 +02:00
|
|
|
use pgBackRestDoc::Common::Exception;
|
|
|
|
use pgBackRestDoc::Common::Ini;
|
|
|
|
use pgBackRestDoc::Common::Log;
|
|
|
|
use pgBackRestDoc::Common::String;
|
2020-03-10 23:57:02 +02:00
|
|
|
use pgBackRestDoc::ProjectInfo;
|
2020-03-10 21:12:44 +02:00
|
|
|
|
2016-12-23 15:22:59 +02:00
|
|
|
use pgBackRestTest::Common::ContainerTest;
|
2020-03-10 21:12:44 +02:00
|
|
|
use pgBackRestTest::Common::DbVersion;
|
2016-12-23 15:22:59 +02:00
|
|
|
use pgBackRestTest::Common::ExecuteTest;
|
|
|
|
use pgBackRestTest::Common::FileTest;
|
|
|
|
use pgBackRestTest::Common::RunTest;
|
2020-03-10 21:12:44 +02:00
|
|
|
use pgBackRestTest::Common::StorageRepo;
|
2019-03-02 15:01:02 +02:00
|
|
|
use pgBackRestTest::Common::VmTest;
|
2020-03-10 21:12:44 +02:00
|
|
|
use pgBackRestTest::Common::Wait;
|
|
|
|
use pgBackRestTest::Env::ArchiveInfo;
|
|
|
|
use pgBackRestTest::Env::BackupInfo;
|
2017-05-12 22:43:04 +02:00
|
|
|
use pgBackRestTest::Env::Host::HostBackupTest;
|
2017-06-12 16:52:32 +02:00
|
|
|
use pgBackRestTest::Env::Host::HostS3Test;
|
|
|
|
use pgBackRestTest::Env::HostEnvTest;
|
2020-03-10 21:12:44 +02:00
|
|
|
use pgBackRestTest::Env::InfoCommon;
|
|
|
|
use pgBackRestTest::Env::Manifest;
|
|
|
|
|
|
|
|
####################################################################################################################################
|
|
|
|
# backupRegExpGet
|
|
|
|
#
|
|
|
|
# Generate a regexp depending on the backups that need to be found.
|
|
|
|
####################################################################################################################################
|
|
|
|
sub backupRegExpGet
|
|
|
|
{
|
|
|
|
# Assign function parameters, defaults, and log debug info
|
|
|
|
my
|
|
|
|
(
|
|
|
|
$strOperation,
|
|
|
|
$bFull,
|
|
|
|
$bDifferential,
|
|
|
|
$bIncremental,
|
|
|
|
$bAnchor
|
|
|
|
) =
|
|
|
|
logDebugParam
|
|
|
|
(
|
|
|
|
__PACKAGE__ . '::backupRegExpGet', \@_,
|
|
|
|
{name => 'bFull', default => false},
|
|
|
|
{name => 'bDifferential', default => false},
|
|
|
|
{name => 'bIncremental', default => false},
|
|
|
|
{name => 'bAnchor', default => true}
|
|
|
|
);
|
|
|
|
|
|
|
|
# One of the types must be selected
|
|
|
|
if (!($bFull || $bDifferential || $bIncremental))
|
|
|
|
{
|
|
|
|
confess &log(ASSERT, 'at least one backup type must be selected');
|
|
|
|
}
|
|
|
|
|
|
|
|
# Standard regexp to match date and time formatting
|
|
|
|
my $strDateTimeRegExp = "[0-9]{8}\\-[0-9]{6}";
|
|
|
|
# Start the expression with the anchor if requested, date/time regexp and full backup indicator
|
|
|
|
my $strRegExp = ($bAnchor ? '^' : '') . $strDateTimeRegExp . 'F';
|
|
|
|
|
|
|
|
# Add the diff and/or incr expressions if requested
|
|
|
|
if ($bDifferential || $bIncremental)
|
|
|
|
{
|
|
|
|
# If full requested then diff/incr is optional
|
|
|
|
if ($bFull)
|
|
|
|
{
|
|
|
|
$strRegExp .= "(\\_";
|
|
|
|
}
|
|
|
|
# Else diff/incr is required
|
|
|
|
else
|
|
|
|
{
|
|
|
|
$strRegExp .= "\\_";
|
|
|
|
}
|
|
|
|
|
|
|
|
# Append date/time regexp for diff/incr
|
|
|
|
$strRegExp .= $strDateTimeRegExp;
|
|
|
|
|
|
|
|
# Filter on both diff/incr
|
|
|
|
if ($bDifferential && $bIncremental)
|
|
|
|
{
|
|
|
|
$strRegExp .= '(D|I)';
|
|
|
|
}
|
|
|
|
# Else just diff
|
|
|
|
elsif ($bDifferential)
|
|
|
|
{
|
|
|
|
$strRegExp .= 'D';
|
|
|
|
}
|
|
|
|
# Else just incr
|
|
|
|
else
|
|
|
|
{
|
|
|
|
$strRegExp .= 'I';
|
|
|
|
}
|
|
|
|
|
|
|
|
# If full requested then diff/incr is optional
|
|
|
|
if ($bFull)
|
|
|
|
{
|
|
|
|
$strRegExp .= '){0,1}';
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
# Append the end anchor if requested
|
|
|
|
$strRegExp .= $bAnchor ? "\$" : '';
|
|
|
|
|
|
|
|
# Return from function and log return values if any
|
|
|
|
return logDebugReturn
|
|
|
|
(
|
|
|
|
$strOperation,
|
|
|
|
{name => 'strRegExp', value => $strRegExp}
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
####################################################################################################################################
|
|
|
|
# backupLabel
|
|
|
|
#
|
|
|
|
# Get unique backup label.
|
|
|
|
####################################################################################################################################
|
|
|
|
sub backupLabel
|
|
|
|
{
|
|
|
|
# Assign function parameters, defaults, and log debug info
|
|
|
|
my
|
|
|
|
(
|
|
|
|
$strOperation,
|
|
|
|
$oStorageRepo,
|
|
|
|
$strRepoBackupPath,
|
|
|
|
$strType,
|
|
|
|
$strBackupLabelLast,
|
|
|
|
$lTimestampStart
|
|
|
|
) =
|
|
|
|
logDebugParam
|
|
|
|
(
|
|
|
|
__PACKAGE__ . '::backupLabelFormat', \@_,
|
|
|
|
{name => 'oStorageRepo', trace => true},
|
|
|
|
{name => 'strRepoBackupPath', trace => true},
|
|
|
|
{name => 'strType', trace => true},
|
|
|
|
{name => 'strBackupLabelLast', required => false, trace => true},
|
|
|
|
{name => 'lTimestampStart', trace => true}
|
|
|
|
);
|
|
|
|
|
|
|
|
# Create backup label
|
|
|
|
my $strBackupLabel = backupLabelFormat($strType, $strBackupLabelLast, $lTimestampStart);
|
|
|
|
|
|
|
|
# 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 ($oStorageRepo->list(
|
|
|
|
$strRepoBackupPath,
|
|
|
|
{strExpression =>
|
|
|
|
($strType eq CFGOPTVAL_BACKUP_TYPE_FULL ? '^' : '_') . timestampFileFormat(undef, $lTimestampStart) .
|
|
|
|
($strType eq CFGOPTVAL_BACKUP_TYPE_FULL ? 'F' : '(D|I)$')}) ||
|
|
|
|
$oStorageRepo->list(
|
|
|
|
"${strRepoBackupPath}/" . PATH_BACKUP_HISTORY . '/' . timestampFormat('%4d', $lTimestampStart),
|
|
|
|
{strExpression =>
|
|
|
|
($strType eq CFGOPTVAL_BACKUP_TYPE_FULL ? '^' : '_') . timestampFileFormat(undef, $lTimestampStart) .
|
|
|
|
($strType eq CFGOPTVAL_BACKUP_TYPE_FULL ? 'F' : '(D|I)\.manifest\.gz$'),
|
|
|
|
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}
|
|
|
|
);
|
|
|
|
}
|
2016-12-23 15:22:59 +02:00
|
|
|
|
2017-01-30 20:59:00 +02:00
|
|
|
####################################################################################################################################
|
|
|
|
# Build PostgreSQL pages for testing
|
|
|
|
####################################################################################################################################
|
|
|
|
sub pageBuild
|
|
|
|
{
|
|
|
|
my $tPageSource = shift;
|
|
|
|
my $iBlockNo = shift;
|
2020-03-05 20:56:20 +02:00
|
|
|
my $iChecksum = shift;
|
2017-01-30 20:59:00 +02:00
|
|
|
my $iWalId = shift;
|
|
|
|
my $iWalOffset = shift;
|
|
|
|
|
2020-03-05 20:56:20 +02:00
|
|
|
return
|
|
|
|
(defined($iWalId) ? pack('I', $iWalId) . pack('I', $iWalOffset) : substr($tPageSource, 0, 8)) . pack('S', $iChecksum) .
|
|
|
|
substr($tPageSource, 10);
|
2017-01-30 20:59:00 +02:00
|
|
|
}
|
|
|
|
|
2016-12-23 15:22:59 +02:00
|
|
|
####################################################################################################################################
|
|
|
|
# run
|
|
|
|
####################################################################################################################################
|
|
|
|
sub run
|
|
|
|
{
|
|
|
|
my $self = shift;
|
|
|
|
|
2019-03-02 15:01:02 +02:00
|
|
|
foreach my $rhRun
|
|
|
|
(
|
2021-10-18 20:32:41 +02:00
|
|
|
{vm => VM2, remote => false, tls => false, storage => GCS, encrypt => false, delta => true, compress => BZ2},
|
|
|
|
{vm => VM2, remote => true, tls => false, storage => AZURE, encrypt => true, delta => false, compress => GZ},
|
|
|
|
{vm => VM3, remote => false, tls => false, storage => POSIX, encrypt => false, delta => true, compress => ZST},
|
|
|
|
{vm => VM3, remote => true, tls => true, storage => S3, encrypt => true, delta => false, compress => LZ4},
|
|
|
|
{vm => VM4, remote => false, tls => false, storage => GCS, encrypt => false, delta => false, compress => GZ},
|
|
|
|
{vm => VM4, remote => true, tls => true, storage => S3, encrypt => true, delta => true, compress => ZST},
|
2019-03-02 15:01:02 +02:00
|
|
|
)
|
2017-06-12 16:52:32 +02:00
|
|
|
{
|
2019-03-02 15:01:02 +02:00
|
|
|
# Only run tests for this vm
|
2019-11-02 11:35:48 +02:00
|
|
|
next if ($rhRun->{vm} ne vmTest($self->vm()));
|
2019-03-02 15:01:02 +02:00
|
|
|
|
|
|
|
# Increment the run, log, and decide whether this unit test should be run
|
|
|
|
my $bRemote = $rhRun->{remote};
|
2021-10-18 20:32:41 +02:00
|
|
|
my $bTls = $rhRun->{tls};
|
2020-05-13 00:55:20 +02:00
|
|
|
my $strStorage = $rhRun->{storage};
|
2019-03-02 15:01:02 +02:00
|
|
|
my $bEncrypt = $rhRun->{encrypt};
|
|
|
|
my $bDeltaBackup = $rhRun->{delta};
|
2020-03-06 21:41:03 +02:00
|
|
|
my $strCompressType = $rhRun->{compress};
|
2017-11-06 19:51:12 +02:00
|
|
|
|
2016-12-23 15:22:59 +02:00
|
|
|
# Increment the run, log, and decide whether this unit test should be run
|
2021-10-18 20:32:41 +02:00
|
|
|
if (!$self->begin("rmt ${bRemote}, tls ${bTls}, storage ${strStorage}, enc ${bEncrypt}, delta ${bDeltaBackup}")) {next}
|
2016-12-23 15:22:59 +02:00
|
|
|
|
|
|
|
# Create hosts, file object, and config
|
2020-06-16 20:06:38 +02:00
|
|
|
my ($oHostDbPrimary, $oHostDbStandby, $oHostBackup) = $self->setup(
|
2021-10-18 20:32:41 +02:00
|
|
|
true, $self->expect(),
|
|
|
|
{bHostBackup => $bRemote, bTls => $bTls, strStorage => $strStorage, bRepoEncrypt => $bEncrypt,
|
|
|
|
strCompressType => NONE});
|
2017-06-22 00:47:25 +02:00
|
|
|
|
|
|
|
# If S3 set process max to 2. This seems like the best place for parallel testing since it will help speed S3 processing
|
|
|
|
# without slowing down the other tests too much.
|
2020-05-13 00:55:20 +02:00
|
|
|
if ($strStorage eq S3)
|
2017-06-22 00:47:25 +02:00
|
|
|
{
|
2020-03-09 23:41:59 +02:00
|
|
|
$oHostBackup->configUpdate({&CFGDEF_SECTION_GLOBAL => {'process-max' => 2}});
|
2020-06-16 20:06:38 +02:00
|
|
|
$oHostDbPrimary->configUpdate({&CFGDEF_SECTION_GLOBAL => {'process-max' => 2}});
|
2017-06-22 00:47:25 +02:00
|
|
|
|
2019-05-23 00:23:44 +02:00
|
|
|
# Reduce log level to warn because parallel tests do not create deterministic logs
|
2020-03-09 23:41:59 +02:00
|
|
|
$oHostBackup->configUpdate({&CFGDEF_SECTION_GLOBAL => {'log-level-console' => lc(WARN)}});
|
2020-06-16 20:06:38 +02:00
|
|
|
$oHostDbPrimary->configUpdate({&CFGDEF_SECTION_GLOBAL => {'log-level-console' => lc(WARN)}});
|
2017-06-22 00:47:25 +02:00
|
|
|
}
|
2016-12-23 15:22:59 +02:00
|
|
|
|
|
|
|
# Get base time
|
|
|
|
my $lTime = time() - 10000;
|
|
|
|
|
|
|
|
# Build the manifest
|
|
|
|
my %oManifest;
|
|
|
|
|
2018-11-25 02:05:03 +02:00
|
|
|
$oManifest{&INI_SECTION_BACKREST}{&INI_KEY_VERSION} = PROJECT_VERSION;
|
|
|
|
$oManifest{&INI_SECTION_BACKREST}{&INI_KEY_FORMAT} = REPOSITORY_FORMAT;
|
2019-11-28 15:27:21 +02:00
|
|
|
$oManifest{&MANIFEST_SECTION_BACKUP_OPTION}{&MANIFEST_KEY_ARCHIVE_CHECK} = JSON::PP::false;
|
2016-12-23 15:22:59 +02:00
|
|
|
$oManifest{&MANIFEST_SECTION_BACKUP_OPTION}{&MANIFEST_KEY_ARCHIVE_COPY} = JSON::PP::true;
|
|
|
|
$oManifest{&MANIFEST_SECTION_BACKUP_OPTION}{&MANIFEST_KEY_BACKUP_STANDBY} = JSON::PP::false;
|
2019-03-10 11:03:52 +02:00
|
|
|
$oManifest{&MANIFEST_SECTION_BACKUP_OPTION}{&MANIFEST_KEY_BUFFER_SIZE} = 16384;
|
2016-12-23 15:22:59 +02:00
|
|
|
$oManifest{&MANIFEST_SECTION_BACKUP_OPTION}{&MANIFEST_KEY_CHECKSUM_PAGE} = JSON::PP::true;
|
2017-06-15 21:32:10 +02:00
|
|
|
$oManifest{&MANIFEST_SECTION_BACKUP_OPTION}{&MANIFEST_KEY_COMPRESS} = JSON::PP::false;
|
2020-03-09 23:41:59 +02:00
|
|
|
$oManifest{&MANIFEST_SECTION_BACKUP_OPTION}{&MANIFEST_KEY_COMPRESS_TYPE} = NONE;
|
2019-03-10 11:03:52 +02:00
|
|
|
$oManifest{&MANIFEST_SECTION_BACKUP_OPTION}{&MANIFEST_KEY_COMPRESS_LEVEL} = 3;
|
|
|
|
$oManifest{&MANIFEST_SECTION_BACKUP_OPTION}{&MANIFEST_KEY_COMPRESS_LEVEL_NETWORK} = $bRemote ? 1 : 3;
|
2017-06-15 21:32:10 +02:00
|
|
|
$oManifest{&MANIFEST_SECTION_BACKUP_OPTION}{&MANIFEST_KEY_HARDLINK} = JSON::PP::false;
|
2016-12-23 15:22:59 +02:00
|
|
|
$oManifest{&MANIFEST_SECTION_BACKUP_OPTION}{&MANIFEST_KEY_ONLINE} = JSON::PP::false;
|
2020-05-13 00:55:20 +02:00
|
|
|
$oManifest{&MANIFEST_SECTION_BACKUP_OPTION}{&MANIFEST_KEY_PROCESS_MAX} = $strStorage eq S3 ? 2 : 1;
|
2018-09-19 17:12:45 +02:00
|
|
|
$oManifest{&MANIFEST_SECTION_BACKUP_OPTION}{&MANIFEST_KEY_DELTA} = JSON::PP::false;
|
2016-12-23 15:22:59 +02:00
|
|
|
|
2019-03-02 15:01:02 +02:00
|
|
|
if ($bEncrypt)
|
2017-11-06 19:51:12 +02:00
|
|
|
{
|
|
|
|
$oManifest{&INI_SECTION_CIPHER}{&INI_KEY_CIPHER_PASS} = 'REPLACEME';
|
|
|
|
}
|
|
|
|
|
2016-12-23 15:22:59 +02:00
|
|
|
$oManifest{&MANIFEST_SECTION_BACKUP_DB}{&MANIFEST_KEY_CATALOG} = 201409291;
|
|
|
|
$oManifest{&MANIFEST_SECTION_BACKUP_DB}{&MANIFEST_KEY_CONTROL} = 942;
|
2017-11-19 03:02:54 +02:00
|
|
|
$oManifest{&MANIFEST_SECTION_BACKUP_DB}{&MANIFEST_KEY_SYSTEM_ID} = 1000000000000000094;
|
2016-12-23 15:22:59 +02:00
|
|
|
$oManifest{&MANIFEST_SECTION_BACKUP_DB}{&MANIFEST_KEY_DB_VERSION} = PG_VERSION_94;
|
|
|
|
$oManifest{&MANIFEST_SECTION_BACKUP_DB}{&MANIFEST_KEY_DB_ID} = 1;
|
|
|
|
|
|
|
|
$oManifest{&MANIFEST_SECTION_BACKUP_TARGET}{&MANIFEST_TARGET_PGDATA}{&MANIFEST_SUBKEY_PATH} =
|
2020-06-16 20:06:38 +02:00
|
|
|
$oHostDbPrimary->dbBasePath();
|
2016-12-23 15:22:59 +02:00
|
|
|
$oManifest{&MANIFEST_SECTION_BACKUP_TARGET}{&MANIFEST_TARGET_PGDATA}{&MANIFEST_SUBKEY_TYPE} = MANIFEST_VALUE_PATH;
|
|
|
|
|
2020-06-16 20:06:38 +02:00
|
|
|
$oHostDbPrimary->manifestPathCreate(\%oManifest, MANIFEST_TARGET_PGDATA);
|
2016-12-23 15:22:59 +02:00
|
|
|
|
2020-06-16 20:06:38 +02:00
|
|
|
$oHostDbPrimary->manifestFileCreate(\%oManifest, MANIFEST_TARGET_PGDATA, DB_FILE_PGVERSION, PG_VERSION_94,
|
2016-12-23 15:22:59 +02:00
|
|
|
'184473f470864e067ee3a22e64b47b0a1c356f29', $lTime, undef, true);
|
|
|
|
|
|
|
|
# Load sample page
|
2020-03-06 21:10:09 +02:00
|
|
|
my $tBasePage = ${storageTest()->get($self->dataPath() . '/page.bin')};
|
2016-12-23 15:22:59 +02:00
|
|
|
my $iBasePageChecksum = 0x1B99;
|
|
|
|
|
|
|
|
# Create base path
|
2020-06-16 20:06:38 +02:00
|
|
|
$oHostDbPrimary->manifestPathCreate(\%oManifest, MANIFEST_TARGET_PGDATA, 'base');
|
|
|
|
$oHostDbPrimary->manifestPathCreate(\%oManifest, MANIFEST_TARGET_PGDATA, 'base/1');
|
2016-12-23 15:22:59 +02:00
|
|
|
|
2020-06-16 20:06:38 +02:00
|
|
|
$oHostDbPrimary->manifestFileCreate(\%oManifest, MANIFEST_TARGET_PGDATA, 'base/1/12000', $tBasePage,
|
2016-12-23 15:22:59 +02:00
|
|
|
'22c98d248ff548311eda88559e4a8405ed77c003', $lTime);
|
2020-06-16 20:06:38 +02:00
|
|
|
$oHostDbPrimary->manifestFileCreate(\%oManifest, MANIFEST_TARGET_PGDATA, 'base/1/' . DB_FILE_PGVERSION,
|
2016-12-23 15:22:59 +02:00
|
|
|
PG_VERSION_94, '184473f470864e067ee3a22e64b47b0a1c356f29', $lTime, '660');
|
|
|
|
|
2017-06-15 21:32:10 +02:00
|
|
|
if (!$bRemote)
|
2016-12-23 15:22:59 +02:00
|
|
|
{
|
2020-06-16 20:06:38 +02:00
|
|
|
$oHostDbPrimary->executeSimple(
|
|
|
|
'chown 7777 ' . $oHostDbPrimary->dbBasePath() . '/base/1/' . DB_FILE_PGVERSION, undef, 'root');
|
2016-12-23 15:22:59 +02:00
|
|
|
$oManifest{&MANIFEST_SECTION_TARGET_FILE}{MANIFEST_TARGET_PGDATA . '/base/1/' . DB_FILE_PGVERSION}
|
|
|
|
{&MANIFEST_SUBKEY_USER} = INI_FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
my $tPageInvalid17000 = $tBasePage . $tBasePage;
|
|
|
|
|
2020-06-16 20:06:38 +02:00
|
|
|
$oHostDbPrimary->manifestPathCreate(\%oManifest, MANIFEST_TARGET_PGDATA, 'base/16384');
|
2016-12-23 15:22:59 +02:00
|
|
|
|
2020-06-16 20:06:38 +02:00
|
|
|
$oHostDbPrimary->manifestFileCreate(
|
2016-12-23 15:22:59 +02:00
|
|
|
\%oManifest, MANIFEST_TARGET_PGDATA, 'base/16384/17000', $tPageInvalid17000,
|
|
|
|
'e0101dd8ffb910c9c202ca35b5f828bcb9697bed', $lTime, undef, undef, '1');
|
2020-06-16 20:06:38 +02:00
|
|
|
$oHostDbPrimary->manifestFileCreate(\%oManifest, MANIFEST_TARGET_PGDATA, 'base/16384/' . DB_FILE_PGVERSION,
|
2016-12-23 15:22:59 +02:00
|
|
|
PG_VERSION_94, '184473f470864e067ee3a22e64b47b0a1c356f29', $lTime);
|
|
|
|
|
2017-06-15 21:32:10 +02:00
|
|
|
if (!$bRemote)
|
2016-12-23 15:22:59 +02:00
|
|
|
{
|
2020-06-16 20:06:38 +02:00
|
|
|
$oHostDbPrimary->executeSimple(
|
|
|
|
'chown :7777 ' . $oHostDbPrimary->dbBasePath() . '/base/16384/' . DB_FILE_PGVERSION, undef, 'root');
|
2016-12-23 15:22:59 +02:00
|
|
|
$oManifest{&MANIFEST_SECTION_TARGET_FILE}{MANIFEST_TARGET_PGDATA . '/base/16384/' . DB_FILE_PGVERSION}
|
|
|
|
{&MANIFEST_SUBKEY_GROUP} = INI_FALSE;
|
|
|
|
}
|
|
|
|
|
2020-06-16 20:06:38 +02:00
|
|
|
$oHostDbPrimary->manifestPathCreate(\%oManifest, MANIFEST_TARGET_PGDATA, 'base/32768');
|
2016-12-23 15:22:59 +02:00
|
|
|
|
|
|
|
my $tPageValid =
|
2020-03-05 20:56:20 +02:00
|
|
|
pageBuild($tBasePage, 0, 0x1b99) .
|
|
|
|
pageBuild($tBasePage, 1, 0x1b9a) .
|
|
|
|
pageBuild($tBasePage, 2, 0x1b97) .
|
2022-02-23 20:05:53 +02:00
|
|
|
("\0" x 8192);
|
2016-12-23 15:22:59 +02:00
|
|
|
|
2020-06-16 20:06:38 +02:00
|
|
|
$oHostDbPrimary->manifestFileCreate(
|
2022-02-23 20:05:53 +02:00
|
|
|
\%oManifest, MANIFEST_TARGET_PGDATA, 'base/32768/33000', $tPageValid, '1d73a0052828531770e7c155aeb22338e017e196',
|
2017-01-30 20:59:00 +02:00
|
|
|
$lTime);
|
2016-12-23 15:22:59 +02:00
|
|
|
|
2017-03-01 21:15:46 +02:00
|
|
|
my $iBlockOffset = 32767 * 131072;
|
|
|
|
|
|
|
|
my $tPageValidSeg32767 =
|
2020-03-05 20:56:20 +02:00
|
|
|
pageBuild($tBasePage, $iBlockOffset + 0, 0xf7de) .
|
|
|
|
pageBuild($tBasePage, $iBlockOffset + 1, 0xf7df) .
|
2017-03-13 21:50:13 +02:00
|
|
|
("\0" x 8192) .
|
2022-02-23 20:05:53 +02:00
|
|
|
("\0" x 8192);
|
2017-03-01 21:15:46 +02:00
|
|
|
|
2020-06-16 20:06:38 +02:00
|
|
|
$oHostDbPrimary->manifestFileCreate(
|
2017-03-01 21:15:46 +02:00
|
|
|
\%oManifest, MANIFEST_TARGET_PGDATA, 'base/32768/33000.32767', $tPageValidSeg32767,
|
2022-02-23 20:05:53 +02:00
|
|
|
'1d11c42e6080e805a7b12bf9f83f4def548d92ac', $lTime);
|
2017-03-01 21:15:46 +02:00
|
|
|
|
2016-12-23 15:22:59 +02:00
|
|
|
my $tPageInvalid33001 =
|
2020-03-05 20:56:20 +02:00
|
|
|
pageBuild($tBasePage, 1, 0x1b9a) .
|
|
|
|
pageBuild($tBasePage, 1, 0x1b9a) .
|
|
|
|
pageBuild($tBasePage, 2, 0x1b97) .
|
|
|
|
pageBuild($tBasePage, 0, 0x1b99) .
|
|
|
|
pageBuild($tBasePage, 0, 0x1b99) .
|
|
|
|
pageBuild($tBasePage, 0, 0x1b99) .
|
|
|
|
pageBuild($tBasePage, 6, 0x1b9b) .
|
|
|
|
pageBuild($tBasePage, 0, 0x1b99);
|
2016-12-23 15:22:59 +02:00
|
|
|
|
2020-06-16 20:06:38 +02:00
|
|
|
$oHostDbPrimary->manifestFileCreate(
|
2016-12-23 15:22:59 +02:00
|
|
|
\%oManifest, MANIFEST_TARGET_PGDATA, 'base/32768/33001', $tPageInvalid33001,
|
|
|
|
'6bf316f11d28c28914ea9be92c00de9bea6d9a6b', $lTime, undef, undef, '0, [3, 5], 7');
|
|
|
|
|
2020-06-16 20:06:38 +02:00
|
|
|
$oHostDbPrimary->manifestFileCreate(\%oManifest, MANIFEST_TARGET_PGDATA, 'base/32768/' . DB_FILE_PGVERSION,
|
2016-12-23 15:22:59 +02:00
|
|
|
PG_VERSION_94, '184473f470864e067ee3a22e64b47b0a1c356f29', $lTime);
|
|
|
|
|
|
|
|
# Create global path
|
2020-06-16 20:06:38 +02:00
|
|
|
$oHostDbPrimary->manifestPathCreate(\%oManifest, MANIFEST_TARGET_PGDATA, 'global');
|
2016-12-23 15:22:59 +02:00
|
|
|
|
2020-06-16 20:06:38 +02:00
|
|
|
$oHostDbPrimary->manifestFileCreate(
|
2018-09-25 11:24:42 +02:00
|
|
|
\%oManifest, MANIFEST_TARGET_PGDATA, DB_FILE_PGCONTROL, '[replaceme]',
|
|
|
|
$self->archBits() == 32 ? '8107e546c59c72a8c1818fc3610d7cc1e5623660' : '4c77c900f7af0d9ab13fa9982051a42e0b637f6c',
|
|
|
|
$lTime - 100, undef, true);
|
2016-12-23 15:22:59 +02:00
|
|
|
|
|
|
|
# Copy pg_control
|
2020-06-16 20:06:38 +02:00
|
|
|
$self->controlGenerate($oHostDbPrimary->dbBasePath(), PG_VERSION_94);
|
|
|
|
utime($lTime - 100, $lTime - 100, $oHostDbPrimary->dbBasePath() . '/' . DB_FILE_PGCONTROL)
|
2016-12-23 15:22:59 +02:00
|
|
|
or confess &log(ERROR, "unable to set time");
|
|
|
|
$oManifest{&MANIFEST_SECTION_TARGET_FILE}{MANIFEST_TARGET_PGDATA . '/' . DB_FILE_PGCONTROL}
|
|
|
|
{&MANIFEST_SUBKEY_SIZE} = 8192;
|
|
|
|
|
|
|
|
# Create tablespace path
|
2020-06-16 20:06:38 +02:00
|
|
|
$oHostDbPrimary->manifestPathCreate(\%oManifest, MANIFEST_TARGET_PGDATA, DB_PATH_PGTBLSPC);
|
2016-12-23 15:22:59 +02:00
|
|
|
|
|
|
|
# Create paths/files to ignore
|
2017-06-15 21:32:10 +02:00
|
|
|
if (!$bRemote)
|
2016-12-23 15:22:59 +02:00
|
|
|
{
|
|
|
|
# Create temp dir and file that will be ignored
|
2020-06-16 20:06:38 +02:00
|
|
|
$oHostDbPrimary->dbPathCreate(\%oManifest, MANIFEST_TARGET_PGDATA, 'base/' . DB_FILE_PREFIX_TMP);
|
|
|
|
$oHostDbPrimary->dbFileCreate(
|
2016-12-23 15:22:59 +02:00
|
|
|
\%oManifest, MANIFEST_TARGET_PGDATA, 'base/' . DB_FILE_PREFIX_TMP . '/' . DB_FILE_PREFIX_TMP . '.1', 'IGNORE');
|
|
|
|
|
|
|
|
# Create pg_dynshmem dir and file - only file will be ignored
|
2020-06-16 20:06:38 +02:00
|
|
|
$oHostDbPrimary->manifestPathCreate(\%oManifest, MANIFEST_TARGET_PGDATA, DB_PATH_PGDYNSHMEM);
|
|
|
|
$oHostDbPrimary->dbFileCreate(\%oManifest, MANIFEST_TARGET_PGDATA, DB_PATH_PGDYNSHMEM . '/anything.tmp', 'IGNORE');
|
2016-12-23 15:22:59 +02:00
|
|
|
|
|
|
|
# Create pg_notify dir and file - only file will be ignored
|
2020-06-16 20:06:38 +02:00
|
|
|
$oHostDbPrimary->manifestPathCreate(\%oManifest, MANIFEST_TARGET_PGDATA, DB_PATH_PGNOTIFY);
|
|
|
|
$oHostDbPrimary->dbFileCreate(\%oManifest, MANIFEST_TARGET_PGDATA, DB_PATH_PGNOTIFY . '/anything.tmp', 'IGNORE');
|
2016-12-23 15:22:59 +02:00
|
|
|
|
|
|
|
# Create pg_replslot dir and file - only file will be ignored
|
2020-06-16 20:06:38 +02:00
|
|
|
$oHostDbPrimary->manifestPathCreate(\%oManifest, MANIFEST_TARGET_PGDATA, DB_PATH_PGREPLSLOT);
|
|
|
|
$oHostDbPrimary->dbFileCreate(\%oManifest, MANIFEST_TARGET_PGDATA, DB_PATH_PGREPLSLOT . '/anything.tmp', 'IGNORE');
|
2016-12-23 15:22:59 +02:00
|
|
|
|
|
|
|
# Create pg_serial dir and file - only file will be ignored
|
2020-06-16 20:06:38 +02:00
|
|
|
$oHostDbPrimary->manifestPathCreate(\%oManifest, MANIFEST_TARGET_PGDATA, DB_PATH_PGSERIAL);
|
|
|
|
$oHostDbPrimary->dbFileCreate(\%oManifest, MANIFEST_TARGET_PGDATA, DB_PATH_PGSERIAL . '/anything.tmp', 'IGNORE');
|
2016-12-23 15:22:59 +02:00
|
|
|
|
2019-08-26 18:05:36 +02:00
|
|
|
# Create pg_snapshots dir and file - only file will be ignored
|
2020-06-16 20:06:38 +02:00
|
|
|
$oHostDbPrimary->manifestPathCreate(\%oManifest, MANIFEST_TARGET_PGDATA, DB_PATH_PGSNAPSHOTS);
|
|
|
|
$oHostDbPrimary->dbFileCreate(\%oManifest, MANIFEST_TARGET_PGDATA, DB_PATH_PGSNAPSHOTS . '/anything.tmp', 'IGNORE');
|
2016-12-23 15:22:59 +02:00
|
|
|
|
|
|
|
# Create pg_stat_tmp dir and file - only file will be ignored
|
2020-06-16 20:06:38 +02:00
|
|
|
$oHostDbPrimary->manifestPathCreate(\%oManifest, MANIFEST_TARGET_PGDATA, DB_PATH_PGSTATTMP);
|
|
|
|
$oHostDbPrimary->dbFileCreate(\%oManifest, MANIFEST_TARGET_PGDATA, DB_PATH_PGSTATTMP . '/anything.tmp', 'IGNORE');
|
2016-12-23 15:22:59 +02:00
|
|
|
|
|
|
|
# Create pg_subtrans dir and file - only file will be ignored
|
2020-06-16 20:06:38 +02:00
|
|
|
$oHostDbPrimary->manifestPathCreate(\%oManifest, MANIFEST_TARGET_PGDATA, DB_PATH_PGSUBTRANS);
|
|
|
|
$oHostDbPrimary->dbFileCreate(\%oManifest, MANIFEST_TARGET_PGDATA, DB_PATH_PGSUBTRANS . '/anything.tmp', 'IGNORE');
|
2016-12-23 15:22:59 +02:00
|
|
|
|
|
|
|
# More files to ignore
|
2020-06-16 20:06:38 +02:00
|
|
|
$oHostDbPrimary->dbFileCreate(\%oManifest, MANIFEST_TARGET_PGDATA, DB_FILE_POSTGRESQLAUTOCONFTMP, 'IGNORE');
|
2021-10-14 01:36:59 +02:00
|
|
|
$oHostDbPrimary->dbFileCreate(\%oManifest, MANIFEST_TARGET_PGDATA, DB_FILE_POSTMTROPTS, 'IGNORE');
|
2020-06-16 20:06:38 +02:00
|
|
|
$oHostDbPrimary->dbFileCreate(\%oManifest, MANIFEST_TARGET_PGDATA, DB_FILE_RECOVERYCONF, 'IGNORE');
|
|
|
|
$oHostDbPrimary->dbFileCreate(\%oManifest, MANIFEST_TARGET_PGDATA, DB_FILE_RECOVERYDONE, 'IGNORE');
|
|
|
|
$oHostDbPrimary->dbFileCreate(\%oManifest, MANIFEST_TARGET_PGDATA, 'global/' . DB_FILE_PGINTERNALINIT, 'IGNORE');
|
2018-07-31 00:53:34 +02:00
|
|
|
|
|
|
|
# Unlog and temp files to ignore (unlog _init will NOT be ignored)
|
2020-06-16 20:06:38 +02:00
|
|
|
$oHostDbPrimary->manifestFileCreate(\%oManifest, MANIFEST_TARGET_PGDATA, 'base/32768/44000_init', $tPageValid,
|
2022-02-23 20:05:53 +02:00
|
|
|
'1d73a0052828531770e7c155aeb22338e017e196', $lTime);
|
2020-06-16 20:06:38 +02:00
|
|
|
$oHostDbPrimary->dbFileCreate(\%oManifest, MANIFEST_TARGET_PGDATA, 'base/32768/44000', 'IGNORE');
|
|
|
|
$oHostDbPrimary->dbFileCreate(\%oManifest, MANIFEST_TARGET_PGDATA, 'base/32768/t333_44000', 'IGNORE');
|
2016-12-23 15:22:59 +02:00
|
|
|
}
|
|
|
|
|
2018-04-08 18:16:32 +02:00
|
|
|
# Help and Version. These have complete unit tests, so here just make sure there is output from the command line.
|
|
|
|
#---------------------------------------------------------------------------------------------------------------------------
|
|
|
|
if ($self->runCurrent() == 1)
|
|
|
|
{
|
2020-06-16 20:06:38 +02:00
|
|
|
$oHostDbPrimary->executeSimple($self->backrestExe() . " version", {oLogTest => $self->expect()});
|
|
|
|
$oHostDbPrimary->executeSimple($self->backrestExe() . " help version", {oLogTest => $self->expect()});
|
2018-04-08 18:16:32 +02:00
|
|
|
}
|
|
|
|
|
2016-12-23 15:22:59 +02:00
|
|
|
# Full backup
|
2017-08-25 22:47:47 +02:00
|
|
|
#---------------------------------------------------------------------------------------------------------------------------
|
|
|
|
my $strType = CFGOPTVAL_BACKUP_TYPE_FULL;
|
2016-12-23 15:22:59 +02:00
|
|
|
my $strOptionalParam = '--manifest-save-threshold=3';
|
|
|
|
my $strTestPoint;
|
|
|
|
|
|
|
|
# Create the archive info file
|
2020-03-09 23:41:59 +02:00
|
|
|
$oHostBackup->stanzaCreate('create required data for stanza', {strOptionalParam => '--no-online'});
|
2016-12-23 15:22:59 +02:00
|
|
|
|
2018-05-02 18:19:54 +02:00
|
|
|
# Create a link to postgresql.conf
|
2020-06-16 20:06:38 +02:00
|
|
|
storageTest()->pathCreate($oHostDbPrimary->dbPath() . '/pg_config', {strMode => '0700', bCreateParent => true});
|
2016-12-23 15:22:59 +02:00
|
|
|
testFileCreate(
|
2020-06-16 20:06:38 +02:00
|
|
|
$oHostDbPrimary->dbPath() . '/pg_config/postgresql.conf', "listen_addresses = *\n", $lTime - 100);
|
|
|
|
testLinkCreate($oHostDbPrimary->dbPath() . '/pg_config/postgresql.conf.link', './postgresql.conf');
|
2016-12-23 15:22:59 +02:00
|
|
|
|
2020-06-16 20:06:38 +02:00
|
|
|
$oHostDbPrimary->manifestLinkCreate(\%oManifest, MANIFEST_TARGET_PGDATA, 'postgresql.conf',
|
2016-12-23 15:22:59 +02:00
|
|
|
'../pg_config/postgresql.conf', true);
|
|
|
|
|
2018-05-02 18:19:54 +02:00
|
|
|
# Create a link to pg_hba.conf
|
|
|
|
testFileCreate(
|
2020-06-16 20:06:38 +02:00
|
|
|
$oHostDbPrimary->dbPath() . '/pg_config/pg_hba.conf', "CONTENTS\n", $lTime - 100);
|
|
|
|
testLinkCreate($oHostDbPrimary->dbPath() . '/pg_config/pg_hba.conf.link', './pg_hba.conf');
|
2018-05-02 18:19:54 +02:00
|
|
|
|
2020-06-16 20:06:38 +02:00
|
|
|
$oHostDbPrimary->manifestLinkCreate(\%oManifest, MANIFEST_TARGET_PGDATA, 'pg_hba.conf',
|
2018-05-02 18:19:54 +02:00
|
|
|
'../pg_config/pg_hba.conf', true);
|
|
|
|
|
2016-12-23 15:22:59 +02:00
|
|
|
# Create stat directory link and file
|
2020-06-16 20:06:38 +02:00
|
|
|
storageTest()->pathCreate($oHostDbPrimary->dbPath() . '/pg_stat', {strMode => '0700', bCreateParent => true});
|
|
|
|
$oHostDbPrimary->manifestLinkCreate(\%oManifest, MANIFEST_TARGET_PGDATA, 'pg_stat', '../pg_stat');
|
|
|
|
$oHostDbPrimary->manifestFileCreate(\%oManifest, MANIFEST_TARGET_PGDATA . '/pg_stat', 'global.stat', 'stats',
|
2016-12-23 15:22:59 +02:00
|
|
|
'e350d5ce0153f3e22d5db21cf2a4eff00f3ee877', $lTime - 100, undef, true);
|
2020-06-16 20:06:38 +02:00
|
|
|
$oHostDbPrimary->manifestPathCreate(\%oManifest, MANIFEST_TARGET_PGDATA, 'pg_clog');
|
2016-12-23 15:22:59 +02:00
|
|
|
|
2018-09-10 16:54:34 +02:00
|
|
|
# Create file with special characters
|
2020-06-16 20:06:38 +02:00
|
|
|
$oHostDbPrimary->manifestFileCreate(
|
2019-07-03 04:20:35 +02:00
|
|
|
\%oManifest, MANIFEST_TARGET_PGDATA, 'special-!_.*\'()&!@;:+,?', undef, undef, $lTime, undef, true);
|
2018-09-10 16:54:34 +02:00
|
|
|
|
2019-03-10 11:03:52 +02:00
|
|
|
$oManifest{&MANIFEST_SECTION_BACKUP_OPTION}{&MANIFEST_KEY_PROCESS_MAX} = 1;
|
|
|
|
|
2019-12-18 03:14:45 +02:00
|
|
|
my $strFullBackup = $oHostBackup->backup(
|
2016-12-23 15:22:59 +02:00
|
|
|
$strType, 'create pg_stat link, pg_clog dir',
|
|
|
|
{oExpectedManifest => \%oManifest,
|
2017-09-19 16:14:18 +02:00
|
|
|
strOptionalParam => $strOptionalParam .
|
|
|
|
# Pass ssh path to make sure it is used
|
2020-03-09 23:41:59 +02:00
|
|
|
($bRemote ? ' --cmd-ssh=/usr/bin/ssh' : '') .
|
2017-09-19 16:14:18 +02:00
|
|
|
# Pass bogus ssh port to make sure it is passed through the protocol layer (it won't be used)
|
2020-03-09 23:41:59 +02:00
|
|
|
($bRemote ? ' --pg1-port=9999' : '') .
|
2017-09-19 16:14:18 +02:00
|
|
|
# Pass bogus socket path to make sure it is passed through the protocol layer (it won't be used)
|
2020-03-09 23:41:59 +02:00
|
|
|
($bRemote ? ' --pg1-socket-path=/test_socket_path' : '') .
|
|
|
|
' --buffer-size=16384 --checksum-page --process-max=1',
|
2020-07-02 22:24:34 +02:00
|
|
|
strRepoType => $strStorage eq POSIX ? CIFS : undef, strTest => $strTestPoint, fTestDelay => 0});
|
2016-12-23 15:22:59 +02:00
|
|
|
|
2020-05-13 00:55:20 +02:00
|
|
|
$oManifest{&MANIFEST_SECTION_BACKUP_OPTION}{&MANIFEST_KEY_PROCESS_MAX} = $strStorage eq S3 ? 2 : 1;
|
2019-12-17 22:23:07 +02:00
|
|
|
$oManifest{&MANIFEST_SECTION_BACKUP_OPTION}{&MANIFEST_KEY_BUFFER_SIZE} = 65536;
|
2019-03-10 11:03:52 +02:00
|
|
|
|
2016-12-23 15:22:59 +02:00
|
|
|
# Stop operations and make sure the correct error occurs
|
2017-08-25 22:47:47 +02:00
|
|
|
#---------------------------------------------------------------------------------------------------------------------------
|
2020-05-13 00:55:20 +02:00
|
|
|
if ($strStorage eq POSIX)
|
2016-12-23 15:22:59 +02:00
|
|
|
{
|
2019-11-25 14:45:58 +02:00
|
|
|
# Test global stop
|
2020-06-16 20:06:38 +02:00
|
|
|
$oHostDbPrimary->stop({bForce => true});
|
2016-12-23 15:22:59 +02:00
|
|
|
|
|
|
|
$oHostBackup->backup(
|
|
|
|
$strType, 'global stop',
|
|
|
|
{oExpectedManifest => \%oManifest, iExpectedExitStatus => ERROR_STOP});
|
|
|
|
|
|
|
|
# Test stanza stop
|
2020-06-16 20:06:38 +02:00
|
|
|
$oHostDbPrimary->stop({strStanza => $oHostDbPrimary->stanza()});
|
2016-12-23 15:22:59 +02:00
|
|
|
|
|
|
|
# This time a warning should be generated
|
2020-06-16 20:06:38 +02:00
|
|
|
$oHostDbPrimary->stop({strStanza => $oHostDbPrimary->stanza()});
|
2016-12-23 15:22:59 +02:00
|
|
|
|
|
|
|
$oHostBackup->backup(
|
|
|
|
$strType, 'stanza stop',
|
|
|
|
{oExpectedManifest => \%oManifest, iExpectedExitStatus => ERROR_STOP});
|
|
|
|
|
2020-06-16 20:06:38 +02:00
|
|
|
$oHostDbPrimary->start({strStanza => $self->stanza()});
|
|
|
|
$oHostDbPrimary->start();
|
2016-12-23 15:22:59 +02:00
|
|
|
|
|
|
|
# This time a warning should be generated
|
2020-06-16 20:06:38 +02:00
|
|
|
$oHostDbPrimary->start();
|
2016-12-23 15:22:59 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
# Resume Full Backup
|
2017-08-25 22:47:47 +02:00
|
|
|
#---------------------------------------------------------------------------------------------------------------------------
|
|
|
|
$strType = CFGOPTVAL_BACKUP_TYPE_FULL;
|
2016-12-23 15:22:59 +02:00
|
|
|
|
|
|
|
# These files should never be backed up (this requires the next backup to do --force)
|
2021-10-14 01:36:59 +02:00
|
|
|
testFileCreate($oHostDbPrimary->dbBasePath() . '/' . DB_FILE_POSTMTRPID, 'JUNK');
|
2020-06-16 20:06:38 +02:00
|
|
|
testFileCreate($oHostDbPrimary->dbBasePath() . '/' . DB_FILE_BACKUPLABELOLD, 'JUNK');
|
|
|
|
testFileCreate($oHostDbPrimary->dbBasePath() . '/' . DB_FILE_RECOVERYCONF, 'JUNK');
|
|
|
|
testFileCreate($oHostDbPrimary->dbBasePath() . '/' . DB_FILE_RECOVERYDONE, 'JUNK');
|
2016-12-23 15:22:59 +02:00
|
|
|
|
|
|
|
# Create files in root tblspc paths that should not be copied or deleted.
|
|
|
|
# This will be checked later after a --force restore.
|
2020-06-16 20:06:38 +02:00
|
|
|
my $strDoNotDeleteFile = $oHostDbPrimary->tablespacePath(1, 2) . '/donotdelete.txt';
|
2017-06-09 23:51:41 +02:00
|
|
|
storageTest()->pathCreate(dirname($strDoNotDeleteFile), {strMode => '0700', bCreateParent => true});
|
2016-12-23 15:22:59 +02:00
|
|
|
testFileCreate($strDoNotDeleteFile, 'DONOTDELETE-1-2');
|
|
|
|
|
2020-06-16 20:06:38 +02:00
|
|
|
storageTest()->pathCreate($oHostDbPrimary->tablespacePath(1), {strMode => '0700', bCreateParent => true});
|
|
|
|
testFileCreate($oHostDbPrimary->tablespacePath(1) . '/donotdelete.txt', 'DONOTDELETE-1');
|
|
|
|
storageTest()->pathCreate($oHostDbPrimary->tablespacePath(2), {strMode => '0700', bCreateParent => true});
|
|
|
|
testFileCreate($oHostDbPrimary->tablespacePath(2) . '/donotdelete.txt', 'DONOTDELETE-2');
|
|
|
|
storageTest()->pathCreate($oHostDbPrimary->tablespacePath(2, 2), {strMode => '0700', bCreateParent => true});
|
|
|
|
testFileCreate($oHostDbPrimary->tablespacePath(2, 2) . '/donotdelete.txt', 'DONOTDELETE-2-2');
|
|
|
|
storageTest()->pathCreate($oHostDbPrimary->tablespacePath(11), {strMode => '0700', bCreateParent => true});
|
2016-12-23 15:22:59 +02:00
|
|
|
|
2017-06-09 23:51:41 +02:00
|
|
|
# Resume by copying the valid full backup over the last aborted full backup if it exists, or by creating a new path
|
|
|
|
my $strResumeBackup = (storageRepo()->list(
|
2020-03-09 23:41:59 +02:00
|
|
|
$oHostBackup->repoBackupPath(), {strExpression => backupRegExpGet(true, true, true), strSortOrder => 'reverse'}))[0];
|
2019-12-06 18:48:41 +02:00
|
|
|
my $strResumeLabel = $strResumeBackup ne $strFullBackup ?
|
2020-03-09 23:41:59 +02:00
|
|
|
$strResumeBackup : backupLabel(storageRepo(), $oHostBackup->repoBackupPath(), $strType, undef, time());
|
|
|
|
my $strResumePath = $oHostBackup->repoBackupPath($strResumeLabel);
|
2016-12-23 15:22:59 +02:00
|
|
|
|
2017-06-09 23:51:41 +02:00
|
|
|
forceStorageRemove(storageRepo(), $strResumePath, {bRecurse => true});
|
2020-03-09 23:41:59 +02:00
|
|
|
forceStorageMove(storageRepo(), $oHostBackup->repoBackupPath($strFullBackup), $strResumePath);
|
2016-12-23 15:22:59 +02:00
|
|
|
|
2017-11-20 19:46:35 +02:00
|
|
|
# Set ownership on base directory to bogus values
|
|
|
|
if (!$bRemote)
|
|
|
|
{
|
2020-06-16 20:06:38 +02:00
|
|
|
$oHostDbPrimary->executeSimple('chown 7777:7777 ' . $oHostDbPrimary->dbBasePath(), undef, 'root');
|
|
|
|
$oHostDbPrimary->executeSimple('chmod 777 ' . $oHostDbPrimary->dbBasePath(), undef, 'root');
|
2017-11-20 19:46:35 +02:00
|
|
|
$oManifest{&MANIFEST_SECTION_TARGET_PATH}{&MANIFEST_TARGET_PGDATA}{&MANIFEST_SUBKEY_USER} = INI_FALSE;
|
|
|
|
$oManifest{&MANIFEST_SECTION_TARGET_PATH}{&MANIFEST_TARGET_PGDATA}{&MANIFEST_SUBKEY_GROUP} = INI_FALSE;
|
|
|
|
$oManifest{&MANIFEST_SECTION_TARGET_PATH}{&MANIFEST_TARGET_PGDATA}{&MANIFEST_SUBKEY_MODE} = '0777';
|
|
|
|
}
|
|
|
|
|
2017-06-09 23:51:41 +02:00
|
|
|
$oHostBackup->manifestMunge(
|
|
|
|
basename($strResumePath),
|
2019-12-06 18:48:41 +02:00
|
|
|
{&MANIFEST_SECTION_BACKUP => {&MANIFEST_KEY_LABEL => $strResumeLabel},
|
|
|
|
&MANIFEST_SECTION_TARGET_FILE =>
|
|
|
|
{(&MANIFEST_TARGET_PGDATA . '/' . &DB_FILE_PGVERSION) => {&MANIFEST_SUBKEY_CHECKSUM => undef}}},
|
2017-04-10 19:24:45 +02:00
|
|
|
false);
|
2016-12-23 15:22:59 +02:00
|
|
|
|
2017-06-09 23:51:41 +02:00
|
|
|
# Remove the main manifest so the backup appears aborted
|
|
|
|
forceStorageRemove(storageRepo(), "${strResumePath}/" . FILE_MANIFEST);
|
|
|
|
|
2016-12-23 15:22:59 +02:00
|
|
|
# Create a temp file in backup temp root to be sure it's deleted correctly
|
2017-06-15 21:32:10 +02:00
|
|
|
my $strTempFile = "${strResumePath}/file.tmp";
|
2017-06-12 16:52:32 +02:00
|
|
|
|
2020-07-02 22:24:34 +02:00
|
|
|
if ($strStorage ne POSIX)
|
2017-06-12 16:52:32 +02:00
|
|
|
{
|
2019-10-09 20:38:24 +02:00
|
|
|
storageRepo()->put($strTempFile, "TEMP");
|
2017-06-12 16:52:32 +02:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2019-10-12 15:45:18 +02:00
|
|
|
executeTest("touch ${strTempFile}", {bRemote => $bRemote});
|
2017-06-12 16:52:32 +02:00
|
|
|
}
|
2016-12-23 15:22:59 +02:00
|
|
|
|
2018-08-24 22:50:33 +02:00
|
|
|
# Add zero-sized file
|
2020-06-16 20:06:38 +02:00
|
|
|
$oHostDbPrimary->manifestFileCreate(\%oManifest, MANIFEST_TARGET_PGDATA, 'zero_from_start', undef,
|
2018-08-24 22:50:33 +02:00
|
|
|
undef, $lTime, undef, true);
|
|
|
|
|
2018-09-19 17:12:45 +02:00
|
|
|
# Add files for testing backups when time changes but content doesn't, and when content changes but time and size don't
|
2020-06-16 20:06:38 +02:00
|
|
|
$oHostDbPrimary->manifestFileCreate(
|
2018-09-19 17:12:45 +02:00
|
|
|
\%oManifest, MANIFEST_TARGET_PGDATA, 'changetime.txt', 'SIZE', '88087292ed82e26f3eb824d0bffc05ccf7a30f8d', $lTime,
|
|
|
|
undef, true);
|
2020-06-16 20:06:38 +02:00
|
|
|
$oHostDbPrimary->manifestFileCreate(
|
2018-09-19 17:12:45 +02:00
|
|
|
\%oManifest, MANIFEST_TARGET_PGDATA, 'changecontent.txt', 'CONTENT', '238a131a3e8eb98d1fc5b27d882ca40b7618fd2a', $lTime,
|
|
|
|
undef, true);
|
|
|
|
|
2019-12-02 00:47:47 +02:00
|
|
|
# Create files to be excluded with the --exclude option
|
|
|
|
$oHostBackup->configUpdate(
|
|
|
|
{(CFGDEF_SECTION_GLOBAL . ':backup') =>
|
2020-03-09 23:41:59 +02:00
|
|
|
{'exclude' => ['postgresql.auto.conf', 'pg_log/', 'pg_log2', 'apipe']}});
|
2020-06-16 20:06:38 +02:00
|
|
|
$oHostDbPrimary->dbLinkCreate(\%oManifest, MANIFEST_TARGET_PGDATA, 'postgresql.auto.conf',
|
2019-12-02 00:47:47 +02:00
|
|
|
'../pg_config/postgresql.conf', true);
|
2020-06-16 20:06:38 +02:00
|
|
|
$oHostDbPrimary->manifestPathCreate(\%oManifest, MANIFEST_TARGET_PGDATA, 'pg_log');
|
|
|
|
$oHostDbPrimary->dbFileCreate(\%oManifest, MANIFEST_TARGET_PGDATA, 'pg_log/logfile', 'IGNORE');
|
|
|
|
$oHostDbPrimary->dbPathCreate(\%oManifest, MANIFEST_TARGET_PGDATA, 'pg_log2');
|
|
|
|
$oHostDbPrimary->dbFileCreate(\%oManifest, MANIFEST_TARGET_PGDATA, 'pg_log2/logfile', 'IGNORE');
|
|
|
|
executeTest('mkfifo ' . $oHostDbPrimary->dbBasePath() . '/apipe');
|
2019-12-02 00:47:47 +02:00
|
|
|
|
2016-12-23 15:22:59 +02:00
|
|
|
$strFullBackup = $oHostBackup->backup(
|
|
|
|
$strType, 'resume',
|
2019-11-21 23:06:27 +02:00
|
|
|
{oExpectedManifest => \%oManifest,
|
2020-03-09 23:41:59 +02:00
|
|
|
strOptionalParam => '--force --checksum-page' . ($bDeltaBackup ? ' --delta' : '')});
|
2016-12-23 15:22:59 +02:00
|
|
|
|
2022-01-20 15:41:05 +02:00
|
|
|
# Remove pid so restore will succeed (the rest will be cleaned up by the delta)
|
2021-10-14 01:36:59 +02:00
|
|
|
storageTest->remove($oHostDbPrimary->dbBasePath() . '/' . DB_FILE_POSTMTRPID);
|
2016-12-23 15:22:59 +02:00
|
|
|
|
|
|
|
# Restore - tests various mode, extra files/paths, missing files/paths
|
2017-08-25 22:47:47 +02:00
|
|
|
#---------------------------------------------------------------------------------------------------------------------------
|
2016-12-23 15:22:59 +02:00
|
|
|
# Munge permissions/modes on files that will be fixed by the restore
|
2017-06-15 21:32:10 +02:00
|
|
|
if (!$bRemote)
|
2016-12-23 15:22:59 +02:00
|
|
|
{
|
2020-06-16 20:06:38 +02:00
|
|
|
$oHostDbPrimary->executeSimple(
|
|
|
|
"chown :7777 " . $oHostDbPrimary->dbBasePath() . '/base/1/' . DB_FILE_PGVERSION, undef, 'root');
|
|
|
|
$oHostDbPrimary->executeSimple(
|
|
|
|
"chmod 600 " . $oHostDbPrimary->dbBasePath() . '/base/1/' . DB_FILE_PGVERSION, undef, 'root');
|
2016-12-23 15:22:59 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
# Create a path and file that are not in the manifest
|
2020-06-16 20:06:38 +02:00
|
|
|
$oHostDbPrimary->dbPathCreate(\%oManifest, MANIFEST_TARGET_PGDATA, 'deleteme');
|
|
|
|
$oHostDbPrimary->dbFileCreate(\%oManifest, MANIFEST_TARGET_PGDATA, 'deleteme/deleteme.txt', 'DELETEME');
|
2016-12-23 15:22:59 +02:00
|
|
|
|
|
|
|
# Change path mode
|
2020-06-16 20:06:38 +02:00
|
|
|
$oHostDbPrimary->dbPathMode(\%oManifest, MANIFEST_TARGET_PGDATA, 'base', '0777');
|
2016-12-23 15:22:59 +02:00
|
|
|
|
|
|
|
# Remove a path
|
2020-06-16 20:06:38 +02:00
|
|
|
$oHostDbPrimary->dbPathRemove(\%oManifest, MANIFEST_TARGET_PGDATA, 'pg_clog');
|
2016-12-23 15:22:59 +02:00
|
|
|
|
|
|
|
# Remove a file
|
2020-06-16 20:06:38 +02:00
|
|
|
$oHostDbPrimary->dbFileRemove(\%oManifest, MANIFEST_TARGET_PGDATA, 'base/16384/17000');
|
2016-12-23 15:22:59 +02:00
|
|
|
|
2017-11-20 19:46:35 +02:00
|
|
|
# Restore will set invalid user and group to root since the base path user/group are also invalid
|
2017-06-15 21:32:10 +02:00
|
|
|
if (!$bRemote)
|
2016-12-23 15:22:59 +02:00
|
|
|
{
|
2019-09-26 13:52:02 +02:00
|
|
|
$oManifest{&MANIFEST_SECTION_TARGET_PATH}{&MANIFEST_TARGET_PGDATA}{&MANIFEST_SUBKEY_USER} = 'root';
|
|
|
|
$oManifest{&MANIFEST_SECTION_TARGET_PATH}{&MANIFEST_TARGET_PGDATA}{&MANIFEST_SUBKEY_GROUP} = 'root';
|
|
|
|
|
2017-11-20 19:46:35 +02:00
|
|
|
$oManifest{&MANIFEST_SECTION_TARGET_FILE}{MANIFEST_TARGET_PGDATA . '/base/1/' . DB_FILE_PGVERSION}
|
|
|
|
{&MANIFEST_SUBKEY_USER} = 'root';
|
|
|
|
$oManifest{&MANIFEST_SECTION_TARGET_FILE}{MANIFEST_TARGET_PGDATA . '/base/16384/' . DB_FILE_PGVERSION}
|
|
|
|
{&MANIFEST_SUBKEY_GROUP} = 'root';
|
2016-12-23 15:22:59 +02:00
|
|
|
}
|
|
|
|
|
2020-06-16 20:06:38 +02:00
|
|
|
$oHostDbPrimary->restore(
|
2017-12-04 00:08:49 +02:00
|
|
|
'add and delete files', $strFullBackup,
|
|
|
|
{rhExpectedManifest => \%oManifest, bDelta => true, strUser => !$bRemote ? 'root' : undef,
|
|
|
|
strOptionalParam => ' --link-all' . ($bRemote ? ' --cmd-ssh=/usr/bin/ssh' : '')});
|
2016-12-23 15:22:59 +02:00
|
|
|
|
2019-12-02 00:47:47 +02:00
|
|
|
# Remove excludes now that they just create noise in the log
|
2020-03-09 23:41:59 +02:00
|
|
|
$oHostBackup->configUpdate({(CFGDEF_SECTION_GLOBAL . ':backup') => {'exclude' => []}});
|
2019-12-02 00:47:47 +02:00
|
|
|
|
2017-11-20 19:46:35 +02:00
|
|
|
# Run again to fix permissions
|
2017-06-15 21:32:10 +02:00
|
|
|
if (!$bRemote)
|
2016-12-23 15:22:59 +02:00
|
|
|
{
|
2017-11-20 19:46:35 +02:00
|
|
|
# Reset the base path user and group for the next restore so files will be reset to the base path user/group
|
2020-06-16 20:06:38 +02:00
|
|
|
$oHostDbPrimary->executeSimple(
|
|
|
|
'chown ' . TEST_USER . ':' . TEST_GROUP . ' ' . $oHostDbPrimary->dbBasePath(), undef, 'root');
|
2017-11-20 19:46:35 +02:00
|
|
|
|
|
|
|
$oHostBackup->manifestMunge(
|
|
|
|
$strFullBackup,
|
|
|
|
{&MANIFEST_SECTION_TARGET_PATH =>
|
|
|
|
{&MANIFEST_TARGET_PGDATA =>
|
2019-08-18 21:29:18 +02:00
|
|
|
{&MANIFEST_SUBKEY_USER => undef, &MANIFEST_SUBKEY_GROUP => undef}}},
|
2017-11-20 19:46:35 +02:00
|
|
|
false);
|
|
|
|
|
2022-01-21 15:52:51 +02:00
|
|
|
$oManifest{&MANIFEST_SECTION_TARGET_PATH}{&MANIFEST_TARGET_PGDATA}{&MANIFEST_SUBKEY_USER} = TEST_USER;
|
|
|
|
$oManifest{&MANIFEST_SECTION_TARGET_PATH}{&MANIFEST_TARGET_PGDATA}{&MANIFEST_SUBKEY_GROUP} = TEST_GROUP;
|
2017-11-20 19:46:35 +02:00
|
|
|
|
2022-01-21 15:52:51 +02:00
|
|
|
$oManifest{&MANIFEST_SECTION_TARGET_FILE}{MANIFEST_TARGET_PGDATA . '/base/1/' . DB_FILE_PGVERSION}
|
|
|
|
{&MANIFEST_SUBKEY_USER} = TEST_USER;
|
|
|
|
$oManifest{&MANIFEST_SECTION_TARGET_FILE}{MANIFEST_TARGET_PGDATA . '/base/16384/' . DB_FILE_PGVERSION}
|
|
|
|
{&MANIFEST_SUBKEY_GROUP} = TEST_GROUP;
|
2017-11-20 19:46:35 +02:00
|
|
|
|
2020-06-16 20:06:38 +02:00
|
|
|
$oHostDbPrimary->restore(
|
2017-12-04 00:08:49 +02:00
|
|
|
'fix permissions', $strFullBackup,
|
|
|
|
{rhExpectedManifest => \%oManifest, bDelta => true, strUser => 'root',
|
|
|
|
strOptionalParam => ' --link-all --log-level-console=detail'});
|
2017-11-20 19:46:35 +02:00
|
|
|
|
|
|
|
# Fix and remove files that are now owned by root
|
2019-10-16 17:05:24 +02:00
|
|
|
$oHostBackup->executeSimple('chown -R ' . TEST_USER . ':' . TEST_GROUP . ' ' . $oHostBackup->logPath(), undef, 'root');
|
2020-06-16 20:06:38 +02:00
|
|
|
$oHostDbPrimary->executeSimple('rm -rf ' . $oHostDbPrimary->lockPath() . '/*', undef, 'root');
|
2016-12-23 15:22:59 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
# Change an existing link to the wrong directory
|
2020-06-16 20:06:38 +02:00
|
|
|
$oHostDbPrimary->dbFileRemove(\%oManifest, MANIFEST_TARGET_PGDATA, 'pg_stat');
|
|
|
|
$oHostDbPrimary->dbLinkCreate(\%oManifest, MANIFEST_TARGET_PGDATA, 'pg_stat', '../wrong');
|
2016-12-23 15:22:59 +02:00
|
|
|
|
2020-06-16 20:06:38 +02:00
|
|
|
$oHostDbPrimary->restore(
|
2017-12-04 00:08:49 +02:00
|
|
|
'fix broken symlink', $strFullBackup,
|
|
|
|
{rhExpectedManifest => \%oManifest, bDelta => true,
|
2019-05-23 00:23:44 +02:00
|
|
|
strOptionalParam => ' --link-all' . ($bRemote ? ' --compress-level-network=0' : '')});
|
2016-12-23 15:22:59 +02:00
|
|
|
|
2019-12-18 03:14:45 +02:00
|
|
|
# Restore links as directories
|
2017-08-25 22:47:47 +02:00
|
|
|
#---------------------------------------------------------------------------------------------------------------------------
|
2016-12-23 15:22:59 +02:00
|
|
|
# Munge the user to make sure it gets reset on the next run
|
|
|
|
$oHostBackup->manifestMunge(
|
2017-04-10 19:24:45 +02:00
|
|
|
$strFullBackup,
|
|
|
|
{&MANIFEST_SECTION_TARGET_FILE =>
|
|
|
|
{&MANIFEST_FILE_PGCONTROL => {&MANIFEST_SUBKEY_USER => 'bogus', &MANIFEST_SUBKEY_GROUP => 'bogus'}}},
|
|
|
|
false);
|
2016-12-23 15:22:59 +02:00
|
|
|
|
|
|
|
# Restore succeeds
|
2020-06-16 20:06:38 +02:00
|
|
|
$oHostDbPrimary->manifestLinkMap(\%oManifest, MANIFEST_TARGET_PGDATA . '/pg_stat');
|
|
|
|
$oHostDbPrimary->manifestLinkMap(\%oManifest, MANIFEST_TARGET_PGDATA . '/postgresql.conf');
|
|
|
|
$oHostDbPrimary->manifestLinkMap(\%oManifest, MANIFEST_TARGET_PGDATA . '/pg_hba.conf');
|
2016-12-23 15:22:59 +02:00
|
|
|
|
2020-06-16 20:06:38 +02:00
|
|
|
$oHostDbPrimary->restore(
|
2019-12-18 03:14:45 +02:00
|
|
|
'restore links as directories', $strFullBackup,
|
2019-05-23 00:23:44 +02:00
|
|
|
{rhExpectedManifest => \%oManifest, bDelta => true, bForce => true});
|
2016-12-23 15:22:59 +02:00
|
|
|
|
2018-05-02 18:19:54 +02:00
|
|
|
# No longer need pg_hba.conf since it is no longer a link and doesn't provide additional coverage
|
2020-06-16 20:06:38 +02:00
|
|
|
$oHostDbPrimary->manifestFileRemove(\%oManifest, MANIFEST_TARGET_PGDATA, 'pg_hba.conf');
|
2018-05-02 18:19:54 +02:00
|
|
|
|
2016-12-23 15:22:59 +02:00
|
|
|
# Incr backup
|
2017-08-25 22:47:47 +02:00
|
|
|
#---------------------------------------------------------------------------------------------------------------------------
|
|
|
|
$strType = CFGOPTVAL_BACKUP_TYPE_INCR;
|
2020-06-16 20:06:38 +02:00
|
|
|
$oHostDbPrimary->manifestReference(\%oManifest, $strFullBackup);
|
2016-12-23 15:22:59 +02:00
|
|
|
|
2022-01-21 15:52:51 +02:00
|
|
|
# Fix mode on base path so defaults are simpler in backups
|
|
|
|
if (!$bRemote)
|
|
|
|
{
|
|
|
|
$oHostDbPrimary->executeSimple('chmod 700 ' . $oHostDbPrimary->dbBasePath(), undef, 'root');
|
|
|
|
$oManifest{&MANIFEST_SECTION_TARGET_PATH}{&MANIFEST_TARGET_PGDATA}{&MANIFEST_SUBKEY_MODE} = '0700';
|
|
|
|
}
|
|
|
|
|
2016-12-23 15:22:59 +02:00
|
|
|
# Add tablespace 1
|
2020-06-16 20:06:38 +02:00
|
|
|
$oHostDbPrimary->manifestTablespaceCreate(\%oManifest, 1);
|
|
|
|
$oHostDbPrimary->manifestPathCreate(\%oManifest, MANIFEST_TARGET_PGTBLSPC . '/1', '16384');
|
2016-12-23 15:22:59 +02:00
|
|
|
|
2020-06-16 20:06:38 +02:00
|
|
|
$oHostDbPrimary->manifestFileCreate(
|
2018-07-03 20:01:57 +02:00
|
|
|
\%oManifest, MANIFEST_TARGET_PGTBLSPC . '/1', '16384/tablespace1.txt', 'TBLSPCB',
|
|
|
|
'14c44cef6287269b08d41de489fd492bb9fc795d', $lTime - 100, undef, undef, false);
|
2020-06-16 20:06:38 +02:00
|
|
|
$oHostDbPrimary->manifestFileCreate(\%oManifest, MANIFEST_TARGET_PGDATA, 'badchecksum.txt', 'BADCHECKSUM',
|
2016-12-23 15:22:59 +02:00
|
|
|
'f927212cd08d11a42a666b2f04235398e9ceeb51', $lTime, undef, true);
|
2020-06-16 20:06:38 +02:00
|
|
|
$oHostDbPrimary->manifestFileCreate(
|
2018-07-03 20:01:57 +02:00
|
|
|
\%oManifest, MANIFEST_TARGET_PGDATA, 'changesize.txt', 'SIZE', '88087292ed82e26f3eb824d0bffc05ccf7a30f8d', $lTime,
|
|
|
|
undef, true);
|
2020-06-16 20:06:38 +02:00
|
|
|
$oHostDbPrimary->manifestFileCreate(
|
2018-07-05 21:40:50 +02:00
|
|
|
\%oManifest, MANIFEST_TARGET_PGDATA, 'zerosize.txt', '', undef, $lTime - 100, undef, true);
|
2016-12-23 15:22:59 +02:00
|
|
|
|
|
|
|
# Create temp dir and file that will be ignored
|
2017-06-15 21:32:10 +02:00
|
|
|
if (!$bRemote)
|
2016-12-23 15:22:59 +02:00
|
|
|
{
|
2020-06-16 20:06:38 +02:00
|
|
|
$oHostDbPrimary->dbPathCreate(\%oManifest, MANIFEST_TARGET_PGTBLSPC . '/1', DB_FILE_PREFIX_TMP);
|
|
|
|
$oHostDbPrimary->dbFileCreate(
|
2016-12-23 15:22:59 +02:00
|
|
|
\%oManifest, MANIFEST_TARGET_PGTBLSPC . '/1', DB_FILE_PREFIX_TMP . '/' . DB_FILE_PREFIX_TMP . '.1', 'IGNORE');
|
|
|
|
}
|
|
|
|
|
2019-12-10 20:16:47 +02:00
|
|
|
my $strBackup = $oHostBackup->backup($strType, 'add tablespace 1', {oExpectedManifest => \%oManifest});
|
2016-12-23 15:22:59 +02:00
|
|
|
|
|
|
|
# Resume Incr Backup
|
2017-08-25 22:47:47 +02:00
|
|
|
#---------------------------------------------------------------------------------------------------------------------------
|
|
|
|
$strType = CFGOPTVAL_BACKUP_TYPE_INCR;
|
2016-12-23 15:22:59 +02:00
|
|
|
|
2017-06-09 23:51:41 +02:00
|
|
|
# Create resumable backup from last backup
|
2020-03-09 23:41:59 +02:00
|
|
|
$strResumeLabel = backupLabel(storageRepo(), $oHostBackup->repoBackupPath(), $strType, substr($strBackup, 0, 16), time());
|
|
|
|
$strResumePath = $oHostBackup->repoBackupPath($strResumeLabel);
|
2016-12-23 15:22:59 +02:00
|
|
|
|
2017-06-09 23:51:41 +02:00
|
|
|
forceStorageRemove(storageRepo(), $strResumePath);
|
2020-03-09 23:41:59 +02:00
|
|
|
forceStorageMove(storageRepo(), $oHostBackup->repoBackupPath($strBackup), $strResumePath);
|
2016-12-23 15:22:59 +02:00
|
|
|
|
2018-07-03 20:01:57 +02:00
|
|
|
# Munge manifest so the resumed file in the repo appears to be bad
|
2019-03-02 15:01:02 +02:00
|
|
|
if ($bEncrypt || $bRemote)
|
2018-07-03 20:01:57 +02:00
|
|
|
{
|
|
|
|
$oHostBackup->manifestMunge(
|
|
|
|
basename($strResumePath),
|
|
|
|
{&MANIFEST_SECTION_TARGET_FILE =>
|
|
|
|
{(&MANIFEST_TARGET_PGDATA . '/badchecksum.txt') => {&MANIFEST_SUBKEY_CHECKSUM => BOGUS}}},
|
|
|
|
false);
|
|
|
|
}
|
|
|
|
# Change contents of resumed file without changing size so it will throw a nasty error about the repo having been corrupted
|
|
|
|
else
|
|
|
|
{
|
|
|
|
storageRepo()->put("${strResumePath}/pg_data/badchecksum.txt", 'BDDCHECKSUM');
|
|
|
|
}
|
|
|
|
|
2019-12-06 18:48:41 +02:00
|
|
|
# Write correct label into resumable manifest
|
|
|
|
$oHostBackup->manifestMunge(
|
|
|
|
basename($strResumePath), {&MANIFEST_SECTION_BACKUP => {&MANIFEST_KEY_LABEL => $strResumeLabel}},false);
|
|
|
|
|
2018-07-03 20:01:57 +02:00
|
|
|
# Change contents/size of a db file to make sure it recopies (and does not resume)
|
2020-06-16 20:06:38 +02:00
|
|
|
$oHostDbPrimary->manifestFileCreate(
|
2018-07-03 20:01:57 +02:00
|
|
|
\%oManifest, MANIFEST_TARGET_PGDATA, 'changesize.txt', 'SIZE+MORE', '3905d5be2ec8d67f41435dab5e0dcda3ae47455d', $lTime,
|
|
|
|
undef, true);
|
|
|
|
|
|
|
|
# Change contents/time of a db file to make sure it recopies (and does not resume)
|
2020-06-16 20:06:38 +02:00
|
|
|
$oHostDbPrimary->manifestFileCreate(
|
2018-07-03 20:01:57 +02:00
|
|
|
\%oManifest, MANIFEST_TARGET_PGTBLSPC . '/1', '16384/tablespace1.txt', 'TBLSPC1',
|
|
|
|
'd85de07d6421d90aa9191c11c889bfde43680f0f', $lTime, undef, undef, false);
|
2016-12-23 15:22:59 +02:00
|
|
|
|
2017-06-09 23:51:41 +02:00
|
|
|
# Remove the main manifest so the backup appears aborted
|
|
|
|
forceStorageRemove(storageRepo(), "${strResumePath}/" . FILE_MANIFEST);
|
|
|
|
|
2016-12-23 15:22:59 +02:00
|
|
|
# Add tablespace 2
|
2020-06-16 20:06:38 +02:00
|
|
|
$oHostDbPrimary->manifestTablespaceCreate(\%oManifest, 2);
|
|
|
|
$oHostDbPrimary->manifestPathCreate(\%oManifest, MANIFEST_TARGET_PGTBLSPC . '/2', '32768');
|
2016-12-23 15:22:59 +02:00
|
|
|
|
2020-06-16 20:06:38 +02:00
|
|
|
$oHostDbPrimary->manifestFileCreate(
|
2016-12-23 15:22:59 +02:00
|
|
|
\%oManifest, MANIFEST_TARGET_PGTBLSPC . '/2', '32768/tablespace2.txt', 'TBLSPC2',
|
|
|
|
'dc7f76e43c46101b47acc55ae4d593a9e6983578', $lTime, undef, undef, false);
|
|
|
|
|
2017-09-04 14:26:57 +02:00
|
|
|
# Make sure pg_internal.init is ignored in tablespaces
|
2020-06-16 20:06:38 +02:00
|
|
|
$oHostDbPrimary->dbFileCreate(\%oManifest, MANIFEST_TARGET_PGTBLSPC . '/2', '32768/' . DB_FILE_PGINTERNALINIT, 'IGNORE');
|
2017-03-02 20:50:29 +02:00
|
|
|
|
2016-12-23 15:22:59 +02:00
|
|
|
# Also create tablespace 11 to be sure it does not conflict with path of tablespace 1
|
2020-06-16 20:06:38 +02:00
|
|
|
$oHostDbPrimary->manifestTablespaceCreate(\%oManifest, 11);
|
2016-12-23 15:22:59 +02:00
|
|
|
|
2018-11-01 17:31:25 +02:00
|
|
|
# Change only the time to be in the past on a valid file and update the timestamp in the expected manifest
|
2020-06-16 20:06:38 +02:00
|
|
|
utime($lTime - 100, $lTime - 100, $oHostDbPrimary->dbBasePath() . '/changetime.txt')
|
|
|
|
or confess &log(ERROR, "unable to set time for file ".$oHostDbPrimary->dbBasePath() . '/changetime.txt');
|
2018-09-19 17:12:45 +02:00
|
|
|
$oManifest{&MANIFEST_SECTION_TARGET_FILE}{'pg_data/changetime.txt'}{&MANIFEST_SUBKEY_TIMESTAMP} = $lTime - 100;
|
|
|
|
|
2018-11-01 17:31:25 +02:00
|
|
|
# Change the content of the changecontent file to be the same size but leave the timestamp the same on the file
|
2020-06-16 20:06:38 +02:00
|
|
|
storageTest()->put($oHostDbPrimary->dbBasePath() . '/changecontent.txt', 'CHGCONT');
|
|
|
|
utime($lTime, $lTime, $oHostDbPrimary->dbBasePath() . '/changecontent.txt')
|
|
|
|
or confess &log(ERROR, "unable to set time for file ".$oHostDbPrimary->dbBasePath() . '/changecontent.txt');
|
2018-09-19 17:12:45 +02:00
|
|
|
|
2018-11-01 17:31:25 +02:00
|
|
|
# The changecontent & changetime files have conditions that will force the delta option to be turned on which should result
|
|
|
|
# in the reference of changecontent to be removed but the reference to changetime to stay since the checksum wouldn't change
|
|
|
|
$oManifest{&MANIFEST_SECTION_TARGET_FILE}{'pg_data/changecontent.txt'}{&MANIFEST_SUBKEY_CHECKSUM} =
|
|
|
|
"a094d94583e209556d03c3c5da33131a065f1689";
|
|
|
|
delete($oManifest{&MANIFEST_SECTION_TARGET_FILE}{'pg_data/changecontent.txt'}{&MANIFEST_SUBKEY_REFERENCE});
|
|
|
|
$oManifest{&MANIFEST_SECTION_TARGET_FILE}{'pg_data/changetime.txt'}{&MANIFEST_SUBKEY_TIMESTAMP} = $lTime - 100;
|
2018-09-19 17:12:45 +02:00
|
|
|
|
2019-03-10 11:03:52 +02:00
|
|
|
$oManifest{&MANIFEST_SECTION_BACKUP_OPTION}{&MANIFEST_KEY_PROCESS_MAX} = 1;
|
|
|
|
|
2016-12-23 15:22:59 +02:00
|
|
|
$strBackup = $oHostBackup->backup(
|
2017-06-22 00:47:25 +02:00
|
|
|
$strType, 'resume and add tablespace 2',
|
2019-11-21 23:06:27 +02:00
|
|
|
{oExpectedManifest => \%oManifest,
|
2020-03-09 23:41:59 +02:00
|
|
|
strOptionalParam => '--process-max=1' . ($bDeltaBackup ? ' --delta' : '')});
|
2016-12-23 15:22:59 +02:00
|
|
|
|
2020-05-13 00:55:20 +02:00
|
|
|
$oManifest{&MANIFEST_SECTION_BACKUP_OPTION}{&MANIFEST_KEY_PROCESS_MAX} = $strStorage eq S3 ? 2 : 1;
|
2019-03-10 11:03:52 +02:00
|
|
|
|
2018-09-19 17:12:45 +02:00
|
|
|
if (!$bRemote)
|
|
|
|
{
|
|
|
|
# Remove the size-changed test file to avoid expect log churn
|
2020-06-16 20:06:38 +02:00
|
|
|
$oHostDbPrimary->manifestFileRemove(\%oManifest, MANIFEST_TARGET_PGDATA, 'changesize.txt');
|
2018-09-19 17:12:45 +02:00
|
|
|
}
|
2018-07-03 20:01:57 +02:00
|
|
|
|
2019-12-18 03:14:45 +02:00
|
|
|
# Drop tablespace 11
|
2017-08-25 22:47:47 +02:00
|
|
|
#---------------------------------------------------------------------------------------------------------------------------
|
|
|
|
$strType = CFGOPTVAL_BACKUP_TYPE_DIFF;
|
2016-12-23 15:22:59 +02:00
|
|
|
|
|
|
|
# Drop tablespace 11
|
2020-06-16 20:06:38 +02:00
|
|
|
$oHostDbPrimary->manifestTablespaceDrop(\%oManifest, 11);
|
2016-12-23 15:22:59 +02:00
|
|
|
|
2019-03-10 11:03:52 +02:00
|
|
|
$oManifest{&MANIFEST_SECTION_BACKUP_OPTION}{&MANIFEST_KEY_PROCESS_MAX} = 1;
|
|
|
|
|
2016-12-23 15:22:59 +02:00
|
|
|
$strBackup = $oHostBackup->backup(
|
2019-12-18 03:14:45 +02:00
|
|
|
$strType, 'drop tablespace 11',
|
2020-03-09 23:41:59 +02:00
|
|
|
{oExpectedManifest => \%oManifest, strOptionalParam => '--process-max=1' . ($bDeltaBackup ? ' --delta' : '')});
|
2016-12-23 15:22:59 +02:00
|
|
|
|
2020-05-13 00:55:20 +02:00
|
|
|
$oManifest{&MANIFEST_SECTION_BACKUP_OPTION}{&MANIFEST_KEY_PROCESS_MAX} = $strStorage eq S3 ? 2 : 1;
|
2019-03-10 11:03:52 +02:00
|
|
|
|
2016-12-23 15:22:59 +02:00
|
|
|
# Restore
|
2017-08-25 22:47:47 +02:00
|
|
|
#---------------------------------------------------------------------------------------------------------------------------
|
2016-12-23 15:22:59 +02:00
|
|
|
# Remap the base and tablespace paths
|
|
|
|
my %oRemapHash;
|
2020-06-16 20:06:38 +02:00
|
|
|
$oRemapHash{&MANIFEST_TARGET_PGDATA} = $oHostDbPrimary->dbBasePath(2);
|
|
|
|
storageTest()->pathCreate($oHostDbPrimary->dbBasePath(2), {strMode => '0700', bCreateParent => true});
|
|
|
|
$oRemapHash{&MANIFEST_TARGET_PGTBLSPC . '/1'} = $oHostDbPrimary->tablespacePath(1, 2);
|
|
|
|
$oRemapHash{&MANIFEST_TARGET_PGTBLSPC . '/2'} = $oHostDbPrimary->tablespacePath(2, 2);
|
2016-12-23 15:22:59 +02:00
|
|
|
|
2020-06-16 20:06:38 +02:00
|
|
|
$oHostDbPrimary->restore(
|
2019-05-23 00:23:44 +02:00
|
|
|
'remap all paths', $strBackup, {rhExpectedManifest => \%oManifest, rhRemapHash => \%oRemapHash});
|
2016-12-23 15:22:59 +02:00
|
|
|
|
|
|
|
# Restore (make sure file in root tablespace path is not deleted by --delta)
|
2017-08-25 22:47:47 +02:00
|
|
|
#---------------------------------------------------------------------------------------------------------------------------
|
2020-06-16 20:06:38 +02:00
|
|
|
$oHostDbPrimary->restore(
|
2017-12-04 00:08:49 +02:00
|
|
|
'ensure file in tblspc root remains after --delta', $strBackup,
|
2019-05-23 00:23:44 +02:00
|
|
|
{rhExpectedManifest => \%oManifest, rhRemapHash => \%oRemapHash, bDelta => true});
|
2016-12-23 15:22:59 +02:00
|
|
|
|
|
|
|
if (!-e $strDoNotDeleteFile)
|
|
|
|
{
|
|
|
|
confess "${strDoNotDeleteFile} was deleted by --delta";
|
|
|
|
}
|
|
|
|
|
|
|
|
# Incr Backup
|
2017-08-25 22:47:47 +02:00
|
|
|
#---------------------------------------------------------------------------------------------------------------------------
|
|
|
|
$strType = CFGOPTVAL_BACKUP_TYPE_INCR;
|
2020-06-16 20:06:38 +02:00
|
|
|
$oHostDbPrimary->manifestReference(\%oManifest, $strBackup);
|
2016-12-23 15:22:59 +02:00
|
|
|
|
2020-06-16 20:06:38 +02:00
|
|
|
$oHostDbPrimary->manifestFileCreate(
|
2019-11-25 14:37:09 +02:00
|
|
|
\%oManifest, MANIFEST_TARGET_PGDATA, 'base/base2.txt', 'BASE2', '09b5e31766be1dba1ec27de82f975c1b6eea2a92', $lTime);
|
2016-12-23 15:22:59 +02:00
|
|
|
|
2020-06-16 20:06:38 +02:00
|
|
|
$oHostDbPrimary->manifestTablespaceDrop(\%oManifest, 1, 2);
|
2016-12-23 15:22:59 +02:00
|
|
|
|
2020-06-16 20:06:38 +02:00
|
|
|
$oHostDbPrimary->manifestFileCreate(
|
2016-12-23 15:22:59 +02:00
|
|
|
\%oManifest, MANIFEST_TARGET_PGTBLSPC . '/2', '32768/tablespace2b.txt', 'TBLSPC2B',
|
|
|
|
'e324463005236d83e6e54795dbddd20a74533bf3', $lTime, undef, undef, false);
|
|
|
|
|
|
|
|
# Munge the version to make sure it gets corrected on the next run
|
2017-04-10 19:24:45 +02:00
|
|
|
$oHostBackup->manifestMunge($strBackup, {&INI_SECTION_BACKREST => {&INI_KEY_VERSION => '0.00'}}, false);
|
2016-12-23 15:22:59 +02:00
|
|
|
|
2019-03-10 11:03:52 +02:00
|
|
|
$oManifest{&MANIFEST_SECTION_BACKUP_OPTION}{&MANIFEST_KEY_PROCESS_MAX} = 1;
|
|
|
|
|
2016-12-23 15:22:59 +02:00
|
|
|
$strBackup = $oHostBackup->backup(
|
|
|
|
$strType, 'add files and remove tablespace 2',
|
2020-03-09 23:41:59 +02:00
|
|
|
{oExpectedManifest => \%oManifest, strOptionalParam => '--process-max=1'});
|
2016-12-23 15:22:59 +02:00
|
|
|
|
2020-05-13 00:55:20 +02:00
|
|
|
$oManifest{&MANIFEST_SECTION_BACKUP_OPTION}{&MANIFEST_KEY_PROCESS_MAX} = $strStorage eq S3 ? 2 : 1;
|
2019-03-10 11:03:52 +02:00
|
|
|
|
2016-12-23 15:22:59 +02:00
|
|
|
# Incr Backup
|
2017-08-25 22:47:47 +02:00
|
|
|
#---------------------------------------------------------------------------------------------------------------------------
|
|
|
|
$strType = CFGOPTVAL_BACKUP_TYPE_INCR;
|
2020-06-16 20:06:38 +02:00
|
|
|
$oHostDbPrimary->manifestReference(\%oManifest, $strBackup);
|
2016-12-23 15:22:59 +02:00
|
|
|
|
2020-06-16 20:06:38 +02:00
|
|
|
$oHostDbPrimary->manifestFileCreate(
|
2016-12-23 15:22:59 +02:00
|
|
|
\%oManifest, MANIFEST_TARGET_PGDATA, 'base/16384/17000', 'BASEUPDT', '9a53d532e27785e681766c98516a5e93f096a501',
|
|
|
|
$lTime, undef, undef, false);
|
|
|
|
|
|
|
|
# Perform the backup
|
2019-05-23 00:23:44 +02:00
|
|
|
$strBackup =$oHostBackup->backup($strType, 'update files', {oExpectedManifest => \%oManifest});
|
2016-12-23 15:22:59 +02:00
|
|
|
|
|
|
|
# Diff Backup
|
2017-08-25 22:47:47 +02:00
|
|
|
#---------------------------------------------------------------------------------------------------------------------------
|
|
|
|
$strType = CFGOPTVAL_BACKUP_TYPE_DIFF;
|
2020-06-16 20:06:38 +02:00
|
|
|
$oHostDbPrimary->manifestReference(\%oManifest, $strFullBackup, true);
|
2016-12-23 15:22:59 +02:00
|
|
|
|
2019-03-10 11:03:52 +02:00
|
|
|
$oManifest{&MANIFEST_SECTION_BACKUP_OPTION}{&MANIFEST_KEY_PROCESS_MAX} = 1;
|
|
|
|
|
2016-12-23 15:22:59 +02:00
|
|
|
$strBackup = $oHostBackup->backup(
|
2017-06-22 00:47:25 +02:00
|
|
|
$strType, 'updates since last full', {oExpectedManifest => \%oManifest,
|
2020-03-09 23:41:59 +02:00
|
|
|
strOptionalParam => '--process-max=1' . ($bDeltaBackup ? ' --delta' : '')});
|
2016-12-23 15:22:59 +02:00
|
|
|
|
2020-05-13 00:55:20 +02:00
|
|
|
$oManifest{&MANIFEST_SECTION_BACKUP_OPTION}{&MANIFEST_KEY_PROCESS_MAX} = $strStorage eq S3 ? 2 : 1;
|
2019-03-10 11:03:52 +02:00
|
|
|
|
2019-12-18 03:14:45 +02:00
|
|
|
# Diff Backup with files removed
|
2017-08-25 22:47:47 +02:00
|
|
|
#---------------------------------------------------------------------------------------------------------------------------
|
2020-06-16 20:06:38 +02:00
|
|
|
$oHostDbPrimary->manifestReference(\%oManifest, $strFullBackup, true);
|
2016-12-23 15:22:59 +02:00
|
|
|
|
2017-08-25 22:47:47 +02:00
|
|
|
$strType = CFGOPTVAL_BACKUP_TYPE_DIFF;
|
2016-12-23 15:22:59 +02:00
|
|
|
|
2020-03-06 21:41:03 +02:00
|
|
|
# Enable compression to ensure a warning is raised (reset when gz to avoid log churn since it is the default)
|
|
|
|
if ($strCompressType eq GZ)
|
|
|
|
{
|
2020-03-09 23:41:59 +02:00
|
|
|
$oHostBackup->configUpdate({&CFGDEF_SECTION_GLOBAL => {'compress-type' => undef}});
|
2020-03-06 21:41:03 +02:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2020-03-09 23:41:59 +02:00
|
|
|
$oHostBackup->configUpdate({&CFGDEF_SECTION_GLOBAL => {'compress-type' => $strCompressType}});
|
2020-03-06 21:41:03 +02:00
|
|
|
}
|
2019-12-18 03:14:45 +02:00
|
|
|
|
2017-06-15 21:32:10 +02:00
|
|
|
# Enable hardlinks (except for s3) to ensure a warning is raised
|
2020-05-13 00:55:20 +02:00
|
|
|
if ($strStorage eq POSIX)
|
2017-06-15 21:32:10 +02:00
|
|
|
{
|
2020-03-09 23:41:59 +02:00
|
|
|
$oHostBackup->configUpdate({&CFGDEF_SECTION_GLOBAL => {'repo1-hardlink' => 'y'}});
|
2017-06-15 21:32:10 +02:00
|
|
|
}
|
|
|
|
|
2019-03-10 11:03:52 +02:00
|
|
|
$oManifest{&MANIFEST_SECTION_BACKUP_OPTION}{&MANIFEST_KEY_PROCESS_MAX} = 1;
|
|
|
|
|
2020-06-16 20:06:38 +02:00
|
|
|
$oHostDbPrimary->manifestFileRemove(\%oManifest, MANIFEST_TARGET_PGTBLSPC . '/2', '32768/tablespace2b.txt', true);
|
|
|
|
$oHostDbPrimary->manifestFileRemove(\%oManifest, MANIFEST_TARGET_PGDATA, 'base/base2.txt', true);
|
|
|
|
$oHostDbPrimary->manifestFileRemove(\%oManifest, MANIFEST_TARGET_PGDATA, 'base/16384/17000');
|
2016-12-23 15:22:59 +02:00
|
|
|
|
2020-06-16 20:06:38 +02:00
|
|
|
$oHostDbPrimary->manifestFileCreate(
|
2016-12-23 15:22:59 +02:00
|
|
|
\%oManifest, MANIFEST_TARGET_PGTBLSPC . '/2', '32768/tablespace2c.txt', 'TBLSPCBIGGER',
|
|
|
|
'dfcb8679956b734706cf87259d50c88f83e80e66', $lTime, undef, undef, false);
|
|
|
|
|
2019-12-18 03:14:45 +02:00
|
|
|
$oHostBackup->backup(
|
|
|
|
$strType, 'remove files',
|
2019-11-25 14:48:52 +02:00
|
|
|
{oExpectedManifest => \%oManifest,
|
2020-03-09 23:41:59 +02:00
|
|
|
strOptionalParam => '--process-max=1' . ($bDeltaBackup ? ' --delta' : '')});
|
2016-12-23 15:22:59 +02:00
|
|
|
|
2020-05-13 00:55:20 +02:00
|
|
|
$oManifest{&MANIFEST_SECTION_BACKUP_OPTION}{&MANIFEST_KEY_PROCESS_MAX} = $strStorage eq S3 ? 2 : 1;
|
2019-03-10 11:03:52 +02:00
|
|
|
|
2016-12-23 15:22:59 +02:00
|
|
|
# Full Backup
|
2017-08-25 22:47:47 +02:00
|
|
|
#---------------------------------------------------------------------------------------------------------------------------
|
|
|
|
$strType = CFGOPTVAL_BACKUP_TYPE_FULL;
|
2016-12-23 15:22:59 +02:00
|
|
|
|
2017-06-15 21:32:10 +02:00
|
|
|
# Now the compression and hardlink changes will take effect
|
|
|
|
$oManifest{&MANIFEST_SECTION_BACKUP_OPTION}{&MANIFEST_KEY_COMPRESS} = JSON::PP::true;
|
2020-03-06 21:41:03 +02:00
|
|
|
$oManifest{&MANIFEST_SECTION_BACKUP_OPTION}{&MANIFEST_KEY_COMPRESS_TYPE} = $strCompressType;
|
2017-06-15 21:32:10 +02:00
|
|
|
|
2020-05-13 00:55:20 +02:00
|
|
|
if ($strStorage eq POSIX)
|
2017-06-15 21:32:10 +02:00
|
|
|
{
|
|
|
|
$oManifest{&MANIFEST_SECTION_BACKUP_OPTION}{&MANIFEST_KEY_HARDLINK} = JSON::PP::true;
|
|
|
|
$oHostBackup->{bHardLink} = true;
|
|
|
|
}
|
|
|
|
|
2020-06-16 20:06:38 +02:00
|
|
|
$oHostDbPrimary->manifestReference(\%oManifest);
|
2016-12-23 15:22:59 +02:00
|
|
|
|
2020-06-16 20:06:38 +02:00
|
|
|
$oHostDbPrimary->manifestFileCreate(
|
2016-12-23 15:22:59 +02:00
|
|
|
\%oManifest, MANIFEST_TARGET_PGDATA, 'base/16384/17000', 'BASEUPDT2', '7579ada0808d7f98087a0a586d0df9de009cdc33',
|
|
|
|
$lTime, undef, undef, false);
|
|
|
|
|
|
|
|
$oManifest{&MANIFEST_SECTION_BACKUP_OPTION}{&MANIFEST_KEY_CHECKSUM_PAGE} = JSON::PP::false;
|
|
|
|
|
|
|
|
$strFullBackup = $oHostBackup->backup(
|
2019-05-23 00:23:44 +02:00
|
|
|
$strType, 'update file', {oExpectedManifest => \%oManifest});
|
2016-12-23 15:22:59 +02:00
|
|
|
|
|
|
|
# Call expire
|
2017-08-25 22:47:47 +02:00
|
|
|
#---------------------------------------------------------------------------------------------------------------------------
|
2017-06-15 21:32:10 +02:00
|
|
|
$oHostBackup->expire({iRetentionFull => 1});
|
2016-12-23 15:22:59 +02:00
|
|
|
|
|
|
|
# Diff Backup
|
2017-08-25 22:47:47 +02:00
|
|
|
#---------------------------------------------------------------------------------------------------------------------------
|
|
|
|
$strType = CFGOPTVAL_BACKUP_TYPE_DIFF;
|
2016-12-23 15:22:59 +02:00
|
|
|
|
2020-06-16 20:06:38 +02:00
|
|
|
$oHostDbPrimary->manifestReference(\%oManifest, $strFullBackup);
|
2016-12-23 15:22:59 +02:00
|
|
|
|
2020-06-16 20:06:38 +02:00
|
|
|
$oHostDbPrimary->manifestFileCreate(
|
2016-12-23 15:22:59 +02:00
|
|
|
\%oManifest, MANIFEST_TARGET_PGDATA, 'base/base2.txt', 'BASE2UPDT', 'cafac3c59553f2cfde41ce2e62e7662295f108c0',
|
|
|
|
$lTime, undef, undef, false);
|
|
|
|
|
|
|
|
# Munge the prior manifest so that option-checksum-page is missing to be sure the logic works for backups before page
|
|
|
|
# checksums were introduced
|
2017-04-10 19:24:45 +02:00
|
|
|
$oHostBackup->manifestMunge(
|
|
|
|
$strFullBackup, {&MANIFEST_SECTION_BACKUP_OPTION => {&MANIFEST_KEY_CHECKSUM_PAGE => undef}}, false);
|
2016-12-23 15:22:59 +02:00
|
|
|
|
|
|
|
$strBackup = $oHostBackup->backup(
|
2020-03-09 23:41:59 +02:00
|
|
|
$strType, 'add file', {oExpectedManifest => \%oManifest, strOptionalParam => '--checksum-page'});
|
2016-12-23 15:22:59 +02:00
|
|
|
|
|
|
|
# Selective Restore
|
2017-08-25 22:47:47 +02:00
|
|
|
#---------------------------------------------------------------------------------------------------------------------------
|
2016-12-23 15:22:59 +02:00
|
|
|
# Remove mapping for tablespace 1
|
|
|
|
delete($oRemapHash{&MANIFEST_TARGET_PGTBLSPC . '/1'});
|
|
|
|
|
|
|
|
# Remove checksum to match zeroed files
|
|
|
|
delete($oManifest{&MANIFEST_SECTION_TARGET_FILE}{'pg_data/base/32768/33000'}{&MANIFEST_SUBKEY_CHECKSUM});
|
|
|
|
delete($oManifest{&MANIFEST_SECTION_TARGET_FILE}{'pg_data/base/32768/33001'}{&MANIFEST_SUBKEY_CHECKSUM});
|
|
|
|
delete($oManifest{&MANIFEST_SECTION_TARGET_FILE}{'pg_tblspc/2/PG_9.4_201409291/32768/tablespace2.txt'}
|
|
|
|
{&MANIFEST_SUBKEY_CHECKSUM});
|
|
|
|
delete($oManifest{&MANIFEST_SECTION_TARGET_FILE}{'pg_tblspc/2/PG_9.4_201409291/32768/tablespace2c.txt'}
|
|
|
|
{&MANIFEST_SUBKEY_CHECKSUM});
|
|
|
|
|
2020-06-16 20:06:38 +02:00
|
|
|
$oHostDbPrimary->restore(
|
2020-03-09 23:41:59 +02:00
|
|
|
'selective restore 16384', 'latest',
|
2017-12-04 00:08:49 +02:00
|
|
|
{rhExpectedManifest => \%oManifest, rhRemapHash => \%oRemapHash, bDelta => true,
|
2019-05-23 00:23:44 +02:00
|
|
|
strOptionalParam => '--db-include=16384'});
|
2016-12-23 15:22:59 +02:00
|
|
|
|
|
|
|
# Restore checksum values for next test
|
|
|
|
$oManifest{&MANIFEST_SECTION_TARGET_FILE}{'pg_data/base/32768/33000'}{&MANIFEST_SUBKEY_CHECKSUM} =
|
2022-02-23 20:05:53 +02:00
|
|
|
'1d73a0052828531770e7c155aeb22338e017e196';
|
2016-12-23 15:22:59 +02:00
|
|
|
$oManifest{&MANIFEST_SECTION_TARGET_FILE}{'pg_data/base/32768/33001'}{&MANIFEST_SUBKEY_CHECKSUM} =
|
|
|
|
'6bf316f11d28c28914ea9be92c00de9bea6d9a6b';
|
|
|
|
$oManifest{&MANIFEST_SECTION_TARGET_FILE}{'pg_tblspc/2/PG_9.4_201409291/32768/tablespace2.txt'}
|
|
|
|
{&MANIFEST_SUBKEY_CHECKSUM} = 'dc7f76e43c46101b47acc55ae4d593a9e6983578';
|
|
|
|
$oManifest{&MANIFEST_SECTION_TARGET_FILE}{'pg_tblspc/2/PG_9.4_201409291/32768/tablespace2c.txt'}
|
|
|
|
{&MANIFEST_SUBKEY_CHECKSUM} = 'dfcb8679956b734706cf87259d50c88f83e80e66';
|
|
|
|
|
|
|
|
# Remove checksum to match zeroed file
|
|
|
|
delete($oManifest{&MANIFEST_SECTION_TARGET_FILE}{'pg_data/base/16384/17000'}{&MANIFEST_SUBKEY_CHECKSUM});
|
|
|
|
|
2020-06-16 20:06:38 +02:00
|
|
|
$oHostDbPrimary->restore(
|
2020-03-09 23:41:59 +02:00
|
|
|
'selective restore 32768', 'latest',
|
2017-12-04 00:08:49 +02:00
|
|
|
{rhExpectedManifest => \%oManifest, rhRemapHash => \%oRemapHash, bDelta => true,
|
2019-05-23 00:23:44 +02:00
|
|
|
strOptionalParam => '--db-include=32768'});
|
2016-12-23 15:22:59 +02:00
|
|
|
|
|
|
|
$oManifest{&MANIFEST_SECTION_TARGET_FILE}{'pg_data/base/16384/17000'}{&MANIFEST_SUBKEY_CHECKSUM} =
|
|
|
|
'7579ada0808d7f98087a0a586d0df9de009cdc33';
|
|
|
|
|
2020-06-16 20:06:38 +02:00
|
|
|
$oHostDbPrimary->restore(
|
2020-03-09 23:41:59 +02:00
|
|
|
'error on invalid id', 'latest',
|
2017-12-04 00:08:49 +02:00
|
|
|
{rhExpectedManifest => \%oManifest, rhRemapHash => \%oRemapHash, bDelta => true,
|
|
|
|
iExpectedExitStatus => ERROR_DB_MISSING, strOptionalParam => '--log-level-console=warn --db-include=7777'});
|
2016-12-23 15:22:59 +02:00
|
|
|
|
2020-06-16 20:06:38 +02:00
|
|
|
$oHostDbPrimary->restore(
|
2020-03-09 23:41:59 +02:00
|
|
|
'error on system id', 'latest',
|
2017-12-04 00:08:49 +02:00
|
|
|
{rhExpectedManifest => \%oManifest, rhRemapHash => \%oRemapHash, bDelta => true,
|
|
|
|
iExpectedExitStatus => ERROR_DB_INVALID, strOptionalParam => '--log-level-console=warn --db-include=1'});
|
2016-12-23 15:22:59 +02:00
|
|
|
|
|
|
|
# Compact Restore
|
2017-08-25 22:47:47 +02:00
|
|
|
#---------------------------------------------------------------------------------------------------------------------------
|
2020-06-16 20:06:38 +02:00
|
|
|
executeTest('rm -rf ' . $oHostDbPrimary->dbBasePath(2) . "/*");
|
2016-12-23 15:22:59 +02:00
|
|
|
|
2020-06-16 20:06:38 +02:00
|
|
|
my $strDbPath = $oHostDbPrimary->dbBasePath(2) . '/base';
|
2017-06-09 23:51:41 +02:00
|
|
|
storageTest()->pathCreate($strDbPath, {strMode => '0700'});
|
2016-12-23 15:22:59 +02:00
|
|
|
|
|
|
|
$oRemapHash{&MANIFEST_TARGET_PGDATA} = $strDbPath;
|
|
|
|
delete($oRemapHash{&MANIFEST_TARGET_PGTBLSPC . '/2'});
|
|
|
|
|
2020-06-16 20:06:38 +02:00
|
|
|
$oHostDbPrimary->restore(
|
2020-03-09 23:41:59 +02:00
|
|
|
'no tablespace remap', 'latest',
|
2019-09-26 13:52:02 +02:00
|
|
|
{rhExpectedManifest => \%oManifest, rhRemapHash => \%oRemapHash, bTablespace => false,
|
2019-05-23 00:23:44 +02:00
|
|
|
strOptionalParam => '--tablespace-map-all=../../tablespace'});
|
2016-12-23 15:22:59 +02:00
|
|
|
|
|
|
|
$oManifest{&MANIFEST_SECTION_BACKUP_TARGET}{'pg_tblspc/2'}{&MANIFEST_SUBKEY_PATH} = '../../tablespace/ts2';
|
|
|
|
$oManifest{&MANIFEST_SECTION_TARGET_LINK}{'pg_data/pg_tblspc/2'}{&MANIFEST_SUBKEY_DESTINATION} = '../../tablespace/ts2';
|
|
|
|
|
|
|
|
# Dump out history path at the end to verify all history files are being recorded. This test is only performed locally
|
|
|
|
# because for some reason sort order is different when this command is executed via ssh (even though the content of the
|
|
|
|
# directory is identical).
|
2017-08-25 22:47:47 +02:00
|
|
|
#---------------------------------------------------------------------------------------------------------------------------
|
2020-05-13 00:55:20 +02:00
|
|
|
if (!$bRemote && $strStorage eq POSIX)
|
2016-12-23 15:22:59 +02:00
|
|
|
{
|
2020-03-09 23:41:59 +02:00
|
|
|
executeTest(
|
|
|
|
'ls -1Rtr ' . $oHostBackup->repoBackupPath(PATH_BACKUP_HISTORY),
|
|
|
|
{oLogTest => $self->expect(), bRemote => $bRemote});
|
2016-12-23 15:22:59 +02:00
|
|
|
}
|
|
|
|
|
2017-05-12 22:05:44 +02:00
|
|
|
# Test backup from standby warning that standby not configured so option reset
|
2017-08-25 22:47:47 +02:00
|
|
|
#---------------------------------------------------------------------------------------------------------------------------
|
2017-06-15 21:32:10 +02:00
|
|
|
if (!defined($oHostDbStandby))
|
2017-05-12 22:05:44 +02:00
|
|
|
{
|
|
|
|
$strBackup = $oHostBackup->backup(
|
2020-06-16 20:06:38 +02:00
|
|
|
$strType, 'option backup-standby reset - backup performed from primary', {oExpectedManifest => \%oManifest,
|
2020-03-09 23:41:59 +02:00
|
|
|
strOptionalParam => '--log-level-console=info --backup-standby'});
|
2017-05-12 22:05:44 +02:00
|
|
|
}
|
2016-12-23 15:22:59 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
1;
|