1 // Copyright (c) 2011-present, Facebook, Inc. All rights reserved.
2 // This source code is licensed under both the GPLv2 (found in the
3 // COPYING file in the root directory) and Apache 2.0 License
4 // (found in the LICENSE.Apache file in the root directory).
6 #include "monitoring/statistics.h"
11 #include "rocksdb/statistics.h"
13 namespace ROCKSDB_NAMESPACE
{
15 // The order of items listed in Tickers should be the same as
16 // the order listed in TickersNameMap
17 const std::vector
<std::pair
<Tickers
, std::string
>> TickersNameMap
= {
18 {BLOCK_CACHE_MISS
, "rocksdb.block.cache.miss"},
19 {BLOCK_CACHE_HIT
, "rocksdb.block.cache.hit"},
20 {BLOCK_CACHE_ADD
, "rocksdb.block.cache.add"},
21 {BLOCK_CACHE_ADD_FAILURES
, "rocksdb.block.cache.add.failures"},
22 {BLOCK_CACHE_INDEX_MISS
, "rocksdb.block.cache.index.miss"},
23 {BLOCK_CACHE_INDEX_HIT
, "rocksdb.block.cache.index.hit"},
24 {BLOCK_CACHE_INDEX_ADD
, "rocksdb.block.cache.index.add"},
25 {BLOCK_CACHE_INDEX_BYTES_INSERT
, "rocksdb.block.cache.index.bytes.insert"},
26 {BLOCK_CACHE_INDEX_BYTES_EVICT
, "rocksdb.block.cache.index.bytes.evict"},
27 {BLOCK_CACHE_FILTER_MISS
, "rocksdb.block.cache.filter.miss"},
28 {BLOCK_CACHE_FILTER_HIT
, "rocksdb.block.cache.filter.hit"},
29 {BLOCK_CACHE_FILTER_ADD
, "rocksdb.block.cache.filter.add"},
30 {BLOCK_CACHE_FILTER_BYTES_INSERT
,
31 "rocksdb.block.cache.filter.bytes.insert"},
32 {BLOCK_CACHE_FILTER_BYTES_EVICT
, "rocksdb.block.cache.filter.bytes.evict"},
33 {BLOCK_CACHE_DATA_MISS
, "rocksdb.block.cache.data.miss"},
34 {BLOCK_CACHE_DATA_HIT
, "rocksdb.block.cache.data.hit"},
35 {BLOCK_CACHE_DATA_ADD
, "rocksdb.block.cache.data.add"},
36 {BLOCK_CACHE_DATA_BYTES_INSERT
, "rocksdb.block.cache.data.bytes.insert"},
37 {BLOCK_CACHE_BYTES_READ
, "rocksdb.block.cache.bytes.read"},
38 {BLOCK_CACHE_BYTES_WRITE
, "rocksdb.block.cache.bytes.write"},
39 {BLOOM_FILTER_USEFUL
, "rocksdb.bloom.filter.useful"},
40 {BLOOM_FILTER_FULL_POSITIVE
, "rocksdb.bloom.filter.full.positive"},
41 {BLOOM_FILTER_FULL_TRUE_POSITIVE
,
42 "rocksdb.bloom.filter.full.true.positive"},
43 {BLOOM_FILTER_MICROS
, "rocksdb.bloom.filter.micros"},
44 {PERSISTENT_CACHE_HIT
, "rocksdb.persistent.cache.hit"},
45 {PERSISTENT_CACHE_MISS
, "rocksdb.persistent.cache.miss"},
46 {SIM_BLOCK_CACHE_HIT
, "rocksdb.sim.block.cache.hit"},
47 {SIM_BLOCK_CACHE_MISS
, "rocksdb.sim.block.cache.miss"},
48 {MEMTABLE_HIT
, "rocksdb.memtable.hit"},
49 {MEMTABLE_MISS
, "rocksdb.memtable.miss"},
50 {GET_HIT_L0
, "rocksdb.l0.hit"},
51 {GET_HIT_L1
, "rocksdb.l1.hit"},
52 {GET_HIT_L2_AND_UP
, "rocksdb.l2andup.hit"},
53 {COMPACTION_KEY_DROP_NEWER_ENTRY
, "rocksdb.compaction.key.drop.new"},
54 {COMPACTION_KEY_DROP_OBSOLETE
, "rocksdb.compaction.key.drop.obsolete"},
55 {COMPACTION_KEY_DROP_RANGE_DEL
, "rocksdb.compaction.key.drop.range_del"},
56 {COMPACTION_KEY_DROP_USER
, "rocksdb.compaction.key.drop.user"},
57 {COMPACTION_RANGE_DEL_DROP_OBSOLETE
,
58 "rocksdb.compaction.range_del.drop.obsolete"},
59 {COMPACTION_OPTIMIZED_DEL_DROP_OBSOLETE
,
60 "rocksdb.compaction.optimized.del.drop.obsolete"},
61 {COMPACTION_CANCELLED
, "rocksdb.compaction.cancelled"},
62 {NUMBER_KEYS_WRITTEN
, "rocksdb.number.keys.written"},
63 {NUMBER_KEYS_READ
, "rocksdb.number.keys.read"},
64 {NUMBER_KEYS_UPDATED
, "rocksdb.number.keys.updated"},
65 {BYTES_WRITTEN
, "rocksdb.bytes.written"},
66 {BYTES_READ
, "rocksdb.bytes.read"},
67 {NUMBER_DB_SEEK
, "rocksdb.number.db.seek"},
68 {NUMBER_DB_NEXT
, "rocksdb.number.db.next"},
69 {NUMBER_DB_PREV
, "rocksdb.number.db.prev"},
70 {NUMBER_DB_SEEK_FOUND
, "rocksdb.number.db.seek.found"},
71 {NUMBER_DB_NEXT_FOUND
, "rocksdb.number.db.next.found"},
72 {NUMBER_DB_PREV_FOUND
, "rocksdb.number.db.prev.found"},
73 {ITER_BYTES_READ
, "rocksdb.db.iter.bytes.read"},
74 {NO_FILE_CLOSES
, "rocksdb.no.file.closes"},
75 {NO_FILE_OPENS
, "rocksdb.no.file.opens"},
76 {NO_FILE_ERRORS
, "rocksdb.no.file.errors"},
77 {STALL_L0_SLOWDOWN_MICROS
, "rocksdb.l0.slowdown.micros"},
78 {STALL_MEMTABLE_COMPACTION_MICROS
, "rocksdb.memtable.compaction.micros"},
79 {STALL_L0_NUM_FILES_MICROS
, "rocksdb.l0.num.files.stall.micros"},
80 {STALL_MICROS
, "rocksdb.stall.micros"},
81 {DB_MUTEX_WAIT_MICROS
, "rocksdb.db.mutex.wait.micros"},
82 {RATE_LIMIT_DELAY_MILLIS
, "rocksdb.rate.limit.delay.millis"},
83 {NO_ITERATORS
, "rocksdb.num.iterators"},
84 {NUMBER_MULTIGET_CALLS
, "rocksdb.number.multiget.get"},
85 {NUMBER_MULTIGET_KEYS_READ
, "rocksdb.number.multiget.keys.read"},
86 {NUMBER_MULTIGET_BYTES_READ
, "rocksdb.number.multiget.bytes.read"},
87 {NUMBER_FILTERED_DELETES
, "rocksdb.number.deletes.filtered"},
88 {NUMBER_MERGE_FAILURES
, "rocksdb.number.merge.failures"},
89 {BLOOM_FILTER_PREFIX_CHECKED
, "rocksdb.bloom.filter.prefix.checked"},
90 {BLOOM_FILTER_PREFIX_USEFUL
, "rocksdb.bloom.filter.prefix.useful"},
91 {NUMBER_OF_RESEEKS_IN_ITERATION
, "rocksdb.number.reseeks.iteration"},
92 {GET_UPDATES_SINCE_CALLS
, "rocksdb.getupdatessince.calls"},
93 {BLOCK_CACHE_COMPRESSED_MISS
, "rocksdb.block.cachecompressed.miss"},
94 {BLOCK_CACHE_COMPRESSED_HIT
, "rocksdb.block.cachecompressed.hit"},
95 {BLOCK_CACHE_COMPRESSED_ADD
, "rocksdb.block.cachecompressed.add"},
96 {BLOCK_CACHE_COMPRESSED_ADD_FAILURES
,
97 "rocksdb.block.cachecompressed.add.failures"},
98 {WAL_FILE_SYNCED
, "rocksdb.wal.synced"},
99 {WAL_FILE_BYTES
, "rocksdb.wal.bytes"},
100 {WRITE_DONE_BY_SELF
, "rocksdb.write.self"},
101 {WRITE_DONE_BY_OTHER
, "rocksdb.write.other"},
102 {WRITE_TIMEDOUT
, "rocksdb.write.timeout"},
103 {WRITE_WITH_WAL
, "rocksdb.write.wal"},
104 {COMPACT_READ_BYTES
, "rocksdb.compact.read.bytes"},
105 {COMPACT_WRITE_BYTES
, "rocksdb.compact.write.bytes"},
106 {FLUSH_WRITE_BYTES
, "rocksdb.flush.write.bytes"},
107 {COMPACT_READ_BYTES_MARKED
, "rocksdb.compact.read.marked.bytes"},
108 {COMPACT_READ_BYTES_PERIODIC
, "rocksdb.compact.read.periodic.bytes"},
109 {COMPACT_READ_BYTES_TTL
, "rocksdb.compact.read.ttl.bytes"},
110 {COMPACT_WRITE_BYTES_MARKED
, "rocksdb.compact.write.marked.bytes"},
111 {COMPACT_WRITE_BYTES_PERIODIC
, "rocksdb.compact.write.periodic.bytes"},
112 {COMPACT_WRITE_BYTES_TTL
, "rocksdb.compact.write.ttl.bytes"},
113 {NUMBER_DIRECT_LOAD_TABLE_PROPERTIES
,
114 "rocksdb.number.direct.load.table.properties"},
115 {NUMBER_SUPERVERSION_ACQUIRES
, "rocksdb.number.superversion_acquires"},
116 {NUMBER_SUPERVERSION_RELEASES
, "rocksdb.number.superversion_releases"},
117 {NUMBER_SUPERVERSION_CLEANUPS
, "rocksdb.number.superversion_cleanups"},
118 {NUMBER_BLOCK_COMPRESSED
, "rocksdb.number.block.compressed"},
119 {NUMBER_BLOCK_DECOMPRESSED
, "rocksdb.number.block.decompressed"},
120 {NUMBER_BLOCK_NOT_COMPRESSED
, "rocksdb.number.block.not_compressed"},
121 {MERGE_OPERATION_TOTAL_TIME
, "rocksdb.merge.operation.time.nanos"},
122 {FILTER_OPERATION_TOTAL_TIME
, "rocksdb.filter.operation.time.nanos"},
123 {ROW_CACHE_HIT
, "rocksdb.row.cache.hit"},
124 {ROW_CACHE_MISS
, "rocksdb.row.cache.miss"},
125 {READ_AMP_ESTIMATE_USEFUL_BYTES
, "rocksdb.read.amp.estimate.useful.bytes"},
126 {READ_AMP_TOTAL_READ_BYTES
, "rocksdb.read.amp.total.read.bytes"},
127 {NUMBER_RATE_LIMITER_DRAINS
, "rocksdb.number.rate_limiter.drains"},
128 {NUMBER_ITER_SKIP
, "rocksdb.number.iter.skip"},
129 {BLOB_DB_NUM_PUT
, "rocksdb.blobdb.num.put"},
130 {BLOB_DB_NUM_WRITE
, "rocksdb.blobdb.num.write"},
131 {BLOB_DB_NUM_GET
, "rocksdb.blobdb.num.get"},
132 {BLOB_DB_NUM_MULTIGET
, "rocksdb.blobdb.num.multiget"},
133 {BLOB_DB_NUM_SEEK
, "rocksdb.blobdb.num.seek"},
134 {BLOB_DB_NUM_NEXT
, "rocksdb.blobdb.num.next"},
135 {BLOB_DB_NUM_PREV
, "rocksdb.blobdb.num.prev"},
136 {BLOB_DB_NUM_KEYS_WRITTEN
, "rocksdb.blobdb.num.keys.written"},
137 {BLOB_DB_NUM_KEYS_READ
, "rocksdb.blobdb.num.keys.read"},
138 {BLOB_DB_BYTES_WRITTEN
, "rocksdb.blobdb.bytes.written"},
139 {BLOB_DB_BYTES_READ
, "rocksdb.blobdb.bytes.read"},
140 {BLOB_DB_WRITE_INLINED
, "rocksdb.blobdb.write.inlined"},
141 {BLOB_DB_WRITE_INLINED_TTL
, "rocksdb.blobdb.write.inlined.ttl"},
142 {BLOB_DB_WRITE_BLOB
, "rocksdb.blobdb.write.blob"},
143 {BLOB_DB_WRITE_BLOB_TTL
, "rocksdb.blobdb.write.blob.ttl"},
144 {BLOB_DB_BLOB_FILE_BYTES_WRITTEN
, "rocksdb.blobdb.blob.file.bytes.written"},
145 {BLOB_DB_BLOB_FILE_BYTES_READ
, "rocksdb.blobdb.blob.file.bytes.read"},
146 {BLOB_DB_BLOB_FILE_SYNCED
, "rocksdb.blobdb.blob.file.synced"},
147 {BLOB_DB_BLOB_INDEX_EXPIRED_COUNT
,
148 "rocksdb.blobdb.blob.index.expired.count"},
149 {BLOB_DB_BLOB_INDEX_EXPIRED_SIZE
, "rocksdb.blobdb.blob.index.expired.size"},
150 {BLOB_DB_BLOB_INDEX_EVICTED_COUNT
,
151 "rocksdb.blobdb.blob.index.evicted.count"},
152 {BLOB_DB_BLOB_INDEX_EVICTED_SIZE
, "rocksdb.blobdb.blob.index.evicted.size"},
153 {BLOB_DB_GC_NUM_FILES
, "rocksdb.blobdb.gc.num.files"},
154 {BLOB_DB_GC_NUM_NEW_FILES
, "rocksdb.blobdb.gc.num.new.files"},
155 {BLOB_DB_GC_FAILURES
, "rocksdb.blobdb.gc.failures"},
156 {BLOB_DB_GC_NUM_KEYS_OVERWRITTEN
, "rocksdb.blobdb.gc.num.keys.overwritten"},
157 {BLOB_DB_GC_NUM_KEYS_EXPIRED
, "rocksdb.blobdb.gc.num.keys.expired"},
158 {BLOB_DB_GC_NUM_KEYS_RELOCATED
, "rocksdb.blobdb.gc.num.keys.relocated"},
159 {BLOB_DB_GC_BYTES_OVERWRITTEN
, "rocksdb.blobdb.gc.bytes.overwritten"},
160 {BLOB_DB_GC_BYTES_EXPIRED
, "rocksdb.blobdb.gc.bytes.expired"},
161 {BLOB_DB_GC_BYTES_RELOCATED
, "rocksdb.blobdb.gc.bytes.relocated"},
162 {BLOB_DB_FIFO_NUM_FILES_EVICTED
, "rocksdb.blobdb.fifo.num.files.evicted"},
163 {BLOB_DB_FIFO_NUM_KEYS_EVICTED
, "rocksdb.blobdb.fifo.num.keys.evicted"},
164 {BLOB_DB_FIFO_BYTES_EVICTED
, "rocksdb.blobdb.fifo.bytes.evicted"},
165 {TXN_PREPARE_MUTEX_OVERHEAD
, "rocksdb.txn.overhead.mutex.prepare"},
166 {TXN_OLD_COMMIT_MAP_MUTEX_OVERHEAD
,
167 "rocksdb.txn.overhead.mutex.old.commit.map"},
168 {TXN_DUPLICATE_KEY_OVERHEAD
, "rocksdb.txn.overhead.duplicate.key"},
169 {TXN_SNAPSHOT_MUTEX_OVERHEAD
, "rocksdb.txn.overhead.mutex.snapshot"},
170 {TXN_GET_TRY_AGAIN
, "rocksdb.txn.get.tryagain"},
171 {NUMBER_MULTIGET_KEYS_FOUND
, "rocksdb.number.multiget.keys.found"},
172 {NO_ITERATOR_CREATED
, "rocksdb.num.iterator.created"},
173 {NO_ITERATOR_DELETED
, "rocksdb.num.iterator.deleted"},
174 {BLOCK_CACHE_COMPRESSION_DICT_MISS
,
175 "rocksdb.block.cache.compression.dict.miss"},
176 {BLOCK_CACHE_COMPRESSION_DICT_HIT
,
177 "rocksdb.block.cache.compression.dict.hit"},
178 {BLOCK_CACHE_COMPRESSION_DICT_ADD
,
179 "rocksdb.block.cache.compression.dict.add"},
180 {BLOCK_CACHE_COMPRESSION_DICT_BYTES_INSERT
,
181 "rocksdb.block.cache.compression.dict.bytes.insert"},
182 {BLOCK_CACHE_COMPRESSION_DICT_BYTES_EVICT
,
183 "rocksdb.block.cache.compression.dict.bytes.evict"},
184 {BLOCK_CACHE_ADD_REDUNDANT
, "rocksdb.block.cache.add.redundant"},
185 {BLOCK_CACHE_INDEX_ADD_REDUNDANT
,
186 "rocksdb.block.cache.index.add.redundant"},
187 {BLOCK_CACHE_FILTER_ADD_REDUNDANT
,
188 "rocksdb.block.cache.filter.add.redundant"},
189 {BLOCK_CACHE_DATA_ADD_REDUNDANT
, "rocksdb.block.cache.data.add.redundant"},
190 {BLOCK_CACHE_COMPRESSION_DICT_ADD_REDUNDANT
,
191 "rocksdb.block.cache.compression.dict.add.redundant"},
192 {FILES_MARKED_TRASH
, "rocksdb.files.marked.trash"},
193 {FILES_DELETED_IMMEDIATELY
, "rocksdb.files.deleted.immediately"},
196 const std::vector
<std::pair
<Histograms
, std::string
>> HistogramsNameMap
= {
197 {DB_GET
, "rocksdb.db.get.micros"},
198 {DB_WRITE
, "rocksdb.db.write.micros"},
199 {COMPACTION_TIME
, "rocksdb.compaction.times.micros"},
200 {COMPACTION_CPU_TIME
, "rocksdb.compaction.times.cpu_micros"},
201 {SUBCOMPACTION_SETUP_TIME
, "rocksdb.subcompaction.setup.times.micros"},
202 {TABLE_SYNC_MICROS
, "rocksdb.table.sync.micros"},
203 {COMPACTION_OUTFILE_SYNC_MICROS
, "rocksdb.compaction.outfile.sync.micros"},
204 {WAL_FILE_SYNC_MICROS
, "rocksdb.wal.file.sync.micros"},
205 {MANIFEST_FILE_SYNC_MICROS
, "rocksdb.manifest.file.sync.micros"},
206 {TABLE_OPEN_IO_MICROS
, "rocksdb.table.open.io.micros"},
207 {DB_MULTIGET
, "rocksdb.db.multiget.micros"},
208 {READ_BLOCK_COMPACTION_MICROS
, "rocksdb.read.block.compaction.micros"},
209 {READ_BLOCK_GET_MICROS
, "rocksdb.read.block.get.micros"},
210 {WRITE_RAW_BLOCK_MICROS
, "rocksdb.write.raw.block.micros"},
211 {STALL_L0_SLOWDOWN_COUNT
, "rocksdb.l0.slowdown.count"},
212 {STALL_MEMTABLE_COMPACTION_COUNT
, "rocksdb.memtable.compaction.count"},
213 {STALL_L0_NUM_FILES_COUNT
, "rocksdb.num.files.stall.count"},
214 {HARD_RATE_LIMIT_DELAY_COUNT
, "rocksdb.hard.rate.limit.delay.count"},
215 {SOFT_RATE_LIMIT_DELAY_COUNT
, "rocksdb.soft.rate.limit.delay.count"},
216 {NUM_FILES_IN_SINGLE_COMPACTION
, "rocksdb.numfiles.in.singlecompaction"},
217 {DB_SEEK
, "rocksdb.db.seek.micros"},
218 {WRITE_STALL
, "rocksdb.db.write.stall"},
219 {SST_READ_MICROS
, "rocksdb.sst.read.micros"},
220 {NUM_SUBCOMPACTIONS_SCHEDULED
, "rocksdb.num.subcompactions.scheduled"},
221 {BYTES_PER_READ
, "rocksdb.bytes.per.read"},
222 {BYTES_PER_WRITE
, "rocksdb.bytes.per.write"},
223 {BYTES_PER_MULTIGET
, "rocksdb.bytes.per.multiget"},
224 {BYTES_COMPRESSED
, "rocksdb.bytes.compressed"},
225 {BYTES_DECOMPRESSED
, "rocksdb.bytes.decompressed"},
226 {COMPRESSION_TIMES_NANOS
, "rocksdb.compression.times.nanos"},
227 {DECOMPRESSION_TIMES_NANOS
, "rocksdb.decompression.times.nanos"},
228 {READ_NUM_MERGE_OPERANDS
, "rocksdb.read.num.merge_operands"},
229 {BLOB_DB_KEY_SIZE
, "rocksdb.blobdb.key.size"},
230 {BLOB_DB_VALUE_SIZE
, "rocksdb.blobdb.value.size"},
231 {BLOB_DB_WRITE_MICROS
, "rocksdb.blobdb.write.micros"},
232 {BLOB_DB_GET_MICROS
, "rocksdb.blobdb.get.micros"},
233 {BLOB_DB_MULTIGET_MICROS
, "rocksdb.blobdb.multiget.micros"},
234 {BLOB_DB_SEEK_MICROS
, "rocksdb.blobdb.seek.micros"},
235 {BLOB_DB_NEXT_MICROS
, "rocksdb.blobdb.next.micros"},
236 {BLOB_DB_PREV_MICROS
, "rocksdb.blobdb.prev.micros"},
237 {BLOB_DB_BLOB_FILE_WRITE_MICROS
, "rocksdb.blobdb.blob.file.write.micros"},
238 {BLOB_DB_BLOB_FILE_READ_MICROS
, "rocksdb.blobdb.blob.file.read.micros"},
239 {BLOB_DB_BLOB_FILE_SYNC_MICROS
, "rocksdb.blobdb.blob.file.sync.micros"},
240 {BLOB_DB_GC_MICROS
, "rocksdb.blobdb.gc.micros"},
241 {BLOB_DB_COMPRESSION_MICROS
, "rocksdb.blobdb.compression.micros"},
242 {BLOB_DB_DECOMPRESSION_MICROS
, "rocksdb.blobdb.decompression.micros"},
243 {FLUSH_TIME
, "rocksdb.db.flush.micros"},
244 {SST_BATCH_SIZE
, "rocksdb.sst.batch.size"},
245 {NUM_INDEX_AND_FILTER_BLOCKS_READ_PER_LEVEL
,
246 "rocksdb.num.index.and.filter.blocks.read.per.level"},
247 {NUM_DATA_BLOCKS_READ_PER_LEVEL
, "rocksdb.num.data.blocks.read.per.level"},
248 {NUM_SST_READ_PER_LEVEL
, "rocksdb.num.sst.read.per.level"},
251 std::shared_ptr
<Statistics
> CreateDBStatistics() {
252 return std::make_shared
<StatisticsImpl
>(nullptr);
255 StatisticsImpl::StatisticsImpl(std::shared_ptr
<Statistics
> stats
)
256 : stats_(std::move(stats
)) {}
258 StatisticsImpl::~StatisticsImpl() {}
260 uint64_t StatisticsImpl::getTickerCount(uint32_t tickerType
) const {
261 MutexLock
lock(&aggregate_lock_
);
262 return getTickerCountLocked(tickerType
);
265 uint64_t StatisticsImpl::getTickerCountLocked(uint32_t tickerType
) const {
266 assert(tickerType
< TICKER_ENUM_MAX
);
268 for (size_t core_idx
= 0; core_idx
< per_core_stats_
.Size(); ++core_idx
) {
269 res
+= per_core_stats_
.AccessAtCore(core_idx
)->tickers_
[tickerType
];
274 void StatisticsImpl::histogramData(uint32_t histogramType
,
275 HistogramData
* const data
) const {
276 MutexLock
lock(&aggregate_lock_
);
277 getHistogramImplLocked(histogramType
)->Data(data
);
280 std::unique_ptr
<HistogramImpl
> StatisticsImpl::getHistogramImplLocked(
281 uint32_t histogramType
) const {
282 assert(histogramType
< HISTOGRAM_ENUM_MAX
);
283 std::unique_ptr
<HistogramImpl
> res_hist(new HistogramImpl());
284 for (size_t core_idx
= 0; core_idx
< per_core_stats_
.Size(); ++core_idx
) {
286 per_core_stats_
.AccessAtCore(core_idx
)->histograms_
[histogramType
]);
291 std::string
StatisticsImpl::getHistogramString(uint32_t histogramType
) const {
292 MutexLock
lock(&aggregate_lock_
);
293 return getHistogramImplLocked(histogramType
)->ToString();
296 void StatisticsImpl::setTickerCount(uint32_t tickerType
, uint64_t count
) {
298 MutexLock
lock(&aggregate_lock_
);
299 setTickerCountLocked(tickerType
, count
);
301 if (stats_
&& tickerType
< TICKER_ENUM_MAX
) {
302 stats_
->setTickerCount(tickerType
, count
);
306 void StatisticsImpl::setTickerCountLocked(uint32_t tickerType
, uint64_t count
) {
307 assert(tickerType
< TICKER_ENUM_MAX
);
308 for (size_t core_idx
= 0; core_idx
< per_core_stats_
.Size(); ++core_idx
) {
310 per_core_stats_
.AccessAtCore(core_idx
)->tickers_
[tickerType
] = count
;
312 per_core_stats_
.AccessAtCore(core_idx
)->tickers_
[tickerType
] = 0;
317 uint64_t StatisticsImpl::getAndResetTickerCount(uint32_t tickerType
) {
320 MutexLock
lock(&aggregate_lock_
);
321 assert(tickerType
< TICKER_ENUM_MAX
);
322 for (size_t core_idx
= 0; core_idx
< per_core_stats_
.Size(); ++core_idx
) {
324 per_core_stats_
.AccessAtCore(core_idx
)->tickers_
[tickerType
].exchange(
325 0, std::memory_order_relaxed
);
328 if (stats_
&& tickerType
< TICKER_ENUM_MAX
) {
329 stats_
->setTickerCount(tickerType
, 0);
334 void StatisticsImpl::recordTick(uint32_t tickerType
, uint64_t count
) {
335 if (get_stats_level() <= StatsLevel::kExceptTickers
) {
338 if (tickerType
< TICKER_ENUM_MAX
) {
339 per_core_stats_
.Access()->tickers_
[tickerType
].fetch_add(
340 count
, std::memory_order_relaxed
);
342 stats_
->recordTick(tickerType
, count
);
349 void StatisticsImpl::recordInHistogram(uint32_t histogramType
, uint64_t value
) {
350 assert(histogramType
< HISTOGRAM_ENUM_MAX
);
351 if (get_stats_level() <= StatsLevel::kExceptHistogramOrTimers
) {
354 per_core_stats_
.Access()->histograms_
[histogramType
].Add(value
);
355 if (stats_
&& histogramType
< HISTOGRAM_ENUM_MAX
) {
356 stats_
->recordInHistogram(histogramType
, value
);
360 Status
StatisticsImpl::Reset() {
361 MutexLock
lock(&aggregate_lock_
);
362 for (uint32_t i
= 0; i
< TICKER_ENUM_MAX
; ++i
) {
363 setTickerCountLocked(i
, 0);
365 for (uint32_t i
= 0; i
< HISTOGRAM_ENUM_MAX
; ++i
) {
366 for (size_t core_idx
= 0; core_idx
< per_core_stats_
.Size(); ++core_idx
) {
367 per_core_stats_
.AccessAtCore(core_idx
)->histograms_
[i
].Clear();
375 // a buffer size used for temp string buffers
376 const int kTmpStrBufferSize
= 200;
380 std::string
StatisticsImpl::ToString() const {
381 MutexLock
lock(&aggregate_lock_
);
384 for (const auto& t
: TickersNameMap
) {
385 assert(t
.first
< TICKER_ENUM_MAX
);
386 char buffer
[kTmpStrBufferSize
];
387 snprintf(buffer
, kTmpStrBufferSize
, "%s COUNT : %" PRIu64
"\n",
388 t
.second
.c_str(), getTickerCountLocked(t
.first
));
391 for (const auto& h
: HistogramsNameMap
) {
392 assert(h
.first
< HISTOGRAM_ENUM_MAX
);
393 char buffer
[kTmpStrBufferSize
];
395 getHistogramImplLocked(h
.first
)->Data(&hData
);
396 // don't handle failures - buffer should always be big enough and arguments
397 // should be provided correctly
399 snprintf(buffer
, kTmpStrBufferSize
,
400 "%s P50 : %f P95 : %f P99 : %f P100 : %f COUNT : %" PRIu64
401 " SUM : %" PRIu64
"\n",
402 h
.second
.c_str(), hData
.median
, hData
.percentile95
,
403 hData
.percentile99
, hData
.max
, hData
.count
, hData
.sum
);
404 if (ret
< 0 || ret
>= kTmpStrBufferSize
) {
414 bool StatisticsImpl::getTickerMap(
415 std::map
<std::string
, uint64_t>* stats_map
) const {
417 if (!stats_map
) return false;
419 MutexLock
lock(&aggregate_lock_
);
420 for (const auto& t
: TickersNameMap
) {
421 assert(t
.first
< TICKER_ENUM_MAX
);
422 (*stats_map
)[t
.second
.c_str()] = getTickerCountLocked(t
.first
);
427 bool StatisticsImpl::HistEnabledForType(uint32_t type
) const {
428 return type
< HISTOGRAM_ENUM_MAX
;
431 } // namespace ROCKSDB_NAMESPACE