mirror of
https://github.com/matrix-construct/construct
synced 2025-01-14 00:34:18 +01:00
ircd::db: Add per-cache statistics.
This commit is contained in:
parent
5e843d0494
commit
e542ef76fb
4 changed files with 168 additions and 37 deletions
|
@ -21,11 +21,9 @@
|
||||||
|
|
||||||
namespace ircd::db
|
namespace ircd::db
|
||||||
{
|
{
|
||||||
struct cache_stats;
|
// Get our stats; refer to db/stats.h for ticker ID related.
|
||||||
|
const uint64_t &ticker(const rocksdb::Cache &, const uint32_t &ticker_id);
|
||||||
// Get our stats
|
uint64_t ticker(const rocksdb::Cache *const &, const uint32_t &ticker_id);
|
||||||
const cache_stats &stats(const rocksdb::Cache &);
|
|
||||||
cache_stats stats(const rocksdb::Cache *const &);
|
|
||||||
|
|
||||||
// Get capacity
|
// Get capacity
|
||||||
size_t capacity(const rocksdb::Cache &);
|
size_t capacity(const rocksdb::Cache &);
|
||||||
|
@ -68,13 +66,3 @@ namespace ircd::db
|
||||||
void clear(rocksdb::Cache &);
|
void clear(rocksdb::Cache &);
|
||||||
void clear(rocksdb::Cache *const &);
|
void clear(rocksdb::Cache *const &);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Our custom cache statistics. Though the rocksdb::Statistics ticker could
|
|
||||||
/// be instantiated for each cache we have our own counters, and we let the
|
|
||||||
/// rocksdb cache impl update our database ticker instead for aggregate stats.
|
|
||||||
struct ircd::db::cache_stats
|
|
||||||
{
|
|
||||||
size_t inserts {0};
|
|
||||||
size_t misses {0};
|
|
||||||
size_t hits {0};
|
|
||||||
};
|
|
||||||
|
|
|
@ -34,8 +34,8 @@ final
|
||||||
static const bool DEFAULT_STRICT;
|
static const bool DEFAULT_STRICT;
|
||||||
|
|
||||||
database *d;
|
database *d;
|
||||||
cache_stats stats;
|
|
||||||
std::shared_ptr<rocksdb::Cache> c;
|
std::shared_ptr<rocksdb::Cache> c;
|
||||||
|
struct database::stats stats;
|
||||||
|
|
||||||
const char *Name() const noexcept override;
|
const char *Name() const noexcept override;
|
||||||
Status Insert(const Slice &key, void *value, size_t charge, deleter, Handle **, Priority) noexcept override;
|
Status Insert(const Slice &key, void *value, size_t charge, deleter, Handle **, Priority) noexcept override;
|
||||||
|
|
|
@ -15,11 +15,13 @@
|
||||||
// RocksDB symbols which we cannot forward declare. It is used internally
|
// RocksDB symbols which we cannot forward declare. It is used internally
|
||||||
// and does not need to be included by general users of IRCd.
|
// and does not need to be included by general users of IRCd.
|
||||||
|
|
||||||
struct ircd::db::database::stats final
|
struct ircd::db::database::stats
|
||||||
:std::enable_shared_from_this<struct ircd::db::database::stats>
|
final
|
||||||
,rocksdb::Statistics
|
:rocksdb::Statistics
|
||||||
{
|
{
|
||||||
database *d;
|
struct passthru;
|
||||||
|
|
||||||
|
database *d {nullptr};
|
||||||
std::array<uint64_t, rocksdb::TICKER_ENUM_MAX> ticker {{0}};
|
std::array<uint64_t, rocksdb::TICKER_ENUM_MAX> ticker {{0}};
|
||||||
std::array<struct db::histogram, rocksdb::HISTOGRAM_ENUM_MAX> histogram;
|
std::array<struct db::histogram, rocksdb::HISTOGRAM_ENUM_MAX> histogram;
|
||||||
|
|
||||||
|
@ -32,5 +34,25 @@ struct ircd::db::database::stats final
|
||||||
uint64_t getAndResetTickerCount(const uint32_t tickerType) noexcept override;
|
uint64_t getAndResetTickerCount(const uint32_t tickerType) noexcept override;
|
||||||
rocksdb::Status Reset() noexcept override;
|
rocksdb::Status Reset() noexcept override;
|
||||||
|
|
||||||
stats(database *const &d);
|
stats(database *const &d = nullptr);
|
||||||
|
~stats() noexcept;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct ircd::db::database::stats::passthru
|
||||||
|
final
|
||||||
|
:rocksdb::Statistics
|
||||||
|
{
|
||||||
|
std::array<rocksdb::Statistics *, 2> pass {{nullptr}};
|
||||||
|
|
||||||
|
void recordTick(const uint32_t tickerType, const uint64_t count) noexcept override;
|
||||||
|
void measureTime(const uint32_t histogramType, const uint64_t time) noexcept override;
|
||||||
|
bool HistEnabledForType(const uint32_t type) const noexcept override;
|
||||||
|
uint64_t getTickerCount(const uint32_t tickerType) const noexcept override;
|
||||||
|
void setTickerCount(const uint32_t tickerType, const uint64_t count) noexcept override;
|
||||||
|
void histogramData(const uint32_t type, rocksdb::HistogramData *) const noexcept override;
|
||||||
|
uint64_t getAndResetTickerCount(const uint32_t tickerType) noexcept override;
|
||||||
|
rocksdb::Status Reset() noexcept override;
|
||||||
|
|
||||||
|
passthru(rocksdb::Statistics *const &a, rocksdb::Statistics *const &b);
|
||||||
|
~passthru() noexcept;
|
||||||
};
|
};
|
||||||
|
|
153
ircd/db.cc
153
ircd/db.cc
|
@ -1906,11 +1906,20 @@ ircd::db::histogram_max
|
||||||
// database::stats (db/database/stats.h) internal
|
// database::stats (db/database/stats.h) internal
|
||||||
//
|
//
|
||||||
|
|
||||||
|
//
|
||||||
|
// stats::stats
|
||||||
|
//
|
||||||
|
|
||||||
ircd::db::database::stats::stats(database *const &d)
|
ircd::db::database::stats::stats(database *const &d)
|
||||||
:d{d}
|
:d{d}
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ircd::db::database::stats::~stats()
|
||||||
|
noexcept
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
rocksdb::Status
|
rocksdb::Status
|
||||||
ircd::db::database::stats::Reset()
|
ircd::db::database::stats::Reset()
|
||||||
noexcept
|
noexcept
|
||||||
|
@ -1992,6 +2001,95 @@ const noexcept
|
||||||
return ticker.at(type);
|
return ticker.at(type);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// database::stats::passthru
|
||||||
|
//
|
||||||
|
|
||||||
|
ircd::db::database::stats::passthru::passthru(rocksdb::Statistics *const &a,
|
||||||
|
rocksdb::Statistics *const &b)
|
||||||
|
:pass
|
||||||
|
{
|
||||||
|
{ a, b }
|
||||||
|
}
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
ircd::db::database::stats::passthru::~passthru()
|
||||||
|
noexcept
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
[[noreturn]]
|
||||||
|
rocksdb::Status
|
||||||
|
ircd::db::database::stats::passthru::Reset()
|
||||||
|
noexcept
|
||||||
|
{
|
||||||
|
throw assertive {"Unavailable for passthru"};
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
ircd::db::database::stats::passthru::recordTick(const uint32_t tickerType,
|
||||||
|
const uint64_t count)
|
||||||
|
noexcept
|
||||||
|
{
|
||||||
|
for(auto *const &pass : this->pass)
|
||||||
|
pass->recordTick(tickerType, count);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
ircd::db::database::stats::passthru::measureTime(const uint32_t histogramType,
|
||||||
|
const uint64_t time)
|
||||||
|
noexcept
|
||||||
|
{
|
||||||
|
for(auto *const &pass : this->pass)
|
||||||
|
pass->measureTime(histogramType, time);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
ircd::db::database::stats::passthru::HistEnabledForType(const uint32_t type)
|
||||||
|
const noexcept
|
||||||
|
{
|
||||||
|
return std::all_of(begin(pass), end(pass), [&type]
|
||||||
|
(const auto *const &pass)
|
||||||
|
{
|
||||||
|
return pass->HistEnabledForType(type);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
[[noreturn]]
|
||||||
|
uint64_t
|
||||||
|
ircd::db::database::stats::passthru::getTickerCount(const uint32_t tickerType)
|
||||||
|
const noexcept
|
||||||
|
{
|
||||||
|
throw assertive {"Unavailable for passthru"};
|
||||||
|
}
|
||||||
|
|
||||||
|
[[noreturn]]
|
||||||
|
void
|
||||||
|
ircd::db::database::stats::passthru::setTickerCount(const uint32_t tickerType,
|
||||||
|
const uint64_t count)
|
||||||
|
noexcept
|
||||||
|
{
|
||||||
|
throw assertive {"Unavailable for passthru"};
|
||||||
|
}
|
||||||
|
|
||||||
|
[[noreturn]]
|
||||||
|
void
|
||||||
|
ircd::db::database::stats::passthru::histogramData(const uint32_t type,
|
||||||
|
rocksdb::HistogramData *const data)
|
||||||
|
const noexcept
|
||||||
|
{
|
||||||
|
throw assertive {"Unavailable for passthru"};
|
||||||
|
}
|
||||||
|
|
||||||
|
[[noreturn]]
|
||||||
|
uint64_t
|
||||||
|
ircd::db::database::stats::passthru::getAndResetTickerCount(const uint32_t tickerType)
|
||||||
|
noexcept
|
||||||
|
{
|
||||||
|
throw assertive {"Unavailable for passthru"};
|
||||||
|
}
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
//
|
//
|
||||||
// database::events
|
// database::events
|
||||||
|
@ -2246,13 +2344,15 @@ ircd::db::database::cache::cache(database *const &d,
|
||||||
{
|
{
|
||||||
rocksdb::NewLRUCache
|
rocksdb::NewLRUCache
|
||||||
(
|
(
|
||||||
std::max(initial_capacity, ssize_t(0)),
|
std::max(initial_capacity, ssize_t(0))
|
||||||
DEFAULT_SHARD_BITS,
|
,DEFAULT_SHARD_BITS
|
||||||
DEFAULT_STRICT,
|
,DEFAULT_STRICT
|
||||||
DEFAULT_HI_PRIO
|
,DEFAULT_HI_PRIO
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
,stats{d}
|
||||||
{
|
{
|
||||||
|
assert(bool(c));
|
||||||
}
|
}
|
||||||
|
|
||||||
ircd::db::database::cache::~cache()
|
ircd::db::database::cache::~cache()
|
||||||
|
@ -2283,7 +2383,9 @@ noexcept
|
||||||
c->Insert(key, value, charge, del, handle, priority)
|
c->Insert(key, value, charge, del, handle, priority)
|
||||||
};
|
};
|
||||||
|
|
||||||
stats.inserts += ret.ok();
|
this->stats.recordTick(rocksdb::Tickers::BLOCK_CACHE_ADD, ret.ok());
|
||||||
|
this->stats.recordTick(rocksdb::Tickers::BLOCK_CACHE_ADD_FAILURES, !ret.ok());
|
||||||
|
this->stats.recordTick(rocksdb::Tickers::BLOCK_CACHE_DATA_BYTES_INSERT, ret.ok()? charge : 0UL);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2293,13 +2395,30 @@ ircd::db::database::cache::Lookup(const Slice &key,
|
||||||
noexcept
|
noexcept
|
||||||
{
|
{
|
||||||
assert(bool(c));
|
assert(bool(c));
|
||||||
auto *const &ret
|
|
||||||
|
database::stats::passthru passthru
|
||||||
{
|
{
|
||||||
c->Lookup(key, statistics)
|
&this->stats, statistics
|
||||||
};
|
};
|
||||||
|
|
||||||
stats.hits += bool(ret);
|
rocksdb::Statistics *const s
|
||||||
stats.misses += !bool(ret);
|
{
|
||||||
|
statistics?
|
||||||
|
dynamic_cast<rocksdb::Statistics *>(&passthru):
|
||||||
|
dynamic_cast<rocksdb::Statistics *>(&this->stats)
|
||||||
|
};
|
||||||
|
|
||||||
|
auto *const &ret
|
||||||
|
{
|
||||||
|
c->Lookup(key, s)
|
||||||
|
};
|
||||||
|
|
||||||
|
// Rocksdb's LRUCache stats are broke. The statistics ptr is null and
|
||||||
|
// passing it to Lookup() does nothing internally. We have to do this
|
||||||
|
// here ourselves :/
|
||||||
|
|
||||||
|
this->stats.recordTick(rocksdb::Tickers::BLOCK_CACHE_HIT, bool(ret));
|
||||||
|
this->stats.recordTick(rocksdb::Tickers::BLOCK_CACHE_MISS, !bool(ret));
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -8885,21 +9004,23 @@ ircd::db::capacity(const rocksdb::Cache &cache)
|
||||||
return cache.GetCapacity();
|
return cache.GetCapacity();
|
||||||
}
|
}
|
||||||
|
|
||||||
ircd::db::cache_stats
|
uint64_t
|
||||||
ircd::db::stats(const rocksdb::Cache *const &cache)
|
ircd::db::ticker(const rocksdb::Cache *const &cache,
|
||||||
|
const uint32_t &ticker_id)
|
||||||
{
|
{
|
||||||
return cache? stats(*cache) : cache_stats{};
|
return cache? ticker(*cache, ticker_id) : 0UL;
|
||||||
}
|
}
|
||||||
|
|
||||||
const ircd::db::cache_stats &
|
const uint64_t &
|
||||||
ircd::db::stats(const rocksdb::Cache &cache)
|
ircd::db::ticker(const rocksdb::Cache &cache,
|
||||||
|
const uint32_t &ticker_id)
|
||||||
{
|
{
|
||||||
const auto &dc
|
const auto &c
|
||||||
{
|
{
|
||||||
dynamic_cast<const database::cache &>(cache)
|
dynamic_cast<const database::cache &>(cache)
|
||||||
};
|
};
|
||||||
|
|
||||||
return dc.stats;
|
return c.stats.ticker.at(ticker_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
Loading…
Reference in a new issue