1
0
mirror of https://github.com/pgbackrest/pgbackrest.git synced 2025-03-03 14:52:21 +02:00

Remove error when overlapping timelines are detected.

Overlapping timelines are valid in many Point-in-Time-Recovery (PITR) scenarios.

Reported by blogh.
This commit is contained in:
David Steele 2017-10-16 14:34:44 -04:00
parent 583a76f605
commit c94e52f697
4 changed files with 24 additions and 54 deletions

View File

@ -12,6 +12,16 @@
<release-list>
<release date="XXXX-XX-XX" version="1.25dev" title="UNDER DEVELOPMENT">
<release-core-list>
<release-bug-list>
<release-item>
<release-item-contributor-list>
<release-item-ideator id="lobréau.benoit"/>
</release-item-contributor-list>
<p>Remove error when overlapping timelines are detected. Overlapping timelines are valid in many Point-in-Time-Recovery (PITR) scenarios.</p>
</release-item>
</release-bug-list>
<release-refactor-list>
<release-item>
<p>Update C naming conventions.</p>

View File

@ -281,9 +281,7 @@ sub walSegmentFind
);
# Error if not a segment
my $bTimeline = $strWalSegment =~ /^[0-F]{16}$/ ? false : true;
if ($bTimeline && !walIsSegment($strWalSegment))
if (!walIsSegment($strWalSegment))
{
confess &log(ERROR, "${strWalSegment} is not a WAL segment", ERROR_ASSERT);
}
@ -294,35 +292,13 @@ sub walSegmentFind
do
{
# If the WAL segment includes the timeline then use it, otherwise contruct a regexp with the major WAL part to find paths
# where the wal could be found.
my @stryTimelineMajor;
if ($bTimeline)
{
@stryTimelineMajor = (substr($strWalSegment, 0, 16));
}
else
{
@stryTimelineMajor = $oStorageRepo->list(
STORAGE_REPO_ARCHIVE . "/${strArchiveId}",
{strExpression => '[0-F]{8}' . substr($strWalSegment, 0, 8), bIgnoreMissing => true});
}
# Search each timelin/major path
foreach my $strTimelineMajor (@stryTimelineMajor)
{
# Construct the name of the WAL segment to find
my $strWalSegmentFind = $bTimeline ? substr($strWalSegment, 0, 24) : $strTimelineMajor . substr($strWalSegment, 8, 16);
# Get the name of the requested WAL segment (may have hash info and compression extension)
push(@stryWalFileName, $oStorageRepo->list(
STORAGE_REPO_ARCHIVE . "/${strArchiveId}/${strTimelineMajor}",
{strExpression =>
"^${strWalSegmentFind}" . (walIsPartial($strWalSegment) ? "\\.partial" : '') .
"-[0-f]{40}(\\." . COMPRESS_EXT . "){0,1}\$",
bIgnoreMissing => true}));
}
# Get the name of the requested WAL segment (may have compression extension)
push(@stryWalFileName, $oStorageRepo->list(
STORAGE_REPO_ARCHIVE . "/${strArchiveId}/" . substr($strWalSegment, 0, 16),
{strExpression =>
'^' . substr($strWalSegment, 0, 24) . (walIsPartial($strWalSegment) ? "\\.partial" : '') .
"-[0-f]{40}(\\." . COMPRESS_EXT . "){0,1}\$",
bIgnoreMissing => true}));
}
while (@stryWalFileName == 0 && waitMore($oWait));
@ -331,8 +307,9 @@ sub walSegmentFind
if (@stryWalFileName > 1)
{
confess &log(ERROR,
"duplicates found in archive for WAL segment " . ($bTimeline ? $strWalSegment : "XXXXXXXX${strWalSegment}") . ': ' .
join(', ', @stryWalFileName), ERROR_ARCHIVE_DUPLICATE);
"duplicates found in archive for WAL segment ${strWalSegment}: " . join(', ', @stryWalFileName) .
"\nHINT: are multiple primaries archiving to this stanza?",
ERROR_ARCHIVE_DUPLICATE);
}
# If waiting and no WAL segment was found then throw an error

View File

@ -889,7 +889,9 @@ sub process
foreach my $strArchive (@stryArchive)
{
my $strArchiveFile = walSegmentFind($oStorageRepo, $strArchiveId, $strArchive, cfgOption(CFGOPT_ARCHIVE_TIMEOUT));
my $strArchiveFile = walSegmentFind(
$oStorageRepo, $strArchiveId, substr($strArchiveStop, 0, 8) . $strArchive, cfgOption(CFGOPT_ARCHIVE_TIMEOUT));
$strArchive = substr($strArchiveFile, 0, 24);
if (cfgOption(CFGOPT_ARCHIVE_COPY))

View File

@ -130,11 +130,6 @@ sub run
$self->testResult(
sub {walSegmentFind(storageRepo(), $strArchiveId, $strWalSegment)}, $strWalSegmentHash, "${strWalSegment} WAL found");
#---------------------------------------------------------------------------------------------------------------------------
$self->testResult(
sub {walSegmentFind(storageRepo(), $strArchiveId, substr($strWalSegment, 8, 16))}, $strWalSegmentHash,
"${strWalSegment} WAL found without timeline");
#---------------------------------------------------------------------------------------------------------------------------
my $strWalSegmentHash2 = "${strWalSegment}-a0b0d38b8aa263e25b8ff52a0a4ba85b6be97f9b.gz";
@ -144,21 +139,7 @@ sub run
sub {walSegmentFind(storageRepo(), $strArchiveId, $strWalSegment)}, ERROR_ARCHIVE_DUPLICATE,
"duplicates found in archive for WAL segment ${strWalSegment}: ${strWalSegmentHash}, ${strWalSegmentHash2}");
#---------------------------------------------------------------------------------------------------------------------------
my $strWalSegment3 = '00000002' . substr($strWalSegment, 8, 16);
my $strWalSegmentHash3 = "${strWalSegment3}-dcdd09246e1918e88c67cf44b35edc23b803d879";
my $strWalMajorPath3 = "${strArchivePath}/" . substr($strWalSegment3, 0, 16);
storageRepo()->pathCreate($strWalMajorPath3, {bCreateParent => true});
storageRepo()->put("${strWalMajorPath3}/${strWalSegmentHash3}");
$self->testException(
sub {walSegmentFind(storageRepo(), $strArchiveId, substr($strWalSegment, 8, 16))}, ERROR_ARCHIVE_DUPLICATE,
"duplicates found in archive for WAL segment XXXXXXXX" . substr($strWalSegment, 8, 16) .
": ${strWalSegmentHash}, ${strWalSegmentHash2}, ${strWalSegmentHash3}");
storageRepo()->remove("${strWalMajorPath}/${strWalSegmentHash}");
storageRepo()->remove("${strWalMajorPath3}/${strWalSegmentHash3}");
#---------------------------------------------------------------------------------------------------------------------------
$self->testResult(