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:
parent
583a76f605
commit
c94e52f697
@ -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>
|
||||
|
@ -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
|
||||
|
@ -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))
|
||||
|
@ -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(
|
||||
|
Loading…
x
Reference in New Issue
Block a user