Histogram of number of merge operands
Summary: Add a histogram in statistics to help users understand how many merge operands they merge. Closes https://github.com/facebook/rocksdb/pull/2373 Differential Revision: D5139983 Pulled By: siying fbshipit-source-id: 61b9ba8ca83f358530a4833d68f0103b56a0e182
This commit is contained in:
parent
345878a7fb
commit
51ac91f586
@ -562,7 +562,7 @@ void DBIter::MergeValuesNewToOld() {
|
|||||||
const Slice val = iter_->value();
|
const Slice val = iter_->value();
|
||||||
s = MergeHelper::TimedFullMerge(
|
s = MergeHelper::TimedFullMerge(
|
||||||
merge_operator_, ikey.user_key, &val, merge_context_.GetOperands(),
|
merge_operator_, ikey.user_key, &val, merge_context_.GetOperands(),
|
||||||
&saved_value_, logger_, statistics_, env_, &pinned_value_);
|
&saved_value_, logger_, statistics_, env_, &pinned_value_, true);
|
||||||
if (!s.ok()) {
|
if (!s.ok()) {
|
||||||
status_ = s;
|
status_ = s;
|
||||||
}
|
}
|
||||||
@ -587,7 +587,7 @@ void DBIter::MergeValuesNewToOld() {
|
|||||||
s = MergeHelper::TimedFullMerge(merge_operator_, saved_key_.GetUserKey(),
|
s = MergeHelper::TimedFullMerge(merge_operator_, saved_key_.GetUserKey(),
|
||||||
nullptr, merge_context_.GetOperands(),
|
nullptr, merge_context_.GetOperands(),
|
||||||
&saved_value_, logger_, statistics_, env_,
|
&saved_value_, logger_, statistics_, env_,
|
||||||
&pinned_value_);
|
&pinned_value_, true);
|
||||||
if (!s.ok()) {
|
if (!s.ok()) {
|
||||||
status_ = s;
|
status_ = s;
|
||||||
}
|
}
|
||||||
@ -806,13 +806,13 @@ bool DBIter::FindValueForCurrentKey() {
|
|||||||
s = MergeHelper::TimedFullMerge(
|
s = MergeHelper::TimedFullMerge(
|
||||||
merge_operator_, saved_key_.GetUserKey(), nullptr,
|
merge_operator_, saved_key_.GetUserKey(), nullptr,
|
||||||
merge_context_.GetOperands(), &saved_value_, logger_, statistics_,
|
merge_context_.GetOperands(), &saved_value_, logger_, statistics_,
|
||||||
env_, &pinned_value_);
|
env_, &pinned_value_, true);
|
||||||
} else {
|
} else {
|
||||||
assert(last_not_merge_type == kTypeValue);
|
assert(last_not_merge_type == kTypeValue);
|
||||||
s = MergeHelper::TimedFullMerge(
|
s = MergeHelper::TimedFullMerge(
|
||||||
merge_operator_, saved_key_.GetUserKey(), &pinned_value_,
|
merge_operator_, saved_key_.GetUserKey(), &pinned_value_,
|
||||||
merge_context_.GetOperands(), &saved_value_, logger_, statistics_,
|
merge_context_.GetOperands(), &saved_value_, logger_, statistics_,
|
||||||
env_, &pinned_value_);
|
env_, &pinned_value_, true);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case kTypeValue:
|
case kTypeValue:
|
||||||
@ -884,7 +884,7 @@ bool DBIter::FindValueForCurrentKeyUsingSeek() {
|
|||||||
s = MergeHelper::TimedFullMerge(merge_operator_, saved_key_.GetUserKey(),
|
s = MergeHelper::TimedFullMerge(merge_operator_, saved_key_.GetUserKey(),
|
||||||
nullptr, merge_context_.GetOperands(),
|
nullptr, merge_context_.GetOperands(),
|
||||||
&saved_value_, logger_, statistics_, env_,
|
&saved_value_, logger_, statistics_, env_,
|
||||||
&pinned_value_);
|
&pinned_value_, true);
|
||||||
// Make iter_ valid and point to saved_key_
|
// Make iter_ valid and point to saved_key_
|
||||||
if (!iter_->Valid() ||
|
if (!iter_->Valid() ||
|
||||||
!user_comparator_->Equal(ikey.user_key, saved_key_.GetUserKey())) {
|
!user_comparator_->Equal(ikey.user_key, saved_key_.GetUserKey())) {
|
||||||
@ -902,7 +902,7 @@ bool DBIter::FindValueForCurrentKeyUsingSeek() {
|
|||||||
s = MergeHelper::TimedFullMerge(merge_operator_, saved_key_.GetUserKey(),
|
s = MergeHelper::TimedFullMerge(merge_operator_, saved_key_.GetUserKey(),
|
||||||
&val, merge_context_.GetOperands(),
|
&val, merge_context_.GetOperands(),
|
||||||
&saved_value_, logger_, statistics_, env_,
|
&saved_value_, logger_, statistics_, env_,
|
||||||
&pinned_value_);
|
&pinned_value_, true);
|
||||||
valid_ = true;
|
valid_ = true;
|
||||||
if (!s.ok()) {
|
if (!s.ok()) {
|
||||||
status_ = s;
|
status_ = s;
|
||||||
|
@ -578,7 +578,7 @@ static bool SaveValue(void* arg, const char* entry) {
|
|||||||
*(s->status) = MergeHelper::TimedFullMerge(
|
*(s->status) = MergeHelper::TimedFullMerge(
|
||||||
merge_operator, s->key->user_key(), &v,
|
merge_operator, s->key->user_key(), &v,
|
||||||
merge_context->GetOperands(), s->value, s->logger, s->statistics,
|
merge_context->GetOperands(), s->value, s->logger, s->statistics,
|
||||||
s->env_);
|
s->env_, nullptr /* result_operand */, true);
|
||||||
} else if (s->value != nullptr) {
|
} else if (s->value != nullptr) {
|
||||||
s->value->assign(v.data(), v.size());
|
s->value->assign(v.data(), v.size());
|
||||||
}
|
}
|
||||||
@ -595,7 +595,7 @@ static bool SaveValue(void* arg, const char* entry) {
|
|||||||
*(s->status) = MergeHelper::TimedFullMerge(
|
*(s->status) = MergeHelper::TimedFullMerge(
|
||||||
merge_operator, s->key->user_key(), nullptr,
|
merge_operator, s->key->user_key(), nullptr,
|
||||||
merge_context->GetOperands(), s->value, s->logger, s->statistics,
|
merge_context->GetOperands(), s->value, s->logger, s->statistics,
|
||||||
s->env_);
|
s->env_, nullptr /* result_operand */, true);
|
||||||
} else {
|
} else {
|
||||||
*(s->status) = Status::NotFound();
|
*(s->status) = Status::NotFound();
|
||||||
}
|
}
|
||||||
|
@ -25,7 +25,8 @@ Status MergeHelper::TimedFullMerge(const MergeOperator* merge_operator,
|
|||||||
const std::vector<Slice>& operands,
|
const std::vector<Slice>& operands,
|
||||||
std::string* result, Logger* logger,
|
std::string* result, Logger* logger,
|
||||||
Statistics* statistics, Env* env,
|
Statistics* statistics, Env* env,
|
||||||
Slice* result_operand) {
|
Slice* result_operand,
|
||||||
|
bool update_num_ops_stats) {
|
||||||
assert(merge_operator != nullptr);
|
assert(merge_operator != nullptr);
|
||||||
|
|
||||||
if (operands.size() == 0) {
|
if (operands.size() == 0) {
|
||||||
@ -34,6 +35,11 @@ Status MergeHelper::TimedFullMerge(const MergeOperator* merge_operator,
|
|||||||
return Status::OK();
|
return Status::OK();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (update_num_ops_stats) {
|
||||||
|
MeasureTime(statistics, READ_NUM_MERGE_OPERANDS,
|
||||||
|
static_cast<uint64_t>(operands.size()));
|
||||||
|
}
|
||||||
|
|
||||||
bool success;
|
bool success;
|
||||||
Slice tmp_result_operand(nullptr, 0);
|
Slice tmp_result_operand(nullptr, 0);
|
||||||
const MergeOperator::MergeOperationInput merge_in(key, value, operands,
|
const MergeOperator::MergeOperationInput merge_in(key, value, operands,
|
||||||
|
@ -56,6 +56,8 @@ class MergeHelper {
|
|||||||
// Wrapper around MergeOperator::FullMergeV2() that records perf statistics.
|
// Wrapper around MergeOperator::FullMergeV2() that records perf statistics.
|
||||||
// Result of merge will be written to result if status returned is OK.
|
// Result of merge will be written to result if status returned is OK.
|
||||||
// If operands is empty, the value will simply be copied to result.
|
// If operands is empty, the value will simply be copied to result.
|
||||||
|
// Set `update_num_ops_stats` to true if it is from a user read, so that
|
||||||
|
// the latency is sensitive.
|
||||||
// Returns one of the following statuses:
|
// Returns one of the following statuses:
|
||||||
// - OK: Entries were successfully merged.
|
// - OK: Entries were successfully merged.
|
||||||
// - Corruption: Merge operator reported unsuccessful merge.
|
// - Corruption: Merge operator reported unsuccessful merge.
|
||||||
@ -64,7 +66,8 @@ class MergeHelper {
|
|||||||
const std::vector<Slice>& operands,
|
const std::vector<Slice>& operands,
|
||||||
std::string* result, Logger* logger,
|
std::string* result, Logger* logger,
|
||||||
Statistics* statistics, Env* env,
|
Statistics* statistics, Env* env,
|
||||||
Slice* result_operand = nullptr);
|
Slice* result_operand = nullptr,
|
||||||
|
bool update_num_ops_stats = false);
|
||||||
|
|
||||||
// Merge entries until we hit
|
// Merge entries until we hit
|
||||||
// - a corrupted key
|
// - a corrupted key
|
||||||
|
@ -1016,7 +1016,8 @@ void Version::Get(const ReadOptions& read_options, const LookupKey& k,
|
|||||||
std::string* str_value = value != nullptr ? value->GetSelf() : nullptr;
|
std::string* str_value = value != nullptr ? value->GetSelf() : nullptr;
|
||||||
*status = MergeHelper::TimedFullMerge(
|
*status = MergeHelper::TimedFullMerge(
|
||||||
merge_operator_, user_key, nullptr, merge_context->GetOperands(),
|
merge_operator_, user_key, nullptr, merge_context->GetOperands(),
|
||||||
str_value, info_log_, db_statistics_, env_);
|
str_value, info_log_, db_statistics_, env_,
|
||||||
|
nullptr /* result_operand */, true);
|
||||||
if (LIKELY(value != nullptr)) {
|
if (LIKELY(value != nullptr)) {
|
||||||
value->PinSelf();
|
value->PinSelf();
|
||||||
}
|
}
|
||||||
|
@ -370,6 +370,9 @@ enum Histograms : uint32_t {
|
|||||||
BYTES_DECOMPRESSED,
|
BYTES_DECOMPRESSED,
|
||||||
COMPRESSION_TIMES_NANOS,
|
COMPRESSION_TIMES_NANOS,
|
||||||
DECOMPRESSION_TIMES_NANOS,
|
DECOMPRESSION_TIMES_NANOS,
|
||||||
|
// Number of merge operands passed to the merge operator in user read
|
||||||
|
// requests.
|
||||||
|
READ_NUM_MERGE_OPERANDS,
|
||||||
|
|
||||||
HISTOGRAM_ENUM_MAX, // TODO(ldemailly): enforce HistogramsNameMap match
|
HISTOGRAM_ENUM_MAX, // TODO(ldemailly): enforce HistogramsNameMap match
|
||||||
};
|
};
|
||||||
@ -405,6 +408,7 @@ const std::vector<std::pair<Histograms, std::string>> HistogramsNameMap = {
|
|||||||
{BYTES_DECOMPRESSED, "rocksdb.bytes.decompressed"},
|
{BYTES_DECOMPRESSED, "rocksdb.bytes.decompressed"},
|
||||||
{COMPRESSION_TIMES_NANOS, "rocksdb.compression.times.nanos"},
|
{COMPRESSION_TIMES_NANOS, "rocksdb.compression.times.nanos"},
|
||||||
{DECOMPRESSION_TIMES_NANOS, "rocksdb.decompression.times.nanos"},
|
{DECOMPRESSION_TIMES_NANOS, "rocksdb.decompression.times.nanos"},
|
||||||
|
{READ_NUM_MERGE_OPERANDS, "rocksdb.read.num.merge_operands"},
|
||||||
};
|
};
|
||||||
|
|
||||||
struct HistogramData {
|
struct HistogramData {
|
||||||
|
Loading…
Reference in New Issue
Block a user