]> git.proxmox.com Git - ceph.git/blob - ceph/src/rocksdb/monitoring/statistics.cc
bump version to 18.2.2-pve1
[ceph.git] / ceph / src / rocksdb / monitoring / statistics.cc
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).
5 //
6 #include "monitoring/statistics.h"
7
8 #include <algorithm>
9 #include <cinttypes>
10 #include <cstdio>
11
12 #include "rocksdb/convenience.h"
13 #include "rocksdb/statistics.h"
14 #include "rocksdb/utilities/customizable_util.h"
15 #include "rocksdb/utilities/options_type.h"
16 #include "util/string_util.h"
17
18 namespace ROCKSDB_NAMESPACE {
19
20 // The order of items listed in Tickers should be the same as
21 // the order listed in TickersNameMap
22 const std::vector<std::pair<Tickers, std::string>> TickersNameMap = {
23 {BLOCK_CACHE_MISS, "rocksdb.block.cache.miss"},
24 {BLOCK_CACHE_HIT, "rocksdb.block.cache.hit"},
25 {BLOCK_CACHE_ADD, "rocksdb.block.cache.add"},
26 {BLOCK_CACHE_ADD_FAILURES, "rocksdb.block.cache.add.failures"},
27 {BLOCK_CACHE_INDEX_MISS, "rocksdb.block.cache.index.miss"},
28 {BLOCK_CACHE_INDEX_HIT, "rocksdb.block.cache.index.hit"},
29 {BLOCK_CACHE_INDEX_ADD, "rocksdb.block.cache.index.add"},
30 {BLOCK_CACHE_INDEX_BYTES_INSERT, "rocksdb.block.cache.index.bytes.insert"},
31 {BLOCK_CACHE_INDEX_BYTES_EVICT, "rocksdb.block.cache.index.bytes.evict"},
32 {BLOCK_CACHE_FILTER_MISS, "rocksdb.block.cache.filter.miss"},
33 {BLOCK_CACHE_FILTER_HIT, "rocksdb.block.cache.filter.hit"},
34 {BLOCK_CACHE_FILTER_ADD, "rocksdb.block.cache.filter.add"},
35 {BLOCK_CACHE_FILTER_BYTES_INSERT,
36 "rocksdb.block.cache.filter.bytes.insert"},
37 {BLOCK_CACHE_FILTER_BYTES_EVICT, "rocksdb.block.cache.filter.bytes.evict"},
38 {BLOCK_CACHE_DATA_MISS, "rocksdb.block.cache.data.miss"},
39 {BLOCK_CACHE_DATA_HIT, "rocksdb.block.cache.data.hit"},
40 {BLOCK_CACHE_DATA_ADD, "rocksdb.block.cache.data.add"},
41 {BLOCK_CACHE_DATA_BYTES_INSERT, "rocksdb.block.cache.data.bytes.insert"},
42 {BLOCK_CACHE_BYTES_READ, "rocksdb.block.cache.bytes.read"},
43 {BLOCK_CACHE_BYTES_WRITE, "rocksdb.block.cache.bytes.write"},
44 {BLOOM_FILTER_USEFUL, "rocksdb.bloom.filter.useful"},
45 {BLOOM_FILTER_FULL_POSITIVE, "rocksdb.bloom.filter.full.positive"},
46 {BLOOM_FILTER_FULL_TRUE_POSITIVE,
47 "rocksdb.bloom.filter.full.true.positive"},
48 {BLOOM_FILTER_MICROS, "rocksdb.bloom.filter.micros"},
49 {PERSISTENT_CACHE_HIT, "rocksdb.persistent.cache.hit"},
50 {PERSISTENT_CACHE_MISS, "rocksdb.persistent.cache.miss"},
51 {SIM_BLOCK_CACHE_HIT, "rocksdb.sim.block.cache.hit"},
52 {SIM_BLOCK_CACHE_MISS, "rocksdb.sim.block.cache.miss"},
53 {MEMTABLE_HIT, "rocksdb.memtable.hit"},
54 {MEMTABLE_MISS, "rocksdb.memtable.miss"},
55 {GET_HIT_L0, "rocksdb.l0.hit"},
56 {GET_HIT_L1, "rocksdb.l1.hit"},
57 {GET_HIT_L2_AND_UP, "rocksdb.l2andup.hit"},
58 {COMPACTION_KEY_DROP_NEWER_ENTRY, "rocksdb.compaction.key.drop.new"},
59 {COMPACTION_KEY_DROP_OBSOLETE, "rocksdb.compaction.key.drop.obsolete"},
60 {COMPACTION_KEY_DROP_RANGE_DEL, "rocksdb.compaction.key.drop.range_del"},
61 {COMPACTION_KEY_DROP_USER, "rocksdb.compaction.key.drop.user"},
62 {COMPACTION_RANGE_DEL_DROP_OBSOLETE,
63 "rocksdb.compaction.range_del.drop.obsolete"},
64 {COMPACTION_OPTIMIZED_DEL_DROP_OBSOLETE,
65 "rocksdb.compaction.optimized.del.drop.obsolete"},
66 {COMPACTION_CANCELLED, "rocksdb.compaction.cancelled"},
67 {NUMBER_KEYS_WRITTEN, "rocksdb.number.keys.written"},
68 {NUMBER_KEYS_READ, "rocksdb.number.keys.read"},
69 {NUMBER_KEYS_UPDATED, "rocksdb.number.keys.updated"},
70 {BYTES_WRITTEN, "rocksdb.bytes.written"},
71 {BYTES_READ, "rocksdb.bytes.read"},
72 {NUMBER_DB_SEEK, "rocksdb.number.db.seek"},
73 {NUMBER_DB_NEXT, "rocksdb.number.db.next"},
74 {NUMBER_DB_PREV, "rocksdb.number.db.prev"},
75 {NUMBER_DB_SEEK_FOUND, "rocksdb.number.db.seek.found"},
76 {NUMBER_DB_NEXT_FOUND, "rocksdb.number.db.next.found"},
77 {NUMBER_DB_PREV_FOUND, "rocksdb.number.db.prev.found"},
78 {ITER_BYTES_READ, "rocksdb.db.iter.bytes.read"},
79 {NO_FILE_CLOSES, "rocksdb.no.file.closes"},
80 {NO_FILE_OPENS, "rocksdb.no.file.opens"},
81 {NO_FILE_ERRORS, "rocksdb.no.file.errors"},
82 {STALL_L0_SLOWDOWN_MICROS, "rocksdb.l0.slowdown.micros"},
83 {STALL_MEMTABLE_COMPACTION_MICROS, "rocksdb.memtable.compaction.micros"},
84 {STALL_L0_NUM_FILES_MICROS, "rocksdb.l0.num.files.stall.micros"},
85 {STALL_MICROS, "rocksdb.stall.micros"},
86 {DB_MUTEX_WAIT_MICROS, "rocksdb.db.mutex.wait.micros"},
87 {RATE_LIMIT_DELAY_MILLIS, "rocksdb.rate.limit.delay.millis"},
88 {NO_ITERATORS, "rocksdb.num.iterators"},
89 {NUMBER_MULTIGET_CALLS, "rocksdb.number.multiget.get"},
90 {NUMBER_MULTIGET_KEYS_READ, "rocksdb.number.multiget.keys.read"},
91 {NUMBER_MULTIGET_BYTES_READ, "rocksdb.number.multiget.bytes.read"},
92 {NUMBER_FILTERED_DELETES, "rocksdb.number.deletes.filtered"},
93 {NUMBER_MERGE_FAILURES, "rocksdb.number.merge.failures"},
94 {BLOOM_FILTER_PREFIX_CHECKED, "rocksdb.bloom.filter.prefix.checked"},
95 {BLOOM_FILTER_PREFIX_USEFUL, "rocksdb.bloom.filter.prefix.useful"},
96 {NUMBER_OF_RESEEKS_IN_ITERATION, "rocksdb.number.reseeks.iteration"},
97 {GET_UPDATES_SINCE_CALLS, "rocksdb.getupdatessince.calls"},
98 {BLOCK_CACHE_COMPRESSED_MISS, "rocksdb.block.cachecompressed.miss"},
99 {BLOCK_CACHE_COMPRESSED_HIT, "rocksdb.block.cachecompressed.hit"},
100 {BLOCK_CACHE_COMPRESSED_ADD, "rocksdb.block.cachecompressed.add"},
101 {BLOCK_CACHE_COMPRESSED_ADD_FAILURES,
102 "rocksdb.block.cachecompressed.add.failures"},
103 {WAL_FILE_SYNCED, "rocksdb.wal.synced"},
104 {WAL_FILE_BYTES, "rocksdb.wal.bytes"},
105 {WRITE_DONE_BY_SELF, "rocksdb.write.self"},
106 {WRITE_DONE_BY_OTHER, "rocksdb.write.other"},
107 {WRITE_TIMEDOUT, "rocksdb.write.timeout"},
108 {WRITE_WITH_WAL, "rocksdb.write.wal"},
109 {COMPACT_READ_BYTES, "rocksdb.compact.read.bytes"},
110 {COMPACT_WRITE_BYTES, "rocksdb.compact.write.bytes"},
111 {FLUSH_WRITE_BYTES, "rocksdb.flush.write.bytes"},
112 {COMPACT_READ_BYTES_MARKED, "rocksdb.compact.read.marked.bytes"},
113 {COMPACT_READ_BYTES_PERIODIC, "rocksdb.compact.read.periodic.bytes"},
114 {COMPACT_READ_BYTES_TTL, "rocksdb.compact.read.ttl.bytes"},
115 {COMPACT_WRITE_BYTES_MARKED, "rocksdb.compact.write.marked.bytes"},
116 {COMPACT_WRITE_BYTES_PERIODIC, "rocksdb.compact.write.periodic.bytes"},
117 {COMPACT_WRITE_BYTES_TTL, "rocksdb.compact.write.ttl.bytes"},
118 {NUMBER_DIRECT_LOAD_TABLE_PROPERTIES,
119 "rocksdb.number.direct.load.table.properties"},
120 {NUMBER_SUPERVERSION_ACQUIRES, "rocksdb.number.superversion_acquires"},
121 {NUMBER_SUPERVERSION_RELEASES, "rocksdb.number.superversion_releases"},
122 {NUMBER_SUPERVERSION_CLEANUPS, "rocksdb.number.superversion_cleanups"},
123 {NUMBER_BLOCK_COMPRESSED, "rocksdb.number.block.compressed"},
124 {NUMBER_BLOCK_DECOMPRESSED, "rocksdb.number.block.decompressed"},
125 {NUMBER_BLOCK_NOT_COMPRESSED, "rocksdb.number.block.not_compressed"},
126 {MERGE_OPERATION_TOTAL_TIME, "rocksdb.merge.operation.time.nanos"},
127 {FILTER_OPERATION_TOTAL_TIME, "rocksdb.filter.operation.time.nanos"},
128 {ROW_CACHE_HIT, "rocksdb.row.cache.hit"},
129 {ROW_CACHE_MISS, "rocksdb.row.cache.miss"},
130 {READ_AMP_ESTIMATE_USEFUL_BYTES, "rocksdb.read.amp.estimate.useful.bytes"},
131 {READ_AMP_TOTAL_READ_BYTES, "rocksdb.read.amp.total.read.bytes"},
132 {NUMBER_RATE_LIMITER_DRAINS, "rocksdb.number.rate_limiter.drains"},
133 {NUMBER_ITER_SKIP, "rocksdb.number.iter.skip"},
134 {BLOB_DB_NUM_PUT, "rocksdb.blobdb.num.put"},
135 {BLOB_DB_NUM_WRITE, "rocksdb.blobdb.num.write"},
136 {BLOB_DB_NUM_GET, "rocksdb.blobdb.num.get"},
137 {BLOB_DB_NUM_MULTIGET, "rocksdb.blobdb.num.multiget"},
138 {BLOB_DB_NUM_SEEK, "rocksdb.blobdb.num.seek"},
139 {BLOB_DB_NUM_NEXT, "rocksdb.blobdb.num.next"},
140 {BLOB_DB_NUM_PREV, "rocksdb.blobdb.num.prev"},
141 {BLOB_DB_NUM_KEYS_WRITTEN, "rocksdb.blobdb.num.keys.written"},
142 {BLOB_DB_NUM_KEYS_READ, "rocksdb.blobdb.num.keys.read"},
143 {BLOB_DB_BYTES_WRITTEN, "rocksdb.blobdb.bytes.written"},
144 {BLOB_DB_BYTES_READ, "rocksdb.blobdb.bytes.read"},
145 {BLOB_DB_WRITE_INLINED, "rocksdb.blobdb.write.inlined"},
146 {BLOB_DB_WRITE_INLINED_TTL, "rocksdb.blobdb.write.inlined.ttl"},
147 {BLOB_DB_WRITE_BLOB, "rocksdb.blobdb.write.blob"},
148 {BLOB_DB_WRITE_BLOB_TTL, "rocksdb.blobdb.write.blob.ttl"},
149 {BLOB_DB_BLOB_FILE_BYTES_WRITTEN, "rocksdb.blobdb.blob.file.bytes.written"},
150 {BLOB_DB_BLOB_FILE_BYTES_READ, "rocksdb.blobdb.blob.file.bytes.read"},
151 {BLOB_DB_BLOB_FILE_SYNCED, "rocksdb.blobdb.blob.file.synced"},
152 {BLOB_DB_BLOB_INDEX_EXPIRED_COUNT,
153 "rocksdb.blobdb.blob.index.expired.count"},
154 {BLOB_DB_BLOB_INDEX_EXPIRED_SIZE, "rocksdb.blobdb.blob.index.expired.size"},
155 {BLOB_DB_BLOB_INDEX_EVICTED_COUNT,
156 "rocksdb.blobdb.blob.index.evicted.count"},
157 {BLOB_DB_BLOB_INDEX_EVICTED_SIZE, "rocksdb.blobdb.blob.index.evicted.size"},
158 {BLOB_DB_GC_NUM_FILES, "rocksdb.blobdb.gc.num.files"},
159 {BLOB_DB_GC_NUM_NEW_FILES, "rocksdb.blobdb.gc.num.new.files"},
160 {BLOB_DB_GC_FAILURES, "rocksdb.blobdb.gc.failures"},
161 {BLOB_DB_GC_NUM_KEYS_OVERWRITTEN, "rocksdb.blobdb.gc.num.keys.overwritten"},
162 {BLOB_DB_GC_NUM_KEYS_EXPIRED, "rocksdb.blobdb.gc.num.keys.expired"},
163 {BLOB_DB_GC_NUM_KEYS_RELOCATED, "rocksdb.blobdb.gc.num.keys.relocated"},
164 {BLOB_DB_GC_BYTES_OVERWRITTEN, "rocksdb.blobdb.gc.bytes.overwritten"},
165 {BLOB_DB_GC_BYTES_EXPIRED, "rocksdb.blobdb.gc.bytes.expired"},
166 {BLOB_DB_GC_BYTES_RELOCATED, "rocksdb.blobdb.gc.bytes.relocated"},
167 {BLOB_DB_FIFO_NUM_FILES_EVICTED, "rocksdb.blobdb.fifo.num.files.evicted"},
168 {BLOB_DB_FIFO_NUM_KEYS_EVICTED, "rocksdb.blobdb.fifo.num.keys.evicted"},
169 {BLOB_DB_FIFO_BYTES_EVICTED, "rocksdb.blobdb.fifo.bytes.evicted"},
170 {TXN_PREPARE_MUTEX_OVERHEAD, "rocksdb.txn.overhead.mutex.prepare"},
171 {TXN_OLD_COMMIT_MAP_MUTEX_OVERHEAD,
172 "rocksdb.txn.overhead.mutex.old.commit.map"},
173 {TXN_DUPLICATE_KEY_OVERHEAD, "rocksdb.txn.overhead.duplicate.key"},
174 {TXN_SNAPSHOT_MUTEX_OVERHEAD, "rocksdb.txn.overhead.mutex.snapshot"},
175 {TXN_GET_TRY_AGAIN, "rocksdb.txn.get.tryagain"},
176 {NUMBER_MULTIGET_KEYS_FOUND, "rocksdb.number.multiget.keys.found"},
177 {NO_ITERATOR_CREATED, "rocksdb.num.iterator.created"},
178 {NO_ITERATOR_DELETED, "rocksdb.num.iterator.deleted"},
179 {BLOCK_CACHE_COMPRESSION_DICT_MISS,
180 "rocksdb.block.cache.compression.dict.miss"},
181 {BLOCK_CACHE_COMPRESSION_DICT_HIT,
182 "rocksdb.block.cache.compression.dict.hit"},
183 {BLOCK_CACHE_COMPRESSION_DICT_ADD,
184 "rocksdb.block.cache.compression.dict.add"},
185 {BLOCK_CACHE_COMPRESSION_DICT_BYTES_INSERT,
186 "rocksdb.block.cache.compression.dict.bytes.insert"},
187 {BLOCK_CACHE_COMPRESSION_DICT_BYTES_EVICT,
188 "rocksdb.block.cache.compression.dict.bytes.evict"},
189 {BLOCK_CACHE_ADD_REDUNDANT, "rocksdb.block.cache.add.redundant"},
190 {BLOCK_CACHE_INDEX_ADD_REDUNDANT,
191 "rocksdb.block.cache.index.add.redundant"},
192 {BLOCK_CACHE_FILTER_ADD_REDUNDANT,
193 "rocksdb.block.cache.filter.add.redundant"},
194 {BLOCK_CACHE_DATA_ADD_REDUNDANT, "rocksdb.block.cache.data.add.redundant"},
195 {BLOCK_CACHE_COMPRESSION_DICT_ADD_REDUNDANT,
196 "rocksdb.block.cache.compression.dict.add.redundant"},
197 {FILES_MARKED_TRASH, "rocksdb.files.marked.trash"},
198 {FILES_DELETED_IMMEDIATELY, "rocksdb.files.deleted.immediately"},
199 {ERROR_HANDLER_BG_ERROR_COUNT, "rocksdb.error.handler.bg.errro.count"},
200 {ERROR_HANDLER_BG_IO_ERROR_COUNT,
201 "rocksdb.error.handler.bg.io.errro.count"},
202 {ERROR_HANDLER_BG_RETRYABLE_IO_ERROR_COUNT,
203 "rocksdb.error.handler.bg.retryable.io.errro.count"},
204 {ERROR_HANDLER_AUTORESUME_COUNT, "rocksdb.error.handler.autoresume.count"},
205 {ERROR_HANDLER_AUTORESUME_RETRY_TOTAL_COUNT,
206 "rocksdb.error.handler.autoresume.retry.total.count"},
207 {ERROR_HANDLER_AUTORESUME_SUCCESS_COUNT,
208 "rocksdb.error.handler.autoresume.success.count"},
209 {MEMTABLE_PAYLOAD_BYTES_AT_FLUSH,
210 "rocksdb.memtable.payload.bytes.at.flush"},
211 {MEMTABLE_GARBAGE_BYTES_AT_FLUSH,
212 "rocksdb.memtable.garbage.bytes.at.flush"},
213 {SECONDARY_CACHE_HITS, "rocksdb.secondary.cache.hits"},
214 {VERIFY_CHECKSUM_READ_BYTES, "rocksdb.verify_checksum.read.bytes"},
215 {BACKUP_READ_BYTES, "rocksdb.backup.read.bytes"},
216 {BACKUP_WRITE_BYTES, "rocksdb.backup.write.bytes"},
217 {REMOTE_COMPACT_READ_BYTES, "rocksdb.remote.compact.read.bytes"},
218 {REMOTE_COMPACT_WRITE_BYTES, "rocksdb.remote.compact.write.bytes"},
219 {HOT_FILE_READ_BYTES, "rocksdb.hot.file.read.bytes"},
220 {WARM_FILE_READ_BYTES, "rocksdb.warm.file.read.bytes"},
221 {COLD_FILE_READ_BYTES, "rocksdb.cold.file.read.bytes"},
222 {HOT_FILE_READ_COUNT, "rocksdb.hot.file.read.count"},
223 {WARM_FILE_READ_COUNT, "rocksdb.warm.file.read.count"},
224 {COLD_FILE_READ_COUNT, "rocksdb.cold.file.read.count"},
225 {LAST_LEVEL_READ_BYTES, "rocksdb.last.level.read.bytes"},
226 {LAST_LEVEL_READ_COUNT, "rocksdb.last.level.read.count"},
227 {NON_LAST_LEVEL_READ_BYTES, "rocksdb.non.last.level.read.bytes"},
228 {NON_LAST_LEVEL_READ_COUNT, "rocksdb.non.last.level.read.count"},
229 {BLOCK_CHECKSUM_COMPUTE_COUNT, "rocksdb.block.checksum.compute.count"},
230 {MULTIGET_COROUTINE_COUNT, "rocksdb.multiget.coroutine.count"},
231 {BLOB_DB_CACHE_MISS, "rocksdb.blobdb.cache.miss"},
232 {BLOB_DB_CACHE_HIT, "rocksdb.blobdb.cache.hit"},
233 {BLOB_DB_CACHE_ADD, "rocksdb.blobdb.cache.add"},
234 {BLOB_DB_CACHE_ADD_FAILURES, "rocksdb.blobdb.cache.add.failures"},
235 {BLOB_DB_CACHE_BYTES_READ, "rocksdb.blobdb.cache.bytes.read"},
236 {BLOB_DB_CACHE_BYTES_WRITE, "rocksdb.blobdb.cache.bytes.write"},
237 {READ_ASYNC_MICROS, "rocksdb.read.async.micros"},
238 {ASYNC_READ_ERROR_COUNT, "rocksdb.async.read.error.count"}};
239
240 const std::vector<std::pair<Histograms, std::string>> HistogramsNameMap = {
241 {DB_GET, "rocksdb.db.get.micros"},
242 {DB_WRITE, "rocksdb.db.write.micros"},
243 {COMPACTION_TIME, "rocksdb.compaction.times.micros"},
244 {COMPACTION_CPU_TIME, "rocksdb.compaction.times.cpu_micros"},
245 {SUBCOMPACTION_SETUP_TIME, "rocksdb.subcompaction.setup.times.micros"},
246 {TABLE_SYNC_MICROS, "rocksdb.table.sync.micros"},
247 {COMPACTION_OUTFILE_SYNC_MICROS, "rocksdb.compaction.outfile.sync.micros"},
248 {WAL_FILE_SYNC_MICROS, "rocksdb.wal.file.sync.micros"},
249 {MANIFEST_FILE_SYNC_MICROS, "rocksdb.manifest.file.sync.micros"},
250 {TABLE_OPEN_IO_MICROS, "rocksdb.table.open.io.micros"},
251 {DB_MULTIGET, "rocksdb.db.multiget.micros"},
252 {READ_BLOCK_COMPACTION_MICROS, "rocksdb.read.block.compaction.micros"},
253 {READ_BLOCK_GET_MICROS, "rocksdb.read.block.get.micros"},
254 {WRITE_RAW_BLOCK_MICROS, "rocksdb.write.raw.block.micros"},
255 {STALL_L0_SLOWDOWN_COUNT, "rocksdb.l0.slowdown.count"},
256 {STALL_MEMTABLE_COMPACTION_COUNT, "rocksdb.memtable.compaction.count"},
257 {STALL_L0_NUM_FILES_COUNT, "rocksdb.num.files.stall.count"},
258 {HARD_RATE_LIMIT_DELAY_COUNT, "rocksdb.hard.rate.limit.delay.count"},
259 {SOFT_RATE_LIMIT_DELAY_COUNT, "rocksdb.soft.rate.limit.delay.count"},
260 {NUM_FILES_IN_SINGLE_COMPACTION, "rocksdb.numfiles.in.singlecompaction"},
261 {DB_SEEK, "rocksdb.db.seek.micros"},
262 {WRITE_STALL, "rocksdb.db.write.stall"},
263 {SST_READ_MICROS, "rocksdb.sst.read.micros"},
264 {NUM_SUBCOMPACTIONS_SCHEDULED, "rocksdb.num.subcompactions.scheduled"},
265 {BYTES_PER_READ, "rocksdb.bytes.per.read"},
266 {BYTES_PER_WRITE, "rocksdb.bytes.per.write"},
267 {BYTES_PER_MULTIGET, "rocksdb.bytes.per.multiget"},
268 {BYTES_COMPRESSED, "rocksdb.bytes.compressed"},
269 {BYTES_DECOMPRESSED, "rocksdb.bytes.decompressed"},
270 {COMPRESSION_TIMES_NANOS, "rocksdb.compression.times.nanos"},
271 {DECOMPRESSION_TIMES_NANOS, "rocksdb.decompression.times.nanos"},
272 {READ_NUM_MERGE_OPERANDS, "rocksdb.read.num.merge_operands"},
273 {BLOB_DB_KEY_SIZE, "rocksdb.blobdb.key.size"},
274 {BLOB_DB_VALUE_SIZE, "rocksdb.blobdb.value.size"},
275 {BLOB_DB_WRITE_MICROS, "rocksdb.blobdb.write.micros"},
276 {BLOB_DB_GET_MICROS, "rocksdb.blobdb.get.micros"},
277 {BLOB_DB_MULTIGET_MICROS, "rocksdb.blobdb.multiget.micros"},
278 {BLOB_DB_SEEK_MICROS, "rocksdb.blobdb.seek.micros"},
279 {BLOB_DB_NEXT_MICROS, "rocksdb.blobdb.next.micros"},
280 {BLOB_DB_PREV_MICROS, "rocksdb.blobdb.prev.micros"},
281 {BLOB_DB_BLOB_FILE_WRITE_MICROS, "rocksdb.blobdb.blob.file.write.micros"},
282 {BLOB_DB_BLOB_FILE_READ_MICROS, "rocksdb.blobdb.blob.file.read.micros"},
283 {BLOB_DB_BLOB_FILE_SYNC_MICROS, "rocksdb.blobdb.blob.file.sync.micros"},
284 {BLOB_DB_GC_MICROS, "rocksdb.blobdb.gc.micros"},
285 {BLOB_DB_COMPRESSION_MICROS, "rocksdb.blobdb.compression.micros"},
286 {BLOB_DB_DECOMPRESSION_MICROS, "rocksdb.blobdb.decompression.micros"},
287 {FLUSH_TIME, "rocksdb.db.flush.micros"},
288 {SST_BATCH_SIZE, "rocksdb.sst.batch.size"},
289 {NUM_INDEX_AND_FILTER_BLOCKS_READ_PER_LEVEL,
290 "rocksdb.num.index.and.filter.blocks.read.per.level"},
291 {NUM_DATA_BLOCKS_READ_PER_LEVEL, "rocksdb.num.data.blocks.read.per.level"},
292 {NUM_SST_READ_PER_LEVEL, "rocksdb.num.sst.read.per.level"},
293 {ERROR_HANDLER_AUTORESUME_RETRY_COUNT,
294 "rocksdb.error.handler.autoresume.retry.count"},
295 {ASYNC_READ_BYTES, "rocksdb.async.read.bytes"},
296 {POLL_WAIT_MICROS, "rocksdb.poll.wait.micros"},
297 {PREFETCHED_BYTES_DISCARDED, "rocksdb.prefetched.bytes.discarded"},
298 {MULTIGET_IO_BATCH_SIZE, "rocksdb.multiget.io.batch.size"},
299 {NUM_LEVEL_READ_PER_MULTIGET, "rocksdb.num.level.read.per.multiget"},
300 {ASYNC_PREFETCH_ABORT_MICROS, "rocksdb.async.prefetch.abort.micros"},
301 };
302
303 std::shared_ptr<Statistics> CreateDBStatistics() {
304 return std::make_shared<StatisticsImpl>(nullptr);
305 }
306
307 #ifndef ROCKSDB_LITE
308 static int RegisterBuiltinStatistics(ObjectLibrary& library,
309 const std::string& /*arg*/) {
310 library.AddFactory<Statistics>(
311 StatisticsImpl::kClassName(),
312 [](const std::string& /*uri*/, std::unique_ptr<Statistics>* guard,
313 std::string* /* errmsg */) {
314 guard->reset(new StatisticsImpl(nullptr));
315 return guard->get();
316 });
317 return 1;
318 }
319 #endif // ROCKSDB_LITE
320
321 Status Statistics::CreateFromString(const ConfigOptions& config_options,
322 const std::string& id,
323 std::shared_ptr<Statistics>* result) {
324 #ifndef ROCKSDB_LITE
325 static std::once_flag once;
326 std::call_once(once, [&]() {
327 RegisterBuiltinStatistics(*(ObjectLibrary::Default().get()), "");
328 });
329 #endif // ROCKSDB_LITE
330 Status s;
331 if (id == "" || id == StatisticsImpl::kClassName()) {
332 result->reset(new StatisticsImpl(nullptr));
333 } else if (id == kNullptrString) {
334 result->reset();
335 } else {
336 s = LoadSharedObject<Statistics>(config_options, id, nullptr, result);
337 }
338 return s;
339 }
340
341 static std::unordered_map<std::string, OptionTypeInfo> stats_type_info = {
342 #ifndef ROCKSDB_LITE
343 {"inner", OptionTypeInfo::AsCustomSharedPtr<Statistics>(
344 0, OptionVerificationType::kByNameAllowFromNull,
345 OptionTypeFlags::kCompareNever)},
346 #endif // !ROCKSDB_LITE
347 };
348
349 StatisticsImpl::StatisticsImpl(std::shared_ptr<Statistics> stats)
350 : stats_(std::move(stats)) {
351 RegisterOptions("StatisticsOptions", &stats_, &stats_type_info);
352 }
353
354 StatisticsImpl::~StatisticsImpl() {}
355
356 uint64_t StatisticsImpl::getTickerCount(uint32_t tickerType) const {
357 MutexLock lock(&aggregate_lock_);
358 return getTickerCountLocked(tickerType);
359 }
360
361 uint64_t StatisticsImpl::getTickerCountLocked(uint32_t tickerType) const {
362 assert(tickerType < TICKER_ENUM_MAX);
363 uint64_t res = 0;
364 for (size_t core_idx = 0; core_idx < per_core_stats_.Size(); ++core_idx) {
365 res += per_core_stats_.AccessAtCore(core_idx)->tickers_[tickerType];
366 }
367 return res;
368 }
369
370 void StatisticsImpl::histogramData(uint32_t histogramType,
371 HistogramData* const data) const {
372 MutexLock lock(&aggregate_lock_);
373 getHistogramImplLocked(histogramType)->Data(data);
374 }
375
376 std::unique_ptr<HistogramImpl> StatisticsImpl::getHistogramImplLocked(
377 uint32_t histogramType) const {
378 assert(histogramType < HISTOGRAM_ENUM_MAX);
379 std::unique_ptr<HistogramImpl> res_hist(new HistogramImpl());
380 for (size_t core_idx = 0; core_idx < per_core_stats_.Size(); ++core_idx) {
381 res_hist->Merge(
382 per_core_stats_.AccessAtCore(core_idx)->histograms_[histogramType]);
383 }
384 return res_hist;
385 }
386
387 std::string StatisticsImpl::getHistogramString(uint32_t histogramType) const {
388 MutexLock lock(&aggregate_lock_);
389 return getHistogramImplLocked(histogramType)->ToString();
390 }
391
392 void StatisticsImpl::setTickerCount(uint32_t tickerType, uint64_t count) {
393 {
394 MutexLock lock(&aggregate_lock_);
395 setTickerCountLocked(tickerType, count);
396 }
397 if (stats_ && tickerType < TICKER_ENUM_MAX) {
398 stats_->setTickerCount(tickerType, count);
399 }
400 }
401
402 void StatisticsImpl::setTickerCountLocked(uint32_t tickerType, uint64_t count) {
403 assert(tickerType < TICKER_ENUM_MAX);
404 for (size_t core_idx = 0; core_idx < per_core_stats_.Size(); ++core_idx) {
405 if (core_idx == 0) {
406 per_core_stats_.AccessAtCore(core_idx)->tickers_[tickerType] = count;
407 } else {
408 per_core_stats_.AccessAtCore(core_idx)->tickers_[tickerType] = 0;
409 }
410 }
411 }
412
413 uint64_t StatisticsImpl::getAndResetTickerCount(uint32_t tickerType) {
414 uint64_t sum = 0;
415 {
416 MutexLock lock(&aggregate_lock_);
417 assert(tickerType < TICKER_ENUM_MAX);
418 for (size_t core_idx = 0; core_idx < per_core_stats_.Size(); ++core_idx) {
419 sum +=
420 per_core_stats_.AccessAtCore(core_idx)->tickers_[tickerType].exchange(
421 0, std::memory_order_relaxed);
422 }
423 }
424 if (stats_ && tickerType < TICKER_ENUM_MAX) {
425 stats_->setTickerCount(tickerType, 0);
426 }
427 return sum;
428 }
429
430 void StatisticsImpl::recordTick(uint32_t tickerType, uint64_t count) {
431 if (get_stats_level() <= StatsLevel::kExceptTickers) {
432 return;
433 }
434 if (tickerType < TICKER_ENUM_MAX) {
435 per_core_stats_.Access()->tickers_[tickerType].fetch_add(
436 count, std::memory_order_relaxed);
437 if (stats_) {
438 stats_->recordTick(tickerType, count);
439 }
440 } else {
441 assert(false);
442 }
443 }
444
445 void StatisticsImpl::recordInHistogram(uint32_t histogramType, uint64_t value) {
446 assert(histogramType < HISTOGRAM_ENUM_MAX);
447 if (get_stats_level() <= StatsLevel::kExceptHistogramOrTimers) {
448 return;
449 }
450 per_core_stats_.Access()->histograms_[histogramType].Add(value);
451 if (stats_ && histogramType < HISTOGRAM_ENUM_MAX) {
452 stats_->recordInHistogram(histogramType, value);
453 }
454 }
455
456 Status StatisticsImpl::Reset() {
457 MutexLock lock(&aggregate_lock_);
458 for (uint32_t i = 0; i < TICKER_ENUM_MAX; ++i) {
459 setTickerCountLocked(i, 0);
460 }
461 for (uint32_t i = 0; i < HISTOGRAM_ENUM_MAX; ++i) {
462 for (size_t core_idx = 0; core_idx < per_core_stats_.Size(); ++core_idx) {
463 per_core_stats_.AccessAtCore(core_idx)->histograms_[i].Clear();
464 }
465 }
466 return Status::OK();
467 }
468
469 namespace {
470
471 // a buffer size used for temp string buffers
472 const int kTmpStrBufferSize = 200;
473
474 } // namespace
475
476 std::string StatisticsImpl::ToString() const {
477 MutexLock lock(&aggregate_lock_);
478 std::string res;
479 res.reserve(20000);
480 for (const auto& t : TickersNameMap) {
481 assert(t.first < TICKER_ENUM_MAX);
482 char buffer[kTmpStrBufferSize];
483 snprintf(buffer, kTmpStrBufferSize, "%s COUNT : %" PRIu64 "\n",
484 t.second.c_str(), getTickerCountLocked(t.first));
485 res.append(buffer);
486 }
487 for (const auto& h : HistogramsNameMap) {
488 assert(h.first < HISTOGRAM_ENUM_MAX);
489 char buffer[kTmpStrBufferSize];
490 HistogramData hData;
491 getHistogramImplLocked(h.first)->Data(&hData);
492 // don't handle failures - buffer should always be big enough and arguments
493 // should be provided correctly
494 int ret =
495 snprintf(buffer, kTmpStrBufferSize,
496 "%s P50 : %f P95 : %f P99 : %f P100 : %f COUNT : %" PRIu64
497 " SUM : %" PRIu64 "\n",
498 h.second.c_str(), hData.median, hData.percentile95,
499 hData.percentile99, hData.max, hData.count, hData.sum);
500 if (ret < 0 || ret >= kTmpStrBufferSize) {
501 assert(false);
502 continue;
503 }
504 res.append(buffer);
505 }
506 res.shrink_to_fit();
507 return res;
508 }
509
510 bool StatisticsImpl::getTickerMap(
511 std::map<std::string, uint64_t>* stats_map) const {
512 assert(stats_map);
513 if (!stats_map) return false;
514 stats_map->clear();
515 MutexLock lock(&aggregate_lock_);
516 for (const auto& t : TickersNameMap) {
517 assert(t.first < TICKER_ENUM_MAX);
518 (*stats_map)[t.second.c_str()] = getTickerCountLocked(t.first);
519 }
520 return true;
521 }
522
523 bool StatisticsImpl::HistEnabledForType(uint32_t type) const {
524 return type < HISTOGRAM_ENUM_MAX;
525 }
526
527 } // namespace ROCKSDB_NAMESPACE