statistics.cc 27 KB

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