Skip to content

Commit

Permalink
Add user stats Reset API
Browse files Browse the repository at this point in the history
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 facebook#2213

Differential Revision: D4952232

Pulled By: ajkr

fbshipit-source-id: c0475c3e4c7b940120d53891b69c3091149a0679
  • Loading branch information
ajkr authored and facebook-github-bot committed Apr 26, 2017
1 parent 6616e4d commit efc361e
Show file tree
Hide file tree
Showing 5 changed files with 85 additions and 15 deletions.
1 change: 1 addition & 0 deletions HISTORY.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
## Unreleased
### New Features
* DB::ResetStats() to reset internal stats.
* Statistics::Reset() to reset user stats.
* ldb add option --try_load_options, which will open DB with its own option file.

## 5.4.0 (04/11/2017)
Expand Down
25 changes: 25 additions & 0 deletions db/db_statistics_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,31 @@ TEST_F(DBStatisticsTest, MutexWaitStats) {
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

int main(int argc, char** argv) {
Expand Down
7 changes: 7 additions & 0 deletions include/rocksdb/statistics.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@
#include <memory>
#include <vector>

#include "rocksdb/status.h"

namespace rocksdb {

/**
Expand Down Expand Up @@ -443,6 +445,11 @@ class Statistics {
virtual uint64_t getAndResetTickerCount(uint32_t tickerType) = 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.
virtual std::string ToString() const {
// Do nothing by default
Expand Down
57 changes: 44 additions & 13 deletions monitoring/statistics.cc
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,10 @@ StatisticsImpl::~StatisticsImpl() {}

uint64_t StatisticsImpl::getTickerCount(uint32_t tickerType) const {
MutexLock lock(&aggregate_lock_);
return getTickerCountLocked(tickerType);
}

uint64_t StatisticsImpl::getTickerCountLocked(uint32_t tickerType) const {
assert(
enable_internal_stats_ ?
tickerType < INTERNAL_TICKER_ENUM_MAX :
Expand Down Expand Up @@ -68,6 +72,12 @@ StatisticsImpl::HistogramInfo::getMergedHistogram() const {

void StatisticsImpl::histogramData(uint32_t histogramType,
HistogramData* const data) const {
MutexLock lock(&aggregate_lock_);
histogramDataLocked(histogramType, data);
}

void StatisticsImpl::histogramDataLocked(uint32_t histogramType,
HistogramData* const data) const {
assert(
enable_internal_stats_ ?
histogramType < INTERNAL_HISTOGRAM_ENUM_MAX :
Expand All @@ -76,6 +86,7 @@ void StatisticsImpl::histogramData(uint32_t histogramType,
}

std::string StatisticsImpl::getHistogramString(uint32_t histogramType) const {
MutexLock lock(&aggregate_lock_);
assert(enable_internal_stats_ ? histogramType < INTERNAL_HISTOGRAM_ENUM_MAX
: histogramType < HISTOGRAM_ENUM_MAX);
return histograms_[histogramType].getMergedHistogram()->ToString();
Expand Down Expand Up @@ -108,23 +119,27 @@ StatisticsImpl::ThreadHistogramInfo* StatisticsImpl::getThreadHistogramInfo(
void StatisticsImpl::setTickerCount(uint32_t tickerType, uint64_t count) {
{
MutexLock lock(&aggregate_lock_);
assert(enable_internal_stats_ ? tickerType < INTERNAL_TICKER_ENUM_MAX
: tickerType < TICKER_ENUM_MAX);
if (tickerType < TICKER_ENUM_MAX || enable_internal_stats_) {
tickers_[tickerType].thread_value->Fold(
[](void* curr_ptr, void* res) {
static_cast<std::atomic<uint64_t>*>(curr_ptr)->store(
0, std::memory_order_relaxed);
},
nullptr /* res */);
tickers_[tickerType].merged_sum.store(count, std::memory_order_relaxed);
}
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
: tickerType < TICKER_ENUM_MAX);
if (tickerType < TICKER_ENUM_MAX || enable_internal_stats_) {
tickers_[tickerType].thread_value->Fold(
[](void* curr_ptr, void* res) {
static_cast<std::atomic<uint64_t>*>(curr_ptr)->store(
0, std::memory_order_relaxed);
},
nullptr /* res */);
tickers_[tickerType].merged_sum.store(count, std::memory_order_relaxed);
}
}

uint64_t StatisticsImpl::getAndResetTickerCount(uint32_t tickerType) {
uint64_t sum = 0;
{
Expand Down Expand Up @@ -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 {

// a buffer size used for temp string buffers
Expand All @@ -184,21 +214,22 @@ const int kTmpStrBufferSize = 200;
} // namespace

std::string StatisticsImpl::ToString() const {
MutexLock lock(&aggregate_lock_);
std::string res;
res.reserve(20000);
for (const auto& t : TickersNameMap) {
if (t.first < TICKER_ENUM_MAX || enable_internal_stats_) {
char buffer[kTmpStrBufferSize];
snprintf(buffer, kTmpStrBufferSize, "%s COUNT : %" PRIu64 "\n",
t.second.c_str(), getTickerCount(t.first));
t.second.c_str(), getTickerCountLocked(t.first));
res.append(buffer);
}
}
for (const auto& h : HistogramsNameMap) {
if (h.first < HISTOGRAM_ENUM_MAX || enable_internal_stats_) {
char buffer[kTmpStrBufferSize];
HistogramData hData;
histogramData(h.first, &hData);
histogramDataLocked(h.first, &hData);
snprintf(
buffer, kTmpStrBufferSize,
"%s statistics Percentiles :=> 50 : %f 95 : %f 99 : %f 100 : %f\n",
Expand Down
10 changes: 8 additions & 2 deletions monitoring/statistics.h
Original file line number Diff line number Diff line change
Expand Up @@ -45,15 +45,16 @@ class StatisticsImpl : public Statistics {
virtual void recordTick(uint32_t ticker_type, uint64_t count) override;
virtual void measureTime(uint32_t histogram_type, uint64_t value) override;

virtual Status Reset() override;
virtual std::string ToString() const override;
virtual bool HistEnabledForType(uint32_t type) const override;

private:
std::shared_ptr<Statistics> stats_shared_;
Statistics* stats_;
bool enable_internal_stats_;
// Synchronizes setTickerCount()/getTickerCount() operations so partially
// completed setTickerCount() won't be visible.
// Synchronizes anything that operates on other threads' thread-specific data
// such that operations like Reset() can be performed atomically.
mutable port::Mutex aggregate_lock_;

// Holds data maintained by each thread for implementing tickers.
Expand Down Expand Up @@ -126,6 +127,11 @@ class StatisticsImpl : public Statistics {
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
// counter if none exists.
ThreadTickerInfo* getThreadTickerInfo(uint32_t ticker_type);
Expand Down

0 comments on commit efc361e

Please sign in to comment.