You've already forked pgbackrest
mirror of
https://github.com/pgbackrest/pgbackrest.git
synced 2025-06-14 23:44:58 +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:
@ -12,6 +12,16 @@
|
|||||||
<release-list>
|
<release-list>
|
||||||
<release date="XXXX-XX-XX" version="1.25dev" title="UNDER DEVELOPMENT">
|
<release date="XXXX-XX-XX" version="1.25dev" title="UNDER DEVELOPMENT">
|
||||||
<release-core-list>
|
<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-refactor-list>
|
||||||
<release-item>
|
<release-item>
|
||||||
<p>Update C naming conventions.</p>
|
<p>Update C naming conventions.</p>
|
||||||
|
@ -281,9 +281,7 @@ sub walSegmentFind
|
|||||||
);
|
);
|
||||||
|
|
||||||
# Error if not a segment
|
# Error if not a segment
|
||||||
my $bTimeline = $strWalSegment =~ /^[0-F]{16}$/ ? false : true;
|
if (!walIsSegment($strWalSegment))
|
||||||
|
|
||||||
if ($bTimeline && !walIsSegment($strWalSegment))
|
|
||||||
{
|
{
|
||||||
confess &log(ERROR, "${strWalSegment} is not a WAL segment", ERROR_ASSERT);
|
confess &log(ERROR, "${strWalSegment} is not a WAL segment", ERROR_ASSERT);
|
||||||
}
|
}
|
||||||
@ -294,35 +292,13 @@ sub walSegmentFind
|
|||||||
|
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
# If the WAL segment includes the timeline then use it, otherwise contruct a regexp with the major WAL part to find paths
|
# Get the name of the requested WAL segment (may have compression extension)
|
||||||
# where the wal could be found.
|
push(@stryWalFileName, $oStorageRepo->list(
|
||||||
my @stryTimelineMajor;
|
STORAGE_REPO_ARCHIVE . "/${strArchiveId}/" . substr($strWalSegment, 0, 16),
|
||||||
|
{strExpression =>
|
||||||
if ($bTimeline)
|
'^' . substr($strWalSegment, 0, 24) . (walIsPartial($strWalSegment) ? "\\.partial" : '') .
|
||||||
{
|
"-[0-f]{40}(\\." . COMPRESS_EXT . "){0,1}\$",
|
||||||
@stryTimelineMajor = (substr($strWalSegment, 0, 16));
|
bIgnoreMissing => true}));
|
||||||
}
|
|
||||||
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}));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
while (@stryWalFileName == 0 && waitMore($oWait));
|
while (@stryWalFileName == 0 && waitMore($oWait));
|
||||||
|
|
||||||
@ -331,8 +307,9 @@ sub walSegmentFind
|
|||||||
if (@stryWalFileName > 1)
|
if (@stryWalFileName > 1)
|
||||||
{
|
{
|
||||||
confess &log(ERROR,
|
confess &log(ERROR,
|
||||||
"duplicates found in archive for WAL segment " . ($bTimeline ? $strWalSegment : "XXXXXXXX${strWalSegment}") . ': ' .
|
"duplicates found in archive for WAL segment ${strWalSegment}: " . join(', ', @stryWalFileName) .
|
||||||
join(', ', @stryWalFileName), ERROR_ARCHIVE_DUPLICATE);
|
"\nHINT: are multiple primaries archiving to this stanza?",
|
||||||
|
ERROR_ARCHIVE_DUPLICATE);
|
||||||
}
|
}
|
||||||
|
|
||||||
# If waiting and no WAL segment was found then throw an error
|
# If waiting and no WAL segment was found then throw an error
|
||||||
|
@ -889,7 +889,9 @@ sub process
|
|||||||
|
|
||||||
foreach my $strArchive (@stryArchive)
|
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);
|
$strArchive = substr($strArchiveFile, 0, 24);
|
||||||
|
|
||||||
if (cfgOption(CFGOPT_ARCHIVE_COPY))
|
if (cfgOption(CFGOPT_ARCHIVE_COPY))
|
||||||
|
@ -130,11 +130,6 @@ sub run
|
|||||||
$self->testResult(
|
$self->testResult(
|
||||||
sub {walSegmentFind(storageRepo(), $strArchiveId, $strWalSegment)}, $strWalSegmentHash, "${strWalSegment} WAL found");
|
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";
|
my $strWalSegmentHash2 = "${strWalSegment}-a0b0d38b8aa263e25b8ff52a0a4ba85b6be97f9b.gz";
|
||||||
|
|
||||||
@ -144,21 +139,7 @@ sub run
|
|||||||
sub {walSegmentFind(storageRepo(), $strArchiveId, $strWalSegment)}, ERROR_ARCHIVE_DUPLICATE,
|
sub {walSegmentFind(storageRepo(), $strArchiveId, $strWalSegment)}, ERROR_ARCHIVE_DUPLICATE,
|
||||||
"duplicates found in archive for WAL segment ${strWalSegment}: ${strWalSegmentHash}, ${strWalSegmentHash2}");
|
"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("${strWalMajorPath}/${strWalSegmentHash}");
|
||||||
storageRepo()->remove("${strWalMajorPath3}/${strWalSegmentHash3}");
|
|
||||||
|
|
||||||
#---------------------------------------------------------------------------------------------------------------------------
|
#---------------------------------------------------------------------------------------------------------------------------
|
||||||
$self->testResult(
|
$self->testResult(
|
||||||
|
Reference in New Issue
Block a user