Add user stats Reset API
Summary: It resets all the ticker and histogram stats to zero. Needed to change the locking a bit since Reset() is the only operation that manipulates multiple tickers/histograms together, and that operation should be seen as atomic by other operations that access tickers/histograms. Closes https://github.com/facebook/rocksdb/pull/2213 Differential Revision: D4952232 Pulled By: ajkr fbshipit-source-id: c0475c3e4c7b940120d53891b69c3091149a0679
This commit is contained in:
parent
958b4c9117
commit
b1845f43e7
@ -115,6 +115,31 @@ TEST_F(DBStatisticsTest, MutexWaitStats) {
|
|||||||
ThreadStatusUtil::TEST_SetStateDelay(ThreadStatus::STATE_MUTEX_WAIT, 0);
|
ThreadStatusUtil::TEST_SetStateDelay(ThreadStatus::STATE_MUTEX_WAIT, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST_F(DBStatisticsTest, ResetStats) {
|
||||||
|
Options options = CurrentOptions();
|
||||||
|
options.create_if_missing = true;
|
||||||
|
options.statistics = rocksdb::CreateDBStatistics();
|
||||||
|
DestroyAndReopen(options);
|
||||||
|
for (int i = 0; i < 2; ++i) {
|
||||||
|
// pick arbitrary ticker and histogram. On first iteration they're zero
|
||||||
|
// because db is unused. On second iteration they're zero due to Reset().
|
||||||
|
ASSERT_EQ(0, TestGetTickerCount(options, NUMBER_KEYS_WRITTEN));
|
||||||
|
HistogramData histogram_data;
|
||||||
|
options.statistics->histogramData(DB_WRITE, &histogram_data);
|
||||||
|
ASSERT_EQ(0.0, histogram_data.max);
|
||||||
|
|
||||||
|
if (i == 0) {
|
||||||
|
// The Put() makes some of the ticker/histogram stats nonzero until we
|
||||||
|
// Reset().
|
||||||
|
ASSERT_OK(Put("hello", "rocksdb"));
|
||||||
|
ASSERT_EQ(1, TestGetTickerCount(options, NUMBER_KEYS_WRITTEN));
|
||||||
|
options.statistics->histogramData(DB_WRITE, &histogram_data);
|
||||||
|
ASSERT_GT(histogram_data.max, 0.0);
|
||||||
|
options.statistics->Reset();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace rocksdb
|
} // namespace rocksdb
|
||||||
|
|
||||||
int main(int argc, char** argv) {
|
int main(int argc, char** argv) {
|
||||||
|
@ -13,6 +13,8 @@
|
|||||||
#include <memory>
|
#include <memory>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
|
#include "rocksdb/status.h"
|
||||||
|
|
||||||
namespace rocksdb {
|
namespace rocksdb {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -443,6 +445,11 @@ class Statistics {
|
|||||||
virtual uint64_t getAndResetTickerCount(uint32_t tickerType) = 0;
|
virtual uint64_t getAndResetTickerCount(uint32_t tickerType) = 0;
|
||||||
virtual void measureTime(uint32_t histogramType, uint64_t time) = 0;
|
virtual void measureTime(uint32_t histogramType, uint64_t time) = 0;
|
||||||
|
|
||||||
|
// Resets all ticker and histogram stats
|
||||||
|
virtual Status Reset() {
|
||||||
|
return Status::NotSupported("Not implemented");
|
||||||
|
}
|
||||||
|
|
||||||
// String representation of the statistic object.
|
// String representation of the statistic object.
|
||||||
virtual std::string ToString() const {
|
virtual std::string ToString() const {
|
||||||
// Do nothing by default
|
// Do nothing by default
|
||||||
|
@ -33,6 +33,10 @@ StatisticsImpl::~StatisticsImpl() {}
|
|||||||
|
|
||||||
uint64_t StatisticsImpl::getTickerCount(uint32_t tickerType) const {
|
uint64_t StatisticsImpl::getTickerCount(uint32_t tickerType) const {
|
||||||
MutexLock lock(&aggregate_lock_);
|
MutexLock lock(&aggregate_lock_);
|
||||||
|
return getTickerCountLocked(tickerType);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint64_t StatisticsImpl::getTickerCountLocked(uint32_t tickerType) const {
|
||||||
assert(
|
assert(
|
||||||
enable_internal_stats_ ?
|
enable_internal_stats_ ?
|
||||||
tickerType < INTERNAL_TICKER_ENUM_MAX :
|
tickerType < INTERNAL_TICKER_ENUM_MAX :
|
||||||
@ -68,6 +72,12 @@ StatisticsImpl::HistogramInfo::getMergedHistogram() const {
|
|||||||
|
|
||||||
void StatisticsImpl::histogramData(uint32_t histogramType,
|
void StatisticsImpl::histogramData(uint32_t histogramType,
|
||||||
HistogramData* const data) const {
|
HistogramData* const data) const {
|
||||||
|
MutexLock lock(&aggregate_lock_);
|
||||||
|
histogramDataLocked(histogramType, data);
|
||||||
|
}
|
||||||
|
|
||||||
|
void StatisticsImpl::histogramDataLocked(uint32_t histogramType,
|
||||||
|
HistogramData* const data) const {
|
||||||
assert(
|
assert(
|
||||||
enable_internal_stats_ ?
|
enable_internal_stats_ ?
|
||||||
histogramType < INTERNAL_HISTOGRAM_ENUM_MAX :
|
histogramType < INTERNAL_HISTOGRAM_ENUM_MAX :
|
||||||
@ -76,6 +86,7 @@ void StatisticsImpl::histogramData(uint32_t histogramType,
|
|||||||
}
|
}
|
||||||
|
|
||||||
std::string StatisticsImpl::getHistogramString(uint32_t histogramType) const {
|
std::string StatisticsImpl::getHistogramString(uint32_t histogramType) const {
|
||||||
|
MutexLock lock(&aggregate_lock_);
|
||||||
assert(enable_internal_stats_ ? histogramType < INTERNAL_HISTOGRAM_ENUM_MAX
|
assert(enable_internal_stats_ ? histogramType < INTERNAL_HISTOGRAM_ENUM_MAX
|
||||||
: histogramType < HISTOGRAM_ENUM_MAX);
|
: histogramType < HISTOGRAM_ENUM_MAX);
|
||||||
return histograms_[histogramType].getMergedHistogram()->ToString();
|
return histograms_[histogramType].getMergedHistogram()->ToString();
|
||||||
@ -108,6 +119,14 @@ StatisticsImpl::ThreadHistogramInfo* StatisticsImpl::getThreadHistogramInfo(
|
|||||||
void StatisticsImpl::setTickerCount(uint32_t tickerType, uint64_t count) {
|
void StatisticsImpl::setTickerCount(uint32_t tickerType, uint64_t count) {
|
||||||
{
|
{
|
||||||
MutexLock lock(&aggregate_lock_);
|
MutexLock lock(&aggregate_lock_);
|
||||||
|
setTickerCountLocked(tickerType, count);
|
||||||
|
}
|
||||||
|
if (stats_ && tickerType < TICKER_ENUM_MAX) {
|
||||||
|
stats_->setTickerCount(tickerType, count);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void StatisticsImpl::setTickerCountLocked(uint32_t tickerType, uint64_t count) {
|
||||||
assert(enable_internal_stats_ ? tickerType < INTERNAL_TICKER_ENUM_MAX
|
assert(enable_internal_stats_ ? tickerType < INTERNAL_TICKER_ENUM_MAX
|
||||||
: tickerType < TICKER_ENUM_MAX);
|
: tickerType < TICKER_ENUM_MAX);
|
||||||
if (tickerType < TICKER_ENUM_MAX || enable_internal_stats_) {
|
if (tickerType < TICKER_ENUM_MAX || enable_internal_stats_) {
|
||||||
@ -119,10 +138,6 @@ void StatisticsImpl::setTickerCount(uint32_t tickerType, uint64_t count) {
|
|||||||
nullptr /* res */);
|
nullptr /* res */);
|
||||||
tickers_[tickerType].merged_sum.store(count, std::memory_order_relaxed);
|
tickers_[tickerType].merged_sum.store(count, std::memory_order_relaxed);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
if (stats_ && tickerType < TICKER_ENUM_MAX) {
|
|
||||||
stats_->setTickerCount(tickerType, count);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
uint64_t StatisticsImpl::getAndResetTickerCount(uint32_t tickerType) {
|
uint64_t StatisticsImpl::getAndResetTickerCount(uint32_t tickerType) {
|
||||||
@ -176,6 +191,21 @@ void StatisticsImpl::measureTime(uint32_t histogramType, uint64_t value) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Status StatisticsImpl::Reset() {
|
||||||
|
MutexLock lock(&aggregate_lock_);
|
||||||
|
for (uint32_t i = 0; i < TICKER_ENUM_MAX; ++i) {
|
||||||
|
setTickerCountLocked(i, 0);
|
||||||
|
}
|
||||||
|
for (uint32_t i = 0; i < HISTOGRAM_ENUM_MAX; ++i) {
|
||||||
|
histograms_[i].thread_value->Fold(
|
||||||
|
[](void* curr_ptr, void* res) {
|
||||||
|
static_cast<HistogramImpl*>(curr_ptr)->Clear();
|
||||||
|
},
|
||||||
|
nullptr /* res */);
|
||||||
|
}
|
||||||
|
return Status::OK();
|
||||||
|
}
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
// a buffer size used for temp string buffers
|
// a buffer size used for temp string buffers
|
||||||
@ -184,13 +214,14 @@ const int kTmpStrBufferSize = 200;
|
|||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
std::string StatisticsImpl::ToString() const {
|
std::string StatisticsImpl::ToString() const {
|
||||||
|
MutexLock lock(&aggregate_lock_);
|
||||||
std::string res;
|
std::string res;
|
||||||
res.reserve(20000);
|
res.reserve(20000);
|
||||||
for (const auto& t : TickersNameMap) {
|
for (const auto& t : TickersNameMap) {
|
||||||
if (t.first < TICKER_ENUM_MAX || enable_internal_stats_) {
|
if (t.first < TICKER_ENUM_MAX || enable_internal_stats_) {
|
||||||
char buffer[kTmpStrBufferSize];
|
char buffer[kTmpStrBufferSize];
|
||||||
snprintf(buffer, kTmpStrBufferSize, "%s COUNT : %" PRIu64 "\n",
|
snprintf(buffer, kTmpStrBufferSize, "%s COUNT : %" PRIu64 "\n",
|
||||||
t.second.c_str(), getTickerCount(t.first));
|
t.second.c_str(), getTickerCountLocked(t.first));
|
||||||
res.append(buffer);
|
res.append(buffer);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -198,7 +229,7 @@ std::string StatisticsImpl::ToString() const {
|
|||||||
if (h.first < HISTOGRAM_ENUM_MAX || enable_internal_stats_) {
|
if (h.first < HISTOGRAM_ENUM_MAX || enable_internal_stats_) {
|
||||||
char buffer[kTmpStrBufferSize];
|
char buffer[kTmpStrBufferSize];
|
||||||
HistogramData hData;
|
HistogramData hData;
|
||||||
histogramData(h.first, &hData);
|
histogramDataLocked(h.first, &hData);
|
||||||
snprintf(
|
snprintf(
|
||||||
buffer, kTmpStrBufferSize,
|
buffer, kTmpStrBufferSize,
|
||||||
"%s statistics Percentiles :=> 50 : %f 95 : %f 99 : %f 100 : %f\n",
|
"%s statistics Percentiles :=> 50 : %f 95 : %f 99 : %f 100 : %f\n",
|
||||||
|
@ -45,6 +45,7 @@ class StatisticsImpl : public Statistics {
|
|||||||
virtual void recordTick(uint32_t ticker_type, uint64_t count) override;
|
virtual void recordTick(uint32_t ticker_type, uint64_t count) override;
|
||||||
virtual void measureTime(uint32_t histogram_type, uint64_t value) override;
|
virtual void measureTime(uint32_t histogram_type, uint64_t value) override;
|
||||||
|
|
||||||
|
virtual Status Reset() override;
|
||||||
virtual std::string ToString() const override;
|
virtual std::string ToString() const override;
|
||||||
virtual bool HistEnabledForType(uint32_t type) const override;
|
virtual bool HistEnabledForType(uint32_t type) const override;
|
||||||
|
|
||||||
@ -52,8 +53,8 @@ class StatisticsImpl : public Statistics {
|
|||||||
std::shared_ptr<Statistics> stats_shared_;
|
std::shared_ptr<Statistics> stats_shared_;
|
||||||
Statistics* stats_;
|
Statistics* stats_;
|
||||||
bool enable_internal_stats_;
|
bool enable_internal_stats_;
|
||||||
// Synchronizes setTickerCount()/getTickerCount() operations so partially
|
// Synchronizes anything that operates on other threads' thread-specific data
|
||||||
// completed setTickerCount() won't be visible.
|
// such that operations like Reset() can be performed atomically.
|
||||||
mutable port::Mutex aggregate_lock_;
|
mutable port::Mutex aggregate_lock_;
|
||||||
|
|
||||||
// Holds data maintained by each thread for implementing tickers.
|
// Holds data maintained by each thread for implementing tickers.
|
||||||
@ -126,6 +127,11 @@ class StatisticsImpl : public Statistics {
|
|||||||
std::unique_ptr<HistogramImpl> getMergedHistogram() const;
|
std::unique_ptr<HistogramImpl> getMergedHistogram() const;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
uint64_t getTickerCountLocked(uint32_t ticker_type) const;
|
||||||
|
void histogramDataLocked(uint32_t histogram_type,
|
||||||
|
HistogramData* const data) const;
|
||||||
|
void setTickerCountLocked(uint32_t ticker_type, uint64_t count);
|
||||||
|
|
||||||
// Returns the info for this tickerType/thread. It sets a new info with zeroed
|
// Returns the info for this tickerType/thread. It sets a new info with zeroed
|
||||||
// counter if none exists.
|
// counter if none exists.
|
||||||
ThreadTickerInfo* getThreadTickerInfo(uint32_t ticker_type);
|
ThreadTickerInfo* getThreadTickerInfo(uint32_t ticker_type);
|
||||||
|
Loading…
Reference in New Issue
Block a user