rocksdb/statistics.rs
1use crate::ffi;
2
3#[derive(Debug, Clone)]
4pub struct NameParseError;
5impl core::fmt::Display for NameParseError {
6 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
7 write!(f, "unrecognized name")
8 }
9}
10
11impl std::error::Error for NameParseError {}
12
13// Helper macro to generate iterable nums that translate into static strings mapped from the cpp
14// land.
15macro_rules! iterable_named_enum {
16 (
17 $(#[$m:meta])*
18 $type_vis:vis enum $typename:ident {
19 $(
20 $(#[$variant_meta:meta])*
21 $variant:ident($variant_str:literal) $(= $value:expr)?,
22 )+
23 }
24 ) => {
25 // Main Type
26 #[allow(clippy::all)]
27 $(#[$m])*
28 $type_vis enum $typename {
29 $(
30 $(#[$variant_meta])*
31 $variant$( = $value)?,
32 )+
33 }
34
35 #[automatically_derived]
36 impl $typename {
37 #[doc = "The corresponding rocksdb string identifier for this variant"]
38 pub const fn name(&self) -> &'static str {
39 match self {
40 $(
41 $typename::$variant => $variant_str,
42 )+
43 }
44 }
45 pub fn iter() -> ::core::slice::Iter<'static, $typename> {
46 static VARIANTS: &'static [$typename] = &[
47 $(
48 $typename::$variant,
49 )+
50 ];
51 VARIANTS.iter()
52 }
53 }
54
55
56 #[automatically_derived]
57 impl ::core::str::FromStr for $typename {
58 type Err = NameParseError;
59 fn from_str(s: &str) -> Result<Self, Self::Err> {
60 match s {
61 $(
62 $variant_str => Ok($typename::$variant),
63 )+
64 _ => Err(NameParseError),
65 }
66 }
67 }
68
69 #[automatically_derived]
70 impl ::core::fmt::Display for $typename {
71 fn fmt(&self, f: &mut ::core::fmt::Formatter<'_>) -> ::core::fmt::Result {
72 self.name().fmt(f)
73 }
74 }
75 };
76}
77
78/// StatsLevel can be used to reduce statistics overhead by skipping certain
79/// types of stats in the stats collection process.
80#[derive(Debug, Copy, Clone, PartialEq, Eq)]
81#[repr(u8)]
82pub enum StatsLevel {
83 /// Disable all metrics
84 DisableAll = 0,
85 /// Disable timer stats, and skip histogram stats
86 ExceptHistogramOrTimers = 2,
87 /// Skip timer stats
88 ExceptTimers,
89 /// Collect all stats except time inside mutex lock AND time spent on
90 /// compression.
91 ExceptDetailedTimers,
92 /// Collect all stats except the counters requiring to get time inside the
93 /// mutex lock.
94 ExceptTimeForMutex,
95 /// Collect all stats, including measuring duration of mutex operations.
96 /// If getting time is expensive on the platform to run, it can
97 /// reduce scalability to more threads, especially for writes.
98 All,
99}
100
101// Keep in-sync with rocksdb/include/rocksdb/statistics.h
102iterable_named_enum! {
103 #[derive(Debug, Copy, Clone, PartialEq, Eq)]
104 #[repr(u32)]
105 pub enum Ticker {
106 /// total block cache misses
107 /// REQUIRES: BlockCacheMiss == BlockCacheIndexMiss +
108 /// BlockCacheFilterMiss +
109 /// BlockCacheDataMiss;
110 BlockCacheMiss("rocksdb.block.cache.miss") = 0,
111 /// total block cache hit
112 /// REQUIRES: BlockCacheHit == BlockCacheIndexHit +
113 /// BlockCacheFilterHit +
114 /// BlockCacheDataHit;
115 BlockCacheHit("rocksdb.block.cache.hit"),
116 /// # of blocks added to block cache.
117 BlockCacheAdd("rocksdb.block.cache.add"),
118 /// # of failures when adding blocks to block cache.
119 BlockCacheAddFailures("rocksdb.block.cache.add.failures"),
120 /// # of times cache miss when accessing index block from block cache.
121 BlockCacheIndexMiss("rocksdb.block.cache.index.miss"),
122 /// # of times cache hit when accessing index block from block cache.
123 BlockCacheIndexHit("rocksdb.block.cache.index.hit"),
124 /// # of index blocks added to block cache.
125 BlockCacheIndexAdd("rocksdb.block.cache.index.add"),
126 /// # of bytes of index blocks inserted into cache
127 BlockCacheIndexBytesInsert("rocksdb.block.cache.index.bytes.insert"),
128 /// # of times cache miss when accessing filter block from block cache.
129 BlockCacheFilterMiss("rocksdb.block.cache.filter.miss"),
130 /// # of times cache hit when accessing filter block from block cache.
131 BlockCacheFilterHit("rocksdb.block.cache.filter.hit"),
132 /// # of filter blocks added to block cache.
133 BlockCacheFilterAdd("rocksdb.block.cache.filter.add"),
134 /// # of bytes of bloom filter blocks inserted into cache
135 BlockCacheFilterBytesInsert("rocksdb.block.cache.filter.bytes.insert"),
136 /// # of times cache miss when accessing data block from block cache.
137 BlockCacheDataMiss("rocksdb.block.cache.data.miss"),
138 /// # of times cache hit when accessing data block from block cache.
139 BlockCacheDataHit("rocksdb.block.cache.data.hit"),
140 /// # of data blocks added to block cache.
141 BlockCacheDataAdd("rocksdb.block.cache.data.add"),
142 /// # of bytes of data blocks inserted into cache
143 BlockCacheDataBytesInsert("rocksdb.block.cache.data.bytes.insert"),
144 /// # of bytes read from cache.
145 BlockCacheBytesRead("rocksdb.block.cache.bytes.read"),
146 /// # of bytes written into cache.
147 BlockCacheBytesWrite("rocksdb.block.cache.bytes.write"),
148
149 /// # of times bloom filter has avoided file reads, i.e., negatives.
150 BloomFilterUseful("rocksdb.bloom.filter.useful"),
151 /// # of times bloom FullFilter has not avoided the reads.
152 BloomFilterFullPositive("rocksdb.bloom.filter.full.positive"),
153 /// # of times bloom FullFilter has not avoided the reads and data actually
154 /// exist.
155 BloomFilterFullTruePositive("rocksdb.bloom.filter.full.true.positive"),
156
157 /// # persistent cache hit
158 PersistentCacheHit("rocksdb.persistent.cache.hit"),
159 /// # persistent cache miss
160 PersistentCacheMiss("rocksdb.persistent.cache.miss"),
161
162 /// # total simulation block cache hits
163 SimBlockCacheHit("rocksdb.sim.block.cache.hit"),
164 /// # total simulation block cache misses
165 SimBlockCacheMiss("rocksdb.sim.block.cache.miss"),
166
167 /// # of memtable hits.
168 MemtableHit("rocksdb.memtable.hit"),
169 /// # of memtable misses.
170 MemtableMiss("rocksdb.memtable.miss"),
171
172 /// # of Get() queries served by L0
173 GetHitL0("rocksdb.l0.hit"),
174 /// # of Get() queries served by L1
175 GetHitL1("rocksdb.l1.hit"),
176 /// # of Get() queries served by L2 and up
177 GetHitL2AndUp("rocksdb.l2andup.hit"),
178
179 /**
180 * Compaction_KeyDrop* count the reasons for key drop during compaction
181 * There are 4 reasons currently.
182 */
183 CompactionKeyDropNewerEntry("rocksdb.compaction.key.drop.new"),
184 /// key was written with a newer value.
185 /// Also includes keys dropped for range del.
186 CompactionKeyDropObsolete("rocksdb.compaction.key.drop.obsolete"),
187 /// The key is obsolete.
188 CompactionKeyDropRangeDel("rocksdb.compaction.key.drop.range_del"),
189 /// key was covered by a range tombstone.
190 CompactionKeyDropUser("rocksdb.compaction.key.drop.user"),
191 /// user compaction function has dropped the key.
192 CompactionRangeDelDropObsolete("rocksdb.compaction.range_del.drop.obsolete"),
193 /// all keys in range were deleted.
194 /// Deletions obsoleted before bottom level due to file gap optimization.
195 CompactionOptimizedDelDropObsolete("rocksdb.compaction.optimized.del.drop.obsolete"),
196 /// If a compaction was canceled in sfm to prevent ENOSPC
197 CompactionCancelled("rocksdb.compaction.cancelled"),
198
199 /// Number of keys written to the database via the Put and Write call's
200 NumberKeysWritten("rocksdb.number.keys.written"),
201 /// Number of Keys read,
202 NumberKeysRead("rocksdb.number.keys.read"),
203 /// Number keys updated, if inplace update is enabled
204 NumberKeysUpdated("rocksdb.number.keys.updated"),
205 /// The number of uncompressed bytes issued by DB::Put(), DB::Delete(),
206 /// DB::Merge(), and DB::Write().
207 BytesWritten("rocksdb.bytes.written"),
208 /// The number of uncompressed bytes read from DB::Get(). It could be
209 /// either from memtables, cache, or table files.
210 /// For the number of logical bytes read from DB::MultiGet(),
211 /// please use NumberMultigetBytesRead.
212 BytesRead("rocksdb.bytes.read"),
213 /// The number of calls to seek/next/prev
214 NumberDbSeek("rocksdb.number.db.seek"),
215 NumberDbNext("rocksdb.number.db.next"),
216 NumberDbPrev("rocksdb.number.db.prev"),
217 /// The number of calls to seek/next/prev that returned data
218 NumberDbSeekFound("rocksdb.number.db.seek.found"),
219 NumberDbNextFound("rocksdb.number.db.next.found"),
220 NumberDbPrevFound("rocksdb.number.db.prev.found"),
221 /// The number of uncompressed bytes read from an iterator.
222 /// Includes size of key and value.
223 IterBytesRead("rocksdb.db.iter.bytes.read"),
224 NoFileOpens("rocksdb.no.file.opens"),
225 NoFileErrors("rocksdb.no.file.errors"),
226 /// Writer has to wait for compaction or flush to finish.
227 StallMicros("rocksdb.stall.micros"),
228 /// The wait time for db mutex.
229 /// Disabled by default. To enable it set stats level to kAll
230 DbMutexWaitMicros("rocksdb.db.mutex.wait.micros"),
231
232 /// Number of MultiGet calls, keys read, and bytes read
233 NumberMultigetCalls("rocksdb.number.multiget.get"),
234 NumberMultigetKeysRead("rocksdb.number.multiget.keys.read"),
235 NumberMultigetBytesRead("rocksdb.number.multiget.bytes.read"),
236
237 NumberMergeFailures("rocksdb.number.merge.failures"),
238
239 /// Prefix filter stats when used for point lookups (Get / MultiGet).
240 /// (For prefix filter stats on iterators, see *_LEVEL_Seek_*.)
241 /// Checked: filter was queried
242 BloomFilterPrefixChecked("rocksdb.bloom.filter.prefix.checked"),
243 /// Useful: filter returned false so prevented accessing data+index blocks
244 BloomFilterPrefixUseful("rocksdb.bloom.filter.prefix.useful"),
245 /// True positive: found a key matching the point query. When another key
246 /// with the same prefix matches, it is considered a false positive by
247 /// these statistics even though the filter returned a true positive.
248 BloomFilterPrefixTruePositive("rocksdb.bloom.filter.prefix.true.positive"),
249
250 /// Number of times we had to reseek inside an iteration to skip
251 /// over large number of keys with same userkey.
252 NumberOfReseeksInIteration("rocksdb.number.reseeks.iteration"),
253
254 /// Record the number of calls to GetUpdatesSince. Useful to keep track of
255 /// transaction log iterator refreshes
256 GetUpdatesSinceCalls("rocksdb.getupdatessince.calls"),
257 /// Number of times WAL sync is done
258 WalFileSynced("rocksdb.wal.synced"),
259 /// Number of bytes written to WAL
260 WalFileBytes("rocksdb.wal.bytes"),
261
262 /// Writes can be processed by requesting thread or by the thread at the
263 /// head of the writers queue.
264 WriteDoneBySelf("rocksdb.write.self"),
265 WriteDoneByOther("rocksdb.write.other"),
266 /// Equivalent to writes done for others
267 WriteWithWal("rocksdb.write.wal"),
268 /// Number of Write calls that request WAL
269 CompactReadBytes("rocksdb.compact.read.bytes"),
270 /// Bytes read during compaction
271 CompactWriteBytes("rocksdb.compact.write.bytes"),
272 /// Bytes written during compaction
273 FlushWriteBytes("rocksdb.flush.write.bytes"),
274 /// Bytes written during flush
275
276 /// Compaction read and write statistics broken down by CompactionReason
277 CompactReadBytesMarked("rocksdb.compact.read.marked.bytes"),
278 CompactReadBytesPeriodic("rocksdb.compact.read.periodic.bytes"),
279 CompactReadBytesTtl("rocksdb.compact.read.ttl.bytes"),
280 CompactWriteBytesMarked("rocksdb.compact.write.marked.bytes"),
281 CompactWriteBytesPeriodic("rocksdb.compact.write.periodic.bytes"),
282 CompactWriteBytesTtl("rocksdb.compact.write.ttl.bytes"),
283
284 /// Number of table's properties loaded directly from file, without creating
285 /// table reader object.
286 NumberDirectLoadTableProperties("rocksdb.number.direct.load.table.properties"),
287 NumberSuperversionAcquires("rocksdb.number.superversion_acquires"),
288 NumberSuperversionReleases("rocksdb.number.superversion_releases"),
289 NumberSuperversionCleanups("rocksdb.number.superversion_cleanups"),
290
291 /// # of compressions/decompressions executed
292 NumberBlockCompressed("rocksdb.number.block.compressed"),
293 NumberBlockDecompressed("rocksdb.number.block.decompressed"),
294
295 /// DEPRECATED / unused (see NumberBlockCompression_*)
296 NumberBlockNotCompressed("rocksdb.number.block.not_compressed"),
297
298 /// Tickers that record cumulative time.
299 MergeOperationTotalTime("rocksdb.merge.operation.time.nanos"),
300 FilterOperationTotalTime("rocksdb.filter.operation.time.nanos"),
301 CompactionCpuTotalTime("rocksdb.compaction.total.time.cpu_micros"),
302
303 /// Row cache.
304 RowCacheHit("rocksdb.row.cache.hit"),
305 RowCacheMiss("rocksdb.row.cache.miss"),
306
307 /// Read amplification statistics.
308 /// Read amplification can be calculated using this formula
309 /// (ReadAMP_ToTAL_ReadBytes / Read_AMP_Estimate_UsefulBytes)
310 //
311 /// REQUIRES: ReadOptions::read_amp_bytes_per_bit to be enabled
312 ReadAmpEstimateUsefulBytes("rocksdb.read.amp.estimate.useful.bytes"),
313 /// Estimate of total bytes actually used.
314 ReadAmpTotalReadBytes("rocksdb.read.amp.total.read.bytes"),
315 /// Total size of loaded data blocks.
316
317 /// Number of refill intervals where rate limiter's bytes are fully consumed.
318 NumberRateLimiterDrains("rocksdb.number.rate_limiter.drains"),
319
320 /// Number of internal keys skipped by Iterator
321 NumberIterSkip("rocksdb.number.iter.skip"),
322
323 /// BlobDB specific stats
324 /// # of Put/PutTtl/PutUntil to BlobDB. Only applicable to legacy BlobDB.
325 BlobDbNumPut("rocksdb.blobdb.num.put"),
326 /// # of Write to BlobDB. Only applicable to legacy BlobDB.
327 BlobDbNumWrite("rocksdb.blobdb.num.write"),
328 /// # of Get to BlobDB. Only applicable to legacy BlobDB.
329 BlobDbNumGet("rocksdb.blobdb.num.get"),
330 /// # of MultiGet to BlobDB. Only applicable to legacy BlobDB.
331 BlobDbNumMultiget("rocksdb.blobdb.num.multiget"),
332 /// # of Seek/SeekToFirst/SeekToLast/SeekForPrev to BlobDB iterator. Only
333 /// applicable to legacy BlobDB.
334 BlobDbNumSeek("rocksdb.blobdb.num.seek"),
335 /// # of Next to BlobDB iterator. Only applicable to legacy BlobDB.
336 BlobDbNumNext("rocksdb.blobdb.num.next"),
337 /// # of Prev to BlobDB iterator. Only applicable to legacy BlobDB.
338 BlobDbNumPrev("rocksdb.blobdb.num.prev"),
339 /// # of keys written to BlobDB. Only applicable to legacy BlobDB.
340 BlobDbNumKeysWritten("rocksdb.blobdb.num.keys.written"),
341 /// # of keys read from BlobDB. Only applicable to legacy BlobDB.
342 BlobDbNumKeysRead("rocksdb.blobdb.num.keys.read"),
343 /// # of bytes (key + value) written to BlobDB. Only applicable to legacy
344 /// BlobDB.
345 BlobDbBytesWritten("rocksdb.blobdb.bytes.written"),
346 /// # of bytes (keys + value) read from BlobDB. Only applicable to legacy
347 /// BlobDB.
348 BlobDbBytesRead("rocksdb.blobdb.bytes.read"),
349 /// # of keys written by BlobDB as non-Ttl inlined value. Only applicable to
350 /// legacy BlobDB.
351 BlobDbWriteInlined("rocksdb.blobdb.write.inlined"),
352 /// # of keys written by BlobDB as Ttl inlined value. Only applicable to legacy
353 /// BlobDB.
354 BlobDbWriteInlinedTtl("rocksdb.blobdb.write.inlined.ttl"),
355 /// # of keys written by BlobDB as non-Ttl blob value. Only applicable to
356 /// legacy BlobDB.
357 BlobDbWriteBlob("rocksdb.blobdb.write.blob"),
358 /// # of keys written by BlobDB as Ttl blob value. Only applicable to legacy
359 /// BlobDB.
360 BlobDbWriteBlobTtl("rocksdb.blobdb.write.blob.ttl"),
361 /// # of bytes written to blob file.
362 BlobDbBlobFileBytesWritten("rocksdb.blobdb.blob.file.bytes.written"),
363 /// # of bytes read from blob file.
364 BlobDbBlobFileBytesRead("rocksdb.blobdb.blob.file.bytes.read"),
365 /// # of times a blob files being synced.
366 BlobDbBlobFileSynced("rocksdb.blobdb.blob.file.synced"),
367 /// # of blob index evicted from base DB by BlobDB compaction filter because
368 /// of expiration. Only applicable to legacy BlobDB.
369 BlobDbBlobIndexExpiredCount("rocksdb.blobdb.blob.index.expired.count"),
370 /// size of blob index evicted from base DB by BlobDB compaction filter
371 /// because of expiration. Only applicable to legacy BlobDB.
372 BlobDbBlobIndexExpiredSize("rocksdb.blobdb.blob.index.expired.size"),
373 /// # of blob index evicted from base DB by BlobDB compaction filter because
374 /// of corresponding file deleted. Only applicable to legacy BlobDB.
375 BlobDbBlobIndexEvictedCount("rocksdb.blobdb.blob.index.evicted.count"),
376 /// size of blob index evicted from base DB by BlobDB compaction filter
377 /// because of corresponding file deleted. Only applicable to legacy BlobDB.
378 BlobDbBlobIndexEvictedSize("rocksdb.blobdb.blob.index.evicted.size"),
379 /// # of blob files that were obsoleted by garbage collection. Only applicable
380 /// to legacy BlobDB.
381 BlobDbGcNumFiles("rocksdb.blobdb.gc.num.files"),
382 /// # of blob files generated by garbage collection. Only applicable to legacy
383 /// BlobDB.
384 BlobDbGcNumNewFiles("rocksdb.blobdb.gc.num.new.files"),
385 /// # of BlobDB garbage collection failures. Only applicable to legacy BlobDB.
386 BlobDbGcFailures("rocksdb.blobdb.gc.failures"),
387 /// # of keys relocated to new blob file by garbage collection.
388 BlobDbGcNumKeysRelocated("rocksdb.blobdb.gc.num.keys.relocated"),
389 /// # of bytes relocated to new blob file by garbage collection.
390 BlobDbGcBytesRelocated("rocksdb.blobdb.gc.bytes.relocated"),
391 /// # of blob files evicted because of BlobDB is full. Only applicable to
392 /// legacy BlobDB.
393 BlobDbFifoNumFilesEvicted("rocksdb.blobdb.fifo.num.files.evicted"),
394 /// # of keys in the blob files evicted because of BlobDB is full. Only
395 /// applicable to legacy BlobDB.
396 BlobDbFifoNumKeysEvicted("rocksdb.blobdb.fifo.num.keys.evicted"),
397 /// # of bytes in the blob files evicted because of BlobDB is full. Only
398 /// applicable to legacy BlobDB.
399 BlobDbFifoBytesEvicted("rocksdb.blobdb.fifo.bytes.evicted"),
400
401 /// These counters indicate a performance issue in WritePrepared transactions.
402 /// We should not seem them ticking them much.
403 /// # of times prepare_mutex_ is acquired in the fast path.
404 TxnPrepareMutexOverhead("rocksdb.txn.overhead.mutex.prepare"),
405 /// # of times old_commit_map_mutex_ is acquired in the fast path.
406 TxnOldCommitMapMutexOverhead("rocksdb.txn.overhead.mutex.old.commit.map"),
407 /// # of times we checked a batch for duplicate keys.
408 TxnDuplicateKeyOverhead("rocksdb.txn.overhead.duplicate.key"),
409 /// # of times snapshot_mutex_ is acquired in the fast path.
410 TxnSnapshotMutexOverhead("rocksdb.txn.overhead.mutex.snapshot"),
411 /// # of times ::Get returned TryAgain due to expired snapshot seq
412 TxnGetTryAgain("rocksdb.txn.get.tryagain"),
413
414 /// Number of keys actually found in MultiGet calls (vs number requested by
415 /// caller)
416 /// NumberMultigetKeys_Read gives the number requested by caller
417 NumberMultigetKeysFound("rocksdb.number.multiget.keys.found"),
418
419 NoIteratorCreated("rocksdb.num.iterator.created"),
420 /// number of iterators created
421 NoIteratorDeleted("rocksdb.num.iterator.deleted"),
422 /// number of iterators deleted
423 BlockCacheCompressionDictMiss("rocksdb.block.cache.compression.dict.miss"),
424 BlockCacheCompressionDictHit("rocksdb.block.cache.compression.dict.hit"),
425 BlockCacheCompressionDictAdd("rocksdb.block.cache.compression.dict.add"),
426 BlockCacheCompressionDictBytesInsert("rocksdb.block.cache.compression.dict.bytes.insert"),
427
428 /// # of blocks redundantly inserted into block cache.
429 /// REQUIRES: BlockCacheAddRedundant <= BlockCacheAdd
430 BlockCacheAddRedundant("rocksdb.block.cache.add.redundant"),
431 /// # of index blocks redundantly inserted into block cache.
432 /// REQUIRES: BlockCacheIndexAddRedundant <= BlockCacheIndexAdd
433 BlockCacheIndexAddRedundant("rocksdb.block.cache.index.add.redundant"),
434 /// # of filter blocks redundantly inserted into block cache.
435 /// REQUIRES: BlockCacheFilterAddRedundant <= BlockCacheFilterAdd
436 BlockCacheFilterAddRedundant("rocksdb.block.cache.filter.add.redundant"),
437 /// # of data blocks redundantly inserted into block cache.
438 /// REQUIRES: BlockCacheDataAddRedundant <= BlockCacheDataAdd
439 BlockCacheDataAddRedundant("rocksdb.block.cache.data.add.redundant"),
440 /// # of dict blocks redundantly inserted into block cache.
441 /// REQUIRES: BlockCacheCompressionDictAddRedundant
442 /// <= BlockCacheCompressionDictAdd
443 BlockCacheCompressionDictAddRedundant("rocksdb.block.cache.compression.dict.add.redundant"),
444
445 /// # of files marked as trash by sst file manager and will be deleted
446 /// later by background thread.
447 FilesMarkedTrash("rocksdb.files.marked.trash"),
448 /// # of trash files deleted by the background thread from the trash queue.
449 FilesDeletedFromTrashQueue("rocksdb.files.marked.trash.deleted"),
450 /// # of files deleted immediately by sst file manager through delete
451 /// scheduler.
452 FilesDeletedImmediately("rocksdb.files.deleted.immediately"),
453
454 /// The counters for error handler, not that, bg_io_error is the subset of
455 /// bg_error and bg_retryable_io_error is the subset of bg_io_error.
456 /// The misspelled versions are deprecated and only kept for compatibility.
457 /// ToDO: remove the misspelled tickers in the next major release.
458 ErrorHandlerBgErrorCount("rocksdb.error.handler.bg.error.count"),
459 ErrorHandlerBgErrorCountMisspelled("rocksdb.error.handler.bg.errro.count"),
460 ErrorHandlerBgIoErrorCount("rocksdb.error.handler.bg.io.error.count"),
461 ErrorHandlerBgIoErrorCountMisspelled("rocksdb.error.handler.bg.io.errro.count"),
462 ErrorHandlerBgRetryableIoErrorCount("rocksdb.error.handler.bg.retryable.io.error.count"),
463 ErrorHandlerBgRetryableIoErrorCountMisspelled("rocksdb.error.handler.bg.retryable.io.errro.count"),
464 ErrorHandlerAutoResumeCount("rocksdb.error.handler.autoresume.count"),
465 ErrorHandlerAutoResumeRetryTotalCount("rocksdb.error.handler.autoresume.retry.total.count"),
466 ErrorHandlerAutoResumeSuccessCount("rocksdb.error.handler.autoresume.success.count"),
467
468 /// Statistics for memtable garbage collection:
469 /// Raw bytes of data (payload) present on memtable at flush time.
470 MemtablePayloadBytesAtFlush("rocksdb.memtable.payload.bytes.at.flush"),
471 /// Outdated bytes of data present on memtable at flush time.
472 MemtableGarbageBytesAtFlush("rocksdb.memtable.garbage.bytes.at.flush"),
473
474 /// Secondary cache statistics
475 SecondaryCacheHits("rocksdb.secondary.cache.hits"),
476
477 /// Bytes read by `VerifyChecksum()` and `VerifyFileChecksums()` APIs.
478 VerifyChecksumReadBytes("rocksdb.verify_checksum.read.bytes"),
479
480 /// Bytes read/written while creating backups
481 BackupReadBytes("rocksdb.backup.read.bytes"),
482 BackupWriteBytes("rocksdb.backup.write.bytes"),
483
484 /// Remote compaction read/write statistics
485 RemoteCompactReadBytes("rocksdb.remote.compact.read.bytes"),
486 RemoteCompactWriteBytes("rocksdb.remote.compact.write.bytes"),
487
488 /// Tiered storage related statistics
489 HotFileReadBytes("rocksdb.hot.file.read.bytes"),
490 WarmFileReadBytes("rocksdb.warm.file.read.bytes"),
491 ColdFileReadBytes("rocksdb.cold.file.read.bytes"),
492 HotFileReadCount("rocksdb.hot.file.read.count"),
493 WarmFileReadCount("rocksdb.warm.file.read.count"),
494 ColdFileReadCount("rocksdb.cold.file.read.count"),
495
496 /// Last level and non-last level read statistics
497 LastLevelReadBytes("rocksdb.last.level.read.bytes"),
498 LastLevelReadCount("rocksdb.last.level.read.count"),
499 NonLastLevelReadBytes("rocksdb.non.last.level.read.bytes"),
500 NonLastLevelReadCount("rocksdb.non.last.level.read.count"),
501
502 /// Statistics on iterator Seek() (and variants) for each sorted run. I.e. a
503 /// single user Seek() can result in many sorted run Seek()s.
504 /// The stats are split between last level and non-last level.
505 /// Filtered: a filter such as prefix Bloom filter indicate the Seek() would
506 /// not find anything relevant, so avoided a likely access to data+index
507 /// blocks.
508 LastLevelSeekFiltered("rocksdb.last.level.seek.filtered"),
509 /// Filter match: a filter such as prefix Bloom filter was queried but did
510 /// not filter out the seek.
511 LastLevelSeekFilterMatch("rocksdb.last.level.seek.filter.match"),
512 /// At least one data block was accessed for a Seek() (or variant) on a
513 /// sorted run.
514 LastLevelSeekData("rocksdb.last.level.seek.data"),
515 /// At least one value() was accessed for the seek (suggesting it was useful),
516 /// and no filter such as prefix Bloom was queried.
517 LastLevelSeekDataUsefulNoFilter("rocksdb.last.level.seek.data.useful.no.filter"),
518 /// At least one value() was accessed for the seek (suggesting it was useful),
519 /// after querying a filter such as prefix Bloom.
520 LastLevelSeekDataUsefulFilterMatch("rocksdb.last.level.seek.data.useful.filter.match"),
521 /// The same set of stats, but for non-last level seeks.
522 NonLastLevelSeekFiltered("rocksdb.non.last.level.seek.filtered"),
523 NonLastLevelSeekFilterMatch("rocksdb.non.last.level.seek.filter.match"),
524 NonLastLevelSeekData("rocksdb.non.last.level.seek.data"),
525 NonLastLevelSeekDataUsefulNoFilter("rocksdb.non.last.level.seek.data.useful.no.filter"),
526 NonLastLevelSeekDataUsefulFilterMatch("rocksdb.non.last.level.seek.data.useful.filter.match"),
527
528 /// Number of block checksum verifications
529 BlockChecksumComputeCount("rocksdb.block.checksum.compute.count"),
530 /// Number of times RocksDB detected a corruption while verifying a block
531 /// checksum. RocksDB does not remember corruptions that happened during user
532 /// reads so the same block corruption may be detected multiple times.
533 BlockChecksumMismatchCount("rocksdb.block.checksum.mismatch.count"),
534
535 MultigetCoroutineCount("rocksdb.multiget.coroutine.count"),
536
537 /// Integrated BlobDB specific stats
538 /// # of times cache miss when accessing blob from blob cache.
539 BlobDbCacheMiss("rocksdb.blobdb.cache.miss"),
540 /// # of times cache hit when accessing blob from blob cache.
541 BlobDbCacheHit("rocksdb.blobdb.cache.hit"),
542 /// # of data blocks added to blob cache.
543 BlobDbCacheAdd("rocksdb.blobdb.cache.add"),
544 /// # of failures when adding blobs to blob cache.
545 BlobDbCacheAddFailures("rocksdb.blobdb.cache.add.failures"),
546 /// # of bytes read from blob cache.
547 BlobDbCacheBytesRead("rocksdb.blobdb.cache.bytes.read"),
548 /// # of bytes written into blob cache.
549 BlobDbCacheBytesWrite("rocksdb.blobdb.cache.bytes.write"),
550
551 /// Time spent in the ReadAsync file system call
552 ReadAsyncMicros("rocksdb.read.async.micros"),
553 /// Number of errors returned to the async read callback
554 AsyncReadErrorCount("rocksdb.async.read.error.count"),
555
556 /// Fine grained secondary cache stats
557 SecondaryCacheFilterHits("rocksdb.secondary.cache.filter.hits"),
558 SecondaryCacheIndexHits("rocksdb.secondary.cache.index.hits"),
559 SecondaryCacheDataHits("rocksdb.secondary.cache.data.hits"),
560
561 /// Number of lookup into the prefetched tail (see
562 /// `TableOpenPrefetchTailReadBytes`)
563 /// that can't find its data for table open
564 TableOpenPrefetchTailMiss("rocksdb.table.open.prefetch.tail.miss"),
565 /// Number of lookup into the prefetched tail (see
566 /// `TableOpenPrefetchTailReadBytes`)
567 /// that finds its data for table open
568 TableOpenPrefetchTailHit("rocksdb.table.open.prefetch.tail.hit"),
569
570 /// Statistics on the filtering by user-defined timestamps
571 /// # of times timestamps are checked on accessing the table
572 TimestampFilterTableChecked("rocksdb.timestamp.filter.table.checked"),
573 /// # of times timestamps can successfully help skip the table access
574 TimestampFilterTableFiltered("rocksdb.timestamp.filter.table.filtered"),
575
576 /// Number of input bytes (uncompressed) to compression for SST blocks that
577 /// are stored compressed.
578 BytesCompressedFrom("rocksdb.bytes.compressed.from"),
579 /// Number of output bytes (compressed) from compression for SST blocks that
580 /// are stored compressed.
581 BytesCompressedTo("rocksdb.bytes.compressed.to"),
582 /// Number of uncompressed bytes for SST blocks that are stored uncompressed
583 /// because compression type is kNoCompression, or some error case caused
584 /// compression not to run or produce an output. Index blocks are only counted
585 /// if enable_index_compression is true.
586 BytesCompressionBypassed("rocksdb.bytes.compression_bypassed"),
587 /// Number of input bytes (uncompressed) to compression for SST blocks that
588 /// are stored uncompressed because the compression result was rejected,
589 /// either because the ratio was not acceptable (see
590 /// CompressionOptions::max_compressed_bytes_per_kb) or found invalid by the
591 /// `verify_compression` option.
592 BytesCompressionRejected("rocksdb.bytes.compression.rejected"),
593
594 /// Like BytesCompressionBypassed but counting number of blocks
595 NumberBlockCompressionBypassed("rocksdb.number.block_compression_bypassed"),
596 /// Like BytesCompressionRejected but counting number of blocks
597 NumberBlockCompressionRejected("rocksdb.number.block_compression_rejected"),
598
599 /// Number of input bytes (compressed) to decompression in reading compressed
600 /// SST blocks from storage.
601 BytesDecompressedFrom("rocksdb.bytes.decompressed.from"),
602 /// Number of output bytes (uncompressed) from decompression in reading
603 /// compressed SST blocks from storage.
604 BytesDecompressedTo("rocksdb.bytes.decompressed.to"),
605
606 /// Number of times readahead is trimmed during scans when
607 /// ReadOptions.auto_readahead_size is set.
608 ReadAheadTrimmed("rocksdb.readahead.trimmed"),
609
610 /// Number of Fifo compactions that drop files based on different reasons
611 FifoMaxSizeCompactions("rocksdb.fifo.max.size.compactions"),
612 FifoTtlCompactions("rocksdb.fifo.ttl.compactions"),
613
614 /// Number of bytes prefetched during user initiated scan
615 PrefetchBytes("rocksdb.prefetch.bytes"),
616
617 /// Number of prefetched bytes that were actually useful
618 PrefetchBytesUseful("rocksdb.prefetch.bytes.useful"),
619
620 /// Number of FS reads avoided due to scan prefetching
621 PrefetchHits("rocksdb.prefetch.hits"),
622
623 /// Compressed secondary cache related stats
624 CompressedSecondaryCacheDummyHits("rocksdb.compressed.secondary.cache.dummy.hits"),
625 CompressedSecondaryCacheHits("rocksdb.compressed.secondary.cache.hits"),
626 CompressedSecondaryCachePromotions("rocksdb.compressed.secondary.cache.promotions"),
627 CompressedSecondaryCachePromotionSkips("rocksdb.compressed.secondary.cache.promotion.skips"),
628 }
629}
630
631iterable_named_enum! {
632 #[derive(Debug, Copy, Clone, PartialEq, Eq)]
633 #[repr(u32)]
634 pub enum Histogram {
635 DbGet("rocksdb.db.get.micros") = 0,
636 DbWrite("rocksdb.db.write.micros"),
637 CompactionTime("rocksdb.compaction.times.micros"),
638 CompactionCpuTime("rocksdb.compaction.times.cpu_micros"),
639 SubcompactionSetupTime("rocksdb.subcompaction.setup.times.micros"),
640 TableSyncMicros("rocksdb.table.sync.micros"),
641 CompactionOutfileSyncMicros("rocksdb.compaction.outfile.sync.micros"),
642 WalFileSyncMicros("rocksdb.wal.file.sync.micros"),
643 ManifestFileSyncMicros("rocksdb.manifest.file.sync.micros"),
644 /// Time spent in IO during table open
645 TableOpenIoMicros("rocksdb.table.open.io.micros"),
646 DbMultiget("rocksdb.db.multiget.micros"),
647 ReadBlockCompactionMicros("rocksdb.read.block.compaction.micros"),
648 ReadBlockGetMicros("rocksdb.read.block.get.micros"),
649 WriteRawBlockMicros("rocksdb.write.raw.block.micros"),
650 NumFilesInSingleCompaction("rocksdb.numfiles.in.singlecompaction"),
651 DbSeek("rocksdb.db.seek.micros"),
652 WriteStall("rocksdb.db.write.stall"),
653 /// Time spent in reading block-based or plain SST table
654 SstReadMicros("rocksdb.sst.read.micros"),
655 /// Time spent in reading SST table (currently only block-based table) or blob
656 /// file corresponding to `Env::IOActivity`
657 FileReadFlushMicros("rocksdb.file.read.flush.micros"),
658 FileReadCompactionMicros("rocksdb.file.read.compaction.micros"),
659 FileReadDbOpenMicros("rocksdb.file.read.db.open.micros"),
660 /// The following `FILE_READ_*` require stats level greater than
661 /// `StatsLevel::kExceptDetailedTimers`
662 FileReadGetMicros("rocksdb.file.read.get.micros"),
663 FileReadMultigetMicros("rocksdb.file.read.multiget.micros"),
664 FileReadDbIteratorMicros("rocksdb.file.read.db.iterator.micros"),
665 FileReadVerifyDbChecksumMicros("rocksdb.file.read.verify.db.checksum.micros"),
666 FileReadVerifyFileChecksumsMicros("rocksdb.file.read.verify.file.checksums.micros"),
667 /// The number of subcompactions actually scheduled during a compaction
668 NumSubcompactionsScheduled("rocksdb.num.subcompactions.scheduled"),
669 /// Value size distribution in each operation
670 BytesPerRead("rocksdb.bytes.per.read"),
671 BytesPerWrite("rocksdb.bytes.per.write"),
672 BytesPerMultiget("rocksdb.bytes.per.multiget"),
673 BytesCompressed("rocksdb.bytes.compressed"),
674 /// DEPRECATED / unused (see BytesCompressed{From,To})
675 BytesDecompressed("rocksdb.bytes.decompressed"),
676 /// DEPRECATED / unused (see BytesDecompressed{From,To})
677 CompressionTimesNanos("rocksdb.compression.times.nanos"),
678 DecompressionTimesNanos("rocksdb.decompression.times.nanos"),
679 /// Number of merge operands passed to the merge operator in user read
680 /// requests.
681 ReadNumMergeOperands("rocksdb.read.num.merge_operands"),
682 /// BlobDB specific stats
683 /// Size of keys written to BlobDB. Only applicable to legacy BlobDB.
684 BlobDbKeySize("rocksdb.blobdb.key.size"),
685 /// Size of values written to BlobDB. Only applicable to legacy BlobDB.
686 BlobDbValueSize("rocksdb.blobdb.value.size"),
687 /// BlobDB Put/PutWithTTL/PutUntil/Write latency. Only applicable to legacy
688 /// BlobDB.
689 BlobDbWriteMicros("rocksdb.blobdb.write.micros"),
690 /// BlobDB Get latency. Only applicable to legacy BlobDB.
691 BlobDbGetMicros("rocksdb.blobdb.get.micros"),
692 /// BlobDB MultiGet latency. Only applicable to legacy BlobDB.
693 BlobDbMultigetMicros("rocksdb.blobdb.multiget.micros"),
694 /// BlobDB Seek/SeekToFirst/SeekToLast/SeekForPrev latency. Only applicable to
695 /// legacy BlobDB.
696 BlobDbSeekMicros("rocksdb.blobdb.seek.micros"),
697 /// BlobDB Next latency. Only applicable to legacy BlobDB.
698 BlobDbNextMicros("rocksdb.blobdb.next.micros"),
699 /// BlobDB Prev latency. Only applicable to legacy BlobDB.
700 BlobDbPrevMicros("rocksdb.blobdb.prev.micros"),
701 /// Blob file write latency.
702 BlobDbBlobFileWriteMicros("rocksdb.blobdb.blob.file.write.micros"),
703 /// Blob file read latency.
704 BlobDbBlobFileReadMicros("rocksdb.blobdb.blob.file.read.micros"),
705 /// Blob file sync latency.
706 BlobDbBlobFileSyncMicros("rocksdb.blobdb.blob.file.sync.micros"),
707 /// BlobDB compression time.
708 BlobDbCompressionMicros("rocksdb.blobdb.compression.micros"),
709 /// BlobDB decompression time.
710 BlobDbDecompressionMicros("rocksdb.blobdb.decompression.micros"),
711 /// Time spent flushing memtable to disk
712 FlushTime("rocksdb.db.flush.micros"),
713 SstBatchSize("rocksdb.sst.batch.size"),
714 /// MultiGet stats logged per level
715 /// Num of index and filter blocks read from file system per level.
716 NumIndexAndFilterBlocksReadPerLevel("rocksdb.num.index.and.filter.blocks.read.per.level"),
717 /// Num of sst files read from file system per level.
718 NumSstReadPerLevel("rocksdb.num.sst.read.per.level"),
719 /// Error handler statistics
720 ErrorHandlerAutoresumeRetryCount("rocksdb.error.handler.autoresume.retry.count"),
721 /// Stats related to asynchronous read requests.
722 AsyncReadBytes("rocksdb.async.read.bytes"),
723 PollWaitMicros("rocksdb.poll.wait.micros"),
724 /// Number of prefetched bytes discarded by RocksDB.
725 PrefetchedBytesDiscarded("rocksdb.prefetched.bytes.discarded"),
726 /// Number of IOs issued in parallel in a MultiGet batch
727 MultigetIoBatchSize("rocksdb.multiget.io.batch.size"),
728 /// Number of levels requiring IO for MultiGet
729 NumLevelReadPerMultiget("rocksdb.num.level.read.per.multiget"),
730 /// Wait time for aborting async read in FilePrefetchBuffer destructor
731 AsyncPrefetchAbortMicros("rocksdb.async.prefetch.abort.micros"),
732 /// Number of bytes read for RocksDB's prefetching contents (as opposed to file
733 /// system's prefetch) from the end of SST table during block based table open
734 TableOpenPrefetchTailReadBytes("rocksdb.table.open.prefetch.tail.read.bytes"),
735 }
736}
737
738pub struct HistogramData {
739 pub(crate) inner: *mut ffi::rocksdb_statistics_histogram_data_t,
740}
741
742impl HistogramData {
743 pub fn new() -> HistogramData {
744 HistogramData::default()
745 }
746 pub fn median(&self) -> f64 {
747 unsafe { ffi::rocksdb_statistics_histogram_data_get_median(self.inner) }
748 }
749 pub fn average(&self) -> f64 {
750 unsafe { ffi::rocksdb_statistics_histogram_data_get_average(self.inner) }
751 }
752 pub fn p95(&self) -> f64 {
753 unsafe { ffi::rocksdb_statistics_histogram_data_get_p95(self.inner) }
754 }
755 pub fn p99(&self) -> f64 {
756 unsafe { ffi::rocksdb_statistics_histogram_data_get_p99(self.inner) }
757 }
758 pub fn max(&self) -> f64 {
759 unsafe { ffi::rocksdb_statistics_histogram_data_get_max(self.inner) }
760 }
761 pub fn min(&self) -> f64 {
762 unsafe { ffi::rocksdb_statistics_histogram_data_get_min(self.inner) }
763 }
764 pub fn sum(&self) -> u64 {
765 unsafe { ffi::rocksdb_statistics_histogram_data_get_sum(self.inner) }
766 }
767 pub fn count(&self) -> u64 {
768 unsafe { ffi::rocksdb_statistics_histogram_data_get_count(self.inner) }
769 }
770 pub fn std_dev(&self) -> f64 {
771 unsafe { ffi::rocksdb_statistics_histogram_data_get_std_dev(self.inner) }
772 }
773}
774
775impl Default for HistogramData {
776 fn default() -> Self {
777 let histogram_data_inner = unsafe { ffi::rocksdb_statistics_histogram_data_create() };
778 assert!(
779 !histogram_data_inner.is_null(),
780 "Could not create RocksDB histogram data"
781 );
782
783 Self {
784 inner: histogram_data_inner,
785 }
786 }
787}
788
789impl Drop for HistogramData {
790 fn drop(&mut self) {
791 unsafe {
792 ffi::rocksdb_statistics_histogram_data_destroy(self.inner);
793 }
794 }
795}
796
797#[test]
798fn sanity_checks() {
799 let want = "rocksdb.async.read.bytes";
800 assert_eq!(want, Histogram::AsyncReadBytes.name());
801
802 let want = "rocksdb.block.cache.index.miss";
803 assert_eq!(want, Ticker::BlockCacheIndexMiss.to_string());
804
805 // assert enum lengths
806 assert_eq!(Ticker::iter().count(), 215 /* TICKER_ENUM_MAX */);
807 assert_eq!(Histogram::iter().count(), 60 /* HISTOGRAM_ENUM_MAX */);
808}