FastRestore:addPrefix:Transform must clear both orignal and transformed range
Otherwise, anything left in the range can interfer with the result.
This commit is contained in:
parent
9318ec033d
commit
3d6f69c8e2
|
@ -257,6 +257,8 @@ struct RestoreAsset {
|
|||
return ss.str();
|
||||
}
|
||||
|
||||
bool hasPrefix() const { return addPrefix.size() > 0 || removePrefix.size() > 0; }
|
||||
|
||||
// RestoreAsset and VersionBatch both use endVersion as exclusive in version range
|
||||
bool isInVersionRange(Version commitVersion) const {
|
||||
return commitVersion >= beginVersion && commitVersion < endVersion;
|
||||
|
@ -264,11 +266,24 @@ struct RestoreAsset {
|
|||
|
||||
// Is mutation's begin and end keys are in RestoreAsset's range
|
||||
bool isInKeyRange(MutationRef mutation) const {
|
||||
if (isRangeMutation(mutation)) {
|
||||
// Range mutation's right side is exclusive
|
||||
return mutation.param1 >= range.begin && mutation.param2 <= range.end;
|
||||
if (hasPrefix()) {
|
||||
Key begin = range.begin; // Avoid creating new keys if we do not have addPrefix or removePrefix
|
||||
Key end = range.end;
|
||||
begin = begin.removePrefix(removePrefix).withPrefix(addPrefix);
|
||||
end = end.removePrefix(removePrefix).withPrefix(addPrefix);
|
||||
if (isRangeMutation(mutation)) {
|
||||
// Range mutation's right side is exclusive
|
||||
return mutation.param1 >= begin && mutation.param2 <= end;
|
||||
} else {
|
||||
return mutation.param1 >= begin && mutation.param1 < end;
|
||||
}
|
||||
} else {
|
||||
return mutation.param1 >= range.begin && mutation.param1 < range.end;
|
||||
if (isRangeMutation(mutation)) {
|
||||
// Range mutation's right side is exclusive
|
||||
return mutation.param1 >= range.begin && mutation.param2 <= range.end;
|
||||
} else {
|
||||
return mutation.param1 >= range.begin && mutation.param1 < range.end;
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
|
|
@ -147,7 +147,8 @@ ACTOR static Future<Void> handleSendMutationVectorRequest(RestoreSendVersionedMu
|
|||
isAtomicOp((MutationRef::Type)versionedMutation.mutation.type) ? 1 : 0;
|
||||
// Sanity check
|
||||
ASSERT_WE_THINK(req.asset.isInVersionRange(versionedMutation.version.version));
|
||||
ASSERT_WE_THINK(req.asset.isInKeyRange(versionedMutation.mutation));
|
||||
ASSERT_WE_THINK(req.asset.isInKeyRange(
|
||||
versionedMutation.mutation)); // mutation is already applied removePrefix and addPrefix
|
||||
|
||||
// Note: Log and range mutations may be delivered out of order. Can we handle it?
|
||||
batchData->addMutation(versionedMutation.mutation, versionedMutation.version);
|
||||
|
|
|
@ -793,7 +793,7 @@ void _parseSerializedMutation(KeyRangeMap<Version>* pRangeVersions,
|
|||
(!isRangeMutation(mutation) && mutation.param1 < asset.range.begin)) {
|
||||
continue;
|
||||
}
|
||||
// Only apply mutation within the asset.range
|
||||
// Only apply mutation within the asset.range and apply removePrefix and addPrefix
|
||||
if (isRangeMutation(mutation)) {
|
||||
mutation.param1 = mutation.param1 >= asset.range.begin ? mutation.param1 : asset.range.begin;
|
||||
mutation.param2 = mutation.param2 < asset.range.end ? mutation.param2 : asset.range.end;
|
||||
|
|
|
@ -381,7 +381,10 @@ struct BackupAndParallelRestoreCorrectnessWorkload : TestWorkload {
|
|||
tr->setOption(FDBTransactionOptions::LOCK_AWARE);
|
||||
for (auto& range : restoreRanges) {
|
||||
TraceEvent("TransformDatabaseContents").detail("Clear", range);
|
||||
tr->clear(range); // Careful when we restore only a sub key range!
|
||||
tr->clear(range); // Clear the range.removePrefix().withPrefix()
|
||||
KeyRange newRange = range;
|
||||
newRange = newRange.removePrefix(removePrefix).withPrefix(addPrefix); // Clear dest. range
|
||||
tr->clear(newRange);
|
||||
}
|
||||
return Void();
|
||||
}));
|
||||
|
|
Loading…
Reference in New Issue