mirror of
https://github.com/apple/foundationdb.git
synced 2025-05-14 09:58:50 +08:00
120 lines
4.5 KiB
C++
120 lines
4.5 KiB
C++
/*
|
|
* MutationTracking.cpp
|
|
*
|
|
* This source file is part of the FoundationDB open source project
|
|
*
|
|
* Copyright 2013-2020 Apple Inc. and the FoundationDB project authors
|
|
*
|
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
* you may not use this file except in compliance with the License.
|
|
* You may obtain a copy of the License at
|
|
*
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
*
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
* See the License for the specific language governing permissions and
|
|
* limitations under the License.
|
|
*/
|
|
|
|
#include <algorithm>
|
|
#include <vector>
|
|
#include "fdbserver/MutationTracking.h"
|
|
#include "fdbserver/LogProtocolMessage.h"
|
|
#include "fdbserver/SpanContextMessage.h"
|
|
|
|
#if defined(FDB_CLEAN_BUILD) && MUTATION_TRACKING_ENABLED
|
|
#error "You cannot use mutation tracking in a clean/release build."
|
|
#endif
|
|
|
|
// Track any of these keys in simulation via enabling MUTATION_TRACKING_ENABLED and setting the keys here.
|
|
std::vector<KeyRef> debugKeys = { ""_sr, "\xff\xff"_sr };
|
|
|
|
TraceEvent debugMutationEnabled(const char* context, Version version, MutationRef const& mutation) {
|
|
if (std::any_of(debugKeys.begin(), debugKeys.end(), [&mutation](const KeyRef& debugKey) {
|
|
return ((mutation.type == mutation.ClearRange || mutation.type == mutation.DebugKeyRange) &&
|
|
mutation.param1 <= debugKey && mutation.param2 > debugKey) ||
|
|
mutation.param1 == debugKey;
|
|
})) {
|
|
|
|
TraceEvent event("MutationTracking");
|
|
event.detail("At", context).detail("Version", version).detail("Mutation", mutation);
|
|
return event;
|
|
}
|
|
return TraceEvent();
|
|
}
|
|
|
|
TraceEvent debugKeyRangeEnabled(const char* context, Version version, KeyRangeRef const& keys) {
|
|
if (std::any_of(
|
|
debugKeys.begin(), debugKeys.end(), [&keys](const KeyRef& debugKey) { return keys.contains(debugKey); })) {
|
|
|
|
TraceEvent event("MutationTracking");
|
|
event.detail("At", context).detail("Version", version).detail("Mutation", MutationRef(MutationRef::DebugKeyRange, keys.begin, keys.end));
|
|
return event;
|
|
}
|
|
return TraceEvent();
|
|
}
|
|
|
|
TraceEvent debugTagsAndMessageEnabled(const char* context, Version version, StringRef commitBlob) {
|
|
BinaryReader rdr(commitBlob, AssumeVersion(g_network->protocolVersion()));
|
|
while (!rdr.empty()) {
|
|
if (*(int32_t*)rdr.peekBytes(4) == VERSION_HEADER) {
|
|
int32_t dummy;
|
|
rdr >> dummy >> version;
|
|
continue;
|
|
}
|
|
TagsAndMessage msg;
|
|
msg.loadFromArena(&rdr, nullptr);
|
|
bool logAdapterMessage = std::any_of(
|
|
msg.tags.begin(), msg.tags.end(), [](const Tag& t) { return t == txsTag || t.locality == tagLocalityTxs; });
|
|
StringRef mutationData = msg.getMessageWithoutTags();
|
|
uint8_t mutationType = *mutationData.begin();
|
|
if (logAdapterMessage) {
|
|
// Skip the message, as there will always be an idential non-logAdapterMessage mutation
|
|
// that we can match against in the same commit.
|
|
} else if (LogProtocolMessage::startsLogProtocolMessage(mutationType)) {
|
|
BinaryReader br(mutationData, AssumeVersion(rdr.protocolVersion()));
|
|
LogProtocolMessage lpm;
|
|
br >> lpm;
|
|
rdr.setProtocolVersion(br.protocolVersion());
|
|
} else if (SpanContextMessage::startsSpanContextMessage(mutationType)) {
|
|
BinaryReader br(mutationData, AssumeVersion(rdr.protocolVersion()));
|
|
SpanContextMessage scm;
|
|
br >> scm;
|
|
} else {
|
|
MutationRef m;
|
|
BinaryReader br(mutationData, AssumeVersion(rdr.protocolVersion()));
|
|
br >> m;
|
|
TraceEvent event = debugMutation(context, version, m);
|
|
if (event.isEnabled()) {
|
|
event.detail("MessageTags", msg.tags);
|
|
return event;
|
|
}
|
|
}
|
|
}
|
|
return TraceEvent();
|
|
}
|
|
|
|
#if MUTATION_TRACKING_ENABLED
|
|
TraceEvent debugMutation(const char* context, Version version, MutationRef const& mutation) {
|
|
return debugMutationEnabled(context, version, mutation);
|
|
}
|
|
TraceEvent debugKeyRange(const char* context, Version version, KeyRangeRef const& keys) {
|
|
return debugKeyRangeEnabled(context, version, keys);
|
|
}
|
|
TraceEvent debugTagsAndMessage(const char* context, Version version, StringRef commitBlob) {
|
|
return debugTagsAndMessageEnabled(context, version, commitBlob);
|
|
}
|
|
#else
|
|
TraceEvent debugMutation(const char* context, Version version, MutationRef const& mutation) {
|
|
return TraceEvent();
|
|
}
|
|
TraceEvent debugKeyRange(const char* context, Version version, KeyRangeRef const& keys) {
|
|
return TraceEvent();
|
|
}
|
|
TraceEvent debugTagsAndMessage(const char* context, Version version, StringRef commitBlob) {
|
|
return TraceEvent();
|
|
}
|
|
#endif
|