FastRestore:Applier:Fix various bugs

1. segmentation error
2. there exist mutations that is not set or clear or atomicOp, precompute result should ignore them.
This commit is contained in:
Meng Xu 2020-02-13 09:24:53 -08:00
parent 4394605b6f
commit 238b2cb8e4
2 changed files with 27 additions and 5 deletions

View File

@ -293,6 +293,7 @@ ACTOR static Future<Void> precomputeMutationsResult(Reference<ApplierBatchData>
}
}
TraceEvent("FastRestoreApplierGetAndComputeStagingKeysWaitOn", applierID);
wait(fGetAndComputeKeys);
// Sanity check all stagingKeys have been precomputed
@ -794,6 +795,9 @@ Value applyAtomicOp(Optional<StringRef> existingValue, Value value, MutationRef:
return doByteMin(existingValue, value, arena);
else if (type == MutationRef::ByteMax)
return doByteMax(existingValue, value, arena);
ASSERT(false);
else {
TraceEvent(SevError, "ApplyAtomicOpUnhandledType").detail("Type", type).detail("TypeStr", typeString[type]);
ASSERT(false);
}
return Value();
}

View File

@ -82,7 +82,14 @@ struct StagingKey {
}
void precomputeResult() {
TraceEvent(SevDebug, "FastRestoreApplierPrecomputeResult")
.detail("Key", key)
.detail("Version", version)
.detail("LargestPendingVersion", (pendingMutations.empty() ? -1 : pendingMutations.rbegin()->first));
std::map<Version, MutationsVec>::iterator lb = pendingMutations.lower_bound(version);
if (lb == pendingMutations.end()) {
return;
}
if (lb->first == version) {
// Sanity check mutations at version are either atomicOps which can be ignored or the same value as buffered
for (int i = 0; i < lb->second.size(); i++) {
@ -102,8 +109,18 @@ struct StagingKey {
if (lb->first == version) {
continue;
}
for (auto& atomicOp : lb->second) {
val = applyAtomicOp(val, atomicOp.param2, (MutationRef::Type)atomicOp.type);
for (auto& mutation : lb->second) {
if (isAtomicOp((MutationRef::Type) mutation.type)) {
val = applyAtomicOp(val, mutation.param2, (MutationRef::Type)mutation.type);
} else if (mutation.type == MutationRef::SetValue || mutation.type == MutationRef::ClearRange) {
TraceEvent(SevError, "FastRestoreApplierPrecomputeResultUnexpectedSet")
.detail("Type", typeString[mutation.type])
.detail("Version", lb->first);
} else {
TraceEvent(SevWarnAlways, "FastRestoreApplierPrecomputeResultSkipUnexpectedBackupMutation")
.detail("Type", typeString[mutation.type])
.detail("Version", lb->first);
}
}
version = lb->first;
type = MutationRef::SetValue; // Precomputed result should be set to DB.
@ -120,8 +137,8 @@ struct StagingKey {
// Has all pendingMutations been pre-applied to the val?
bool hasPrecomputed() {
ASSERT(pendingMutations.rbegin()->first >= pendingMutations.begin()->first);
return version >= pendingMutations.rbegin()->first;
ASSERT(pendingMutations.empty() || pendingMutations.rbegin()->first >= pendingMutations.begin()->first);
return pendingMutations.empty() || version >= pendingMutations.rbegin()->first;
}
int expectedMutationSize() { return key.size() + val.size(); }
@ -200,6 +217,7 @@ struct ApplierBatchData : public ReferenceCounted<ApplierBatchData> {
return false;
}
}
TraceEvent("FastRestoreApplierAllKeysPrecomputed");
return true;
}