diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..5657f6e --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +vendor \ No newline at end of file diff --git a/README.md b/README.md new file mode 100644 index 0000000..db47ab9 --- /dev/null +++ b/README.md @@ -0,0 +1,144 @@ +### Purpose of this module + +opendb module provides observability and configurability for rocksdb databases. + +### Observability + +When you open RocksDB with provided API: +- opendb registers prometheus metrics +- opendb launches a `reportMetrics` goroutine which every `rocksdb.report-metrics-interval-secs` seconds reports metrics to prometheus, `reportMetrics` goroutine performs following steps: + - uses grocksdb API to gather rocksdb properties/stats in text format + - more info can be found here: https://github.com/facebook/rocksdb/wiki/RocksDB-Tuning-Guide#rocksdb-statistics + - parses rocksdb properties/stats from text and reports them as prometheus metrics + +List of reported metrics and their documentation can be found in: +- source code: `registerMetrics()` function in `metrics.go` +- corresponding grafana dashboard + +### Configurability + +opendb allows you to override default rocksdb settings, more info can be found here: +- https://github.com/facebook/rocksdb/wiki/Setup-Options-and-Basic-Tuning +- https://github.com/facebook/rocksdb/wiki/RocksDB-Tuning-Guide + +There are 2 main scenarios: +- create a new rocksdb database +- open already existing database + +#### Create a new rocksdb database + +- opendb starts with default cometbft-db rocksdb configuration, see for the details: https://github.com/Kava-Labs/cometbft-db/blob/main/rocksdb.go +- opendb overrides options which explicitly specified in appOpts (app.toml) + +#### Open an already existing database + +- opendb loads stored rocksdb configuration and starts with it +- opendb overrides options which explicitly specified in appOpts (app.toml) + +### List of databases: + +| Name | Subsystem | IAVL V1 size as of 10.5 millions blocks | +| ------------------------------- | ------------------ | --------------------------------------- | +| application.db | Kava | 4.5 TB | +| metadata.db (snapshots) | Kava | 21 MB | +| blockstore.db | Ethermint | 337 GB | +| state.db | Ethermint | 282 GB | +| tx_index.db | Ethermint | 504 GB | +| evidence.db | Ethermint | 28 MB | +| evm_indexer.db | Ethermint | 2.2 GB | + +### List of reported rocksdb metrics: + +| Name | Subsystem | Docs | +| ------------------------------- | ------------------ | ---- | +| number_keys_written | Key | | +| number_keys_read | Key | | +| number_keys_updated | Key | | +| estimate_num_keys | Key | estimated number of total keys in the active and unflushed immutable memtables and storage | +| number_file_opens | File | | +| number_file_errors | File | | +| block_cache_usage | Memory | memory size for the entries residing in block cache | +| estimate_table_readers_mem | Memory | estimated memory used for reading SST tables, excluding memory used in block cache (e.g., filter and index blocks) | +| cur_size_all_mem_tables | Memory | approximate size of active and unflushed immutable memtables (bytes) | +| block_cache_pinned_usage | Memory | returns the memory size for the entries being pinned | +| block_cache_miss | Cache | block_cache_miss == block_cache_index_miss + block_cache_filter_miss + block_cache_data_miss | +| block_cache_hit | Cache | block_cache_hit == block_cache_index_hit + block_cache_filter_hit + block_cache_data_hit | +| block_cache_add | Cache | number of blocks added to block cache | +| block_cache_add_failures | Cache | number of failures when adding blocks to block cache | +| block_cache_index_miss | Detailed Cache | | +| block_cache_index_hit | Detailed Cache | | +| block_cache_index_bytes_insert | Detailed Cache | | +| block_cache_filter_miss | Detailed Cache | | +| block_cache_filter_hit | Detailed Cache | | +| block_cache_filter_bytes_insert | Detailed Cache | | +| block_cache_data_miss | Detailed Cache | | +| block_cache_data_hit | Detailed Cache | | +| block_cache_data_bytes_insert | Detailed Cache | | +| db_get_micros_p50 | Latency | | +| db_get_micros_p95 | Latency | | +| db_get_micros_p99 | Latency | | +| db_get_micros_p100 | Latency | | +| db_get_micros_count | Latency | | +| db_write_micros_p50 | Latency | | +| db_write_micros_p95 | Latency | | +| db_write_micros_p99 | Latency | | +| db_write_micros_p100 | Latency | | +| db_write_micros_count | Latency | | +| stall_micros | Stall | Writer has to wait for compaction or flush to finish. | +| db_write_stall_p50 | Stall | | +| db_write_stall_p95 | Stall | | +| db_write_stall_p99 | Stall | | +| db_write_stall_p100 | Stall | | +| db_write_stall_count | Stall | | +| db_write_stall_sum | Stall | | +| bloom_filter_useful | Filter | number of times bloom filter has avoided file reads, i.e., negatives. | +| bloom_filter_full_positive | Filter | number of times bloom FullFilter has not avoided the reads. | +| bloom_filter_full_true_positive | Filter | number of times bloom FullFilter has not avoided the reads and data actually exist. | +| last_level_read_bytes | LSM | | +| last_level_read_count | LSM | | +| non_last_level_read_bytes | LSM | | +| non_last_level_read_count | LSM | | +| get_hit_l0 | LSM | number of Get() queries served by L0 | +| get_hit_l1 | LSM | number of Get() queries served by L1 | +| get_hit_l2_and_up | LSM | number of Get() queries served by L2 and up | + +### Example of RocksDB configuration + +```yml +##################### +# RocksDB Tuning +##################### +rocksdb_enable_metrics: true +rocksdb_report_metrics_interval_secs: 15 + +rocksdb_max_open_files: 16384 # increase default max # of open files from 4096 +rocksdb_max_file_opening_threads: 16 +rocksdb_table_cache_numshardbits: 6 +rocksdb_allow_mmap_writes: false +rocksdb_allow_mmap_reads: false +rocksdb_use_fsync: false +rocksdb_use_adaptive_mutex: false +rocksdb_bytes_per_sync: 0 +rocksdb_max_background_jobs: 16 + +rocksdb_write_buffer_size: 134217728 +rocksdb_num_levels: 7 +rocksdb_max_write_buffer_number: 6 +rocksdb_min_write_buffer_number_to_merge: 2 +rocksdb_max_bytes_for_level_base: 536870912 +rocksdb_max_bytes_for_level_multiplier: 10.000000 +rocksdb_target_file_size_base: 67108864 +rocksdb_target_file_size_multiplier: 1 +rocksdb_level0_file_num_compaction_trigger: 2 +rocksdb_level0_slowdown_writes_trigger: 20 + +rocksdb_block_cache_size: 1073741824 +rocksdb_bits_per_key: 10 +rocksdb_block_size: 16384 # 16K to match default zfs. Decreases block index memory usage by 4x from the default 4K +rocksdb_cache_index_and_filter_blocks: false +rocksdb_pin_l0_filter_and_index_blocks_in_cache: false +rocksdb_format_version: 5 + +# https://rocksdb.org/blog/2022/10/07/asynchronous-io-in-rocksdb.html +rocksdb_read_async_io: true # help speed up iterations +``` diff --git a/go.mod b/go.mod index b9c3514..3ec9cfe 100644 --- a/go.mod +++ b/go.mod @@ -1,6 +1,6 @@ module github.com/Kava-Labs/opendb -go 1.22.3 +go 1.21 require ( github.com/cometbft/cometbft-db v0.9.1 @@ -13,7 +13,6 @@ require ( ) require ( - cosmossdk.io/api v0.7.5 // indirect cosmossdk.io/errors v1.0.1 // indirect cosmossdk.io/log v1.3.1 // indirect cosmossdk.io/math v1.3.0 // indirect @@ -33,14 +32,14 @@ require ( github.com/cockroachdb/pebble v1.1.0 // indirect github.com/cockroachdb/redact v1.1.5 // indirect github.com/cockroachdb/tokenbucket v0.0.0-20230807174530-cc333fc44b06 // indirect - github.com/cometbft/cometbft v0.38.7 // indirect + github.com/cometbft/cometbft v0.37.4 // indirect github.com/confio/ics23/go v0.9.0 // indirect github.com/cosmos/btcutil v1.0.5 // indirect github.com/cosmos/cosmos-db v1.0.2 // indirect github.com/cosmos/cosmos-proto v1.0.0-beta.5 // indirect github.com/cosmos/go-bip39 v1.0.0 // indirect github.com/cosmos/gogogateway v1.2.0 // indirect - github.com/cosmos/gogoproto v1.4.12 // indirect + github.com/cosmos/gogoproto v1.4.10 // indirect github.com/cosmos/iavl v1.1.2 // indirect github.com/cosmos/ics23/go v0.10.0 // indirect github.com/cosmos/ledger-cosmos-go v0.13.3 // indirect @@ -102,24 +101,21 @@ require ( github.com/rogpeppe/go-internal v1.12.0 // indirect github.com/rs/cors v1.8.3 // indirect github.com/rs/zerolog v1.32.0 // indirect - github.com/sagikazarmark/locafero v0.4.0 // indirect - github.com/sagikazarmark/slog-shim v0.1.0 // indirect github.com/sasha-s/go-deadlock v0.3.1 // indirect - github.com/sourcegraph/conc v0.3.0 // indirect github.com/spf13/afero v1.11.0 // indirect github.com/spf13/cobra v1.8.0 // indirect + github.com/spf13/jwalterweatherman v1.1.0 // indirect github.com/spf13/pflag v1.0.5 // indirect - github.com/spf13/viper v1.18.2 // indirect + github.com/spf13/viper v1.16.0 // indirect github.com/subosito/gotenv v1.6.0 // indirect github.com/syndtr/goleveldb v1.0.1-0.20220721030215-126854af5e6d // indirect github.com/tendermint/go-amino v0.16.0 // indirect github.com/tidwall/btree v1.7.0 // indirect github.com/zondax/hid v0.9.2 // indirect github.com/zondax/ledger-go v0.14.3 // indirect - go.etcd.io/bbolt v1.4.0-alpha.0.0.20240404170359-43604f3112c5 // indirect - go.uber.org/multierr v1.10.0 // indirect + go.etcd.io/bbolt v1.3.8 // indirect golang.org/x/crypto v0.22.0 // indirect - golang.org/x/exp v0.0.0-20240404231335-c0f41cb1a7a0 // indirect + golang.org/x/exp v0.0.0-20230711153332-06a737ee72cb // indirect golang.org/x/net v0.24.0 // indirect golang.org/x/sys v0.19.0 // indirect golang.org/x/term v0.19.0 // indirect diff --git a/go.sum b/go.sum index 418afa0..1886def 100644 --- a/go.sum +++ b/go.sum @@ -1,7 +1,7 @@ cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= -cosmossdk.io/api v0.7.5 h1:eMPTReoNmGUm8DeiQL9DyM8sYDjEhWzL1+nLbI9DqtQ= -cosmossdk.io/api v0.7.5/go.mod h1:IcxpYS5fMemZGqyYtErK7OqvdM0C8kdW3dq8Q/XIG38= +cosmossdk.io/api v0.3.1 h1:NNiOclKRR0AOlO4KIqeaG6PS6kswOMhHD0ir0SscNXE= +cosmossdk.io/api v0.3.1/go.mod h1:DfHfMkiNA2Uhy8fj0JJlOCYOBp4eWUUJ1te5zBGNyIw= cosmossdk.io/core v0.6.1 h1:OBy7TI2W+/gyn2z40vVvruK3di+cAluinA6cybFbE7s= cosmossdk.io/core v0.6.1/go.mod h1:g3MMBCBXtxbDWBURDVnJE7XML4BG5qENhs0gzkcpuFA= cosmossdk.io/depinject v1.0.0-alpha.4 h1:PLNp8ZYAMPTUKyG9IK2hsbciDWqna2z1Wsl98okJopc= @@ -97,8 +97,8 @@ github.com/cosmos/go-bip39 v1.0.0/go.mod h1:RNJv0H/pOIVgxw6KS7QeX2a0Uo0aKUlfhZ4x github.com/cosmos/gogogateway v1.2.0 h1:Ae/OivNhp8DqBi/sh2A8a1D0y638GpL3tkmLQAiKxTE= github.com/cosmos/gogogateway v1.2.0/go.mod h1:iQpLkGWxYcnCdz5iAdLcRBSw3h7NXeOkZ4GUkT+tbFI= github.com/cosmos/gogoproto v1.4.2/go.mod h1:cLxOsn1ljAHSV527CHOtaIP91kK6cCrZETRBrkzItWU= -github.com/cosmos/gogoproto v1.4.12 h1:vB6Lbe/rtnYGjQuFxkPiPYiCybqFT8QvLipDZP8JpFE= -github.com/cosmos/gogoproto v1.4.12/go.mod h1:LnZob1bXRdUoqMMtwYlcR3wjiElmlC+FkjaZRv1/eLY= +github.com/cosmos/gogoproto v1.4.10 h1:QH/yT8X+c0F4ZDacDv3z+xE3WU1P1Z3wQoLMBRJoKuI= +github.com/cosmos/gogoproto v1.4.10/go.mod h1:3aAZzeRWpAwr+SS/LLkICX2/kDFyaYVzckBDzygIxek= github.com/cosmos/iavl v1.1.2 h1:zL9FK7C4L/P4IF1Dm5fIwz0WXCnn7Bp1M2FxH0ayM7Y= github.com/cosmos/iavl v1.1.2/go.mod h1:jLeUvm6bGT1YutCaL2fIar/8vGUE8cPZvh/gXEWDaDM= github.com/cosmos/ics23/go v0.10.0 h1:iXqLLgp2Lp+EdpIuwXTYIQU+AiHj9mOC2X9ab++bZDM= @@ -393,16 +393,10 @@ github.com/rs/zerolog v1.32.0 h1:keLypqrlIjaFsbmJOBdB/qvyF8KEtCWHwobLp5l/mQ0= github.com/rs/zerolog v1.32.0/go.mod h1:/7mN4D5sKwJLZQ2b/znpjC3/GQWY/xaDXUM0kKWRHss= github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g= github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= -github.com/sagikazarmark/locafero v0.4.0 h1:HApY1R9zGo4DBgr7dqsTH/JJxLTTsOt7u6keLGt6kNQ= -github.com/sagikazarmark/locafero v0.4.0/go.mod h1:Pe1W6UlPYUk/+wc/6KFhbORCfqzgYEpgQ3O5fPuL3H4= -github.com/sagikazarmark/slog-shim v0.1.0 h1:diDBnUNK9N/354PgrxMywXnAwEr1QZcOr6gto+ugjYE= -github.com/sagikazarmark/slog-shim v0.1.0/go.mod h1:SrcSrq8aKtyuqEI1uvTDTK1arOWRIczQRv+GVI1AkeQ= github.com/sasha-s/go-deadlock v0.3.1 h1:sqv7fDNShgjcaxkO0JNcOAlr8B9+cV5Ey/OB71efZx0= github.com/sasha-s/go-deadlock v0.3.1/go.mod h1:F73l+cr82YSh10GxyRI6qZiCgK64VaZjwesgfQ1/iLM= github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= -github.com/sourcegraph/conc v0.3.0 h1:OQTbbt6P72L20UqAkXXuLOj79LfEanQ+YQFNpLA9ySo= -github.com/sourcegraph/conc v0.3.0/go.mod h1:Sdozi7LEKbFPqYX2/J+iBAM6HpqSLTASQIKqDmF7Mt0= github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= github.com/spaolacci/murmur3 v1.1.0 h1:7c1g84S4BPRrfL5Xrdp6fOJ206sU9y293DDHaoy0bLI= github.com/spaolacci/murmur3 v1.1.0/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= @@ -416,12 +410,14 @@ github.com/spf13/cobra v0.0.5/go.mod h1:3K3wKZymM7VvHMDS9+Akkh4K60UwM26emMESw8tL github.com/spf13/cobra v1.8.0 h1:7aJaZx1B85qltLMc546zn58BxxfZdR/W22ej9CFoEf0= github.com/spf13/cobra v1.8.0/go.mod h1:WXLWApfZ71AjXPya3WOlMsY9yMs7YeiHhFVlvLyhcho= github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo= +github.com/spf13/jwalterweatherman v1.1.0 h1:ue6voC5bR5F8YxI5S67j9i582FU4Qvo2bmqnqMYADFk= +github.com/spf13/jwalterweatherman v1.1.0/go.mod h1:aNWZUN0dPAAO/Ljvb5BEdw96iTZ0EXowPYD95IqWIGo= github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= github.com/spf13/viper v1.3.2/go.mod h1:ZiWeW+zYFKm7srdB9IoDzzZXaJaI5eL9QjNiN/DMA2s= -github.com/spf13/viper v1.18.2 h1:LUXCnvUvSM6FXAsj6nnfc8Q2tp1dIgUfY9Kc8GsSOiQ= -github.com/spf13/viper v1.18.2/go.mod h1:EKmWIqdnk5lOcmR72yw6hS+8OPYcwD0jteitLMVB+yk= +github.com/spf13/viper v1.16.0 h1:rGGH0XDZhdUOryiDWjmIvUSWpbNqisK8Wk0Vyefw8hc= +github.com/spf13/viper v1.16.0/go.mod h1:yg78JgCJcbrQOvV9YLXgkLaZqUidkY9K+Dd1FofRzQg= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= @@ -457,11 +453,9 @@ github.com/zondax/hid v0.9.2 h1:WCJFnEDMiqGF64nlZz28E9qLVZ0KSJ7xpc5DLEyma2U= github.com/zondax/hid v0.9.2/go.mod h1:l5wttcP0jwtdLjqjMMWFVEE7d1zO0jvSPA9OPZxWpEM= github.com/zondax/ledger-go v0.14.3 h1:wEpJt2CEcBJ428md/5MgSLsXLBos98sBOyxNmCjfUCw= github.com/zondax/ledger-go v0.14.3/go.mod h1:IKKaoxupuB43g4NxeQmbLXv7T9AlQyie1UpHb342ycI= -go.etcd.io/bbolt v1.4.0-alpha.0.0.20240404170359-43604f3112c5 h1:qxen9oVGzDdIRP6ejyAJc760RwW4SnVDiTYTzwnXuxo= -go.etcd.io/bbolt v1.4.0-alpha.0.0.20240404170359-43604f3112c5/go.mod h1:eW0HG9/oHQhvRCvb1/pIXW4cOvtDqeQK+XSi3TnwaXY= +go.etcd.io/bbolt v1.3.8 h1:xs88BrvEv273UsB79e0hcVrlUWmS0a8upikMFhSyAtA= +go.etcd.io/bbolt v1.3.8/go.mod h1:N9Mkw9X8x5fupy0IKsmuqVtoGDyxsaDlbk4Rd05IAQw= go.opentelemetry.io/proto/otlp v0.7.0/go.mod h1:PqfVotwruBrMGOCsRd/89rSnXhoiJIqeYNgFYFoEGnI= -go.uber.org/multierr v1.10.0 h1:S0h4aNzvfcFsC3dRF1jLoaov7oRaKqRGC/pUEJ2yvPQ= -go.uber.org/multierr v1.10.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y= golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20181203042331-505ab145d0a9/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= @@ -472,8 +466,8 @@ golang.org/x/crypto v0.0.0-20200728195943-123391ffb6de/go.mod h1:LzIPMQfyMNhhGPh golang.org/x/crypto v0.22.0 h1:g1v0xeRhjcugydODzvb3mEM9SQ0HGp9s/nh3COQ/C30= golang.org/x/crypto v0.22.0/go.mod h1:vr6Su+7cTlO45qkww3VDJlzDn0ctJvRgYbC2NvXHt+M= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= -golang.org/x/exp v0.0.0-20240404231335-c0f41cb1a7a0 h1:985EYyeCOxTpcgOTJpflJUwOeEz0CQOdPt73OzpE9F8= -golang.org/x/exp v0.0.0-20240404231335-c0f41cb1a7a0/go.mod h1:/lliqkxwWAhPjf5oSOIJup2XcqJaw8RGS6k3TGEc7GI= +golang.org/x/exp v0.0.0-20230711153332-06a737ee72cb h1:xIApU0ow1zwMa2uL1VDNeQlNVFTWMQxZUZCMDy0Q4Us= +golang.org/x/exp v0.0.0-20230711153332-06a737ee72cb/go.mod h1:FXUEEKJgO7OQYeo8N01OfiKP8RXMtf6e8aTskBGqWdc= golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= @@ -508,8 +502,8 @@ golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.7.0 h1:YsImfSBoP9QPYL0xyKJPq0gcaJdG3rInoqxTWbfQu9M= -golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= +golang.org/x/sync v0.6.0 h1:5BMeUDZ7vkXGfEr1x9B4bRcTH4lpkTkpdh0T/J+qjbQ= +golang.org/x/sync v0.6.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= diff --git a/metrics.go b/metrics.go index dc7fd8d..5a476e1 100644 --- a/metrics.go +++ b/metrics.go @@ -9,6 +9,10 @@ import ( stdprometheus "github.com/prometheus/client_golang/prometheus" ) +const ( + dbNameMetricLabelName = "db_name" +) + // rocksdbMetrics will be initialized in registerMetrics() if enableRocksdbMetrics flag set to true var rocksdbMetrics *Metrics @@ -95,29 +99,30 @@ func registerMetrics() { return } - labels := make([]string, 0) + namespace := "rocksdb_v2" + labels := []string{dbNameMetricLabelName} rocksdbMetrics = &Metrics{ // Keys NumberKeysWritten: prometheus.NewGaugeFrom(stdprometheus.GaugeOpts{ - Namespace: "rocksdb", + Namespace: namespace, Subsystem: "key", Name: "number_keys_written", Help: "", }, labels), NumberKeysRead: prometheus.NewGaugeFrom(stdprometheus.GaugeOpts{ - Namespace: "rocksdb", + Namespace: namespace, Subsystem: "key", Name: "number_keys_read", Help: "", }, labels), NumberKeysUpdated: prometheus.NewGaugeFrom(stdprometheus.GaugeOpts{ - Namespace: "rocksdb", + Namespace: namespace, Subsystem: "key", Name: "number_keys_updated", Help: "", }, labels), EstimateNumKeys: prometheus.NewGaugeFrom(stdprometheus.GaugeOpts{ - Namespace: "rocksdb", + Namespace: namespace, Subsystem: "key", Name: "estimate_num_keys", Help: "estimated number of total keys in the active and unflushed immutable memtables and storage", @@ -125,13 +130,13 @@ func registerMetrics() { // Files NumberFileOpens: prometheus.NewGaugeFrom(stdprometheus.GaugeOpts{ - Namespace: "rocksdb", + Namespace: namespace, Subsystem: "file", Name: "number_file_opens", Help: "", }, labels), NumberFileErrors: prometheus.NewGaugeFrom(stdprometheus.GaugeOpts{ - Namespace: "rocksdb", + Namespace: namespace, Subsystem: "file", Name: "number_file_errors", Help: "", @@ -139,25 +144,25 @@ func registerMetrics() { // Memory BlockCacheUsage: prometheus.NewGaugeFrom(stdprometheus.GaugeOpts{ - Namespace: "rocksdb", + Namespace: namespace, Subsystem: "memory", Name: "block_cache_usage", Help: "memory size for the entries residing in block cache", }, labels), EstimateTableReadersMem: prometheus.NewGaugeFrom(stdprometheus.GaugeOpts{ - Namespace: "rocksdb", + Namespace: namespace, Subsystem: "memory", Name: "estimate_table_readers_mem", Help: "estimated memory used for reading SST tables, excluding memory used in block cache (e.g., filter and index blocks)", }, labels), CurSizeAllMemTables: prometheus.NewGaugeFrom(stdprometheus.GaugeOpts{ - Namespace: "rocksdb", + Namespace: namespace, Subsystem: "memory", Name: "cur_size_all_mem_tables", Help: "approximate size of active and unflushed immutable memtables (bytes)", }, labels), BlockCachePinnedUsage: prometheus.NewGaugeFrom(stdprometheus.GaugeOpts{ - Namespace: "rocksdb", + Namespace: namespace, Subsystem: "memory", Name: "block_cache_pinned_usage", Help: "returns the memory size for the entries being pinned", @@ -165,25 +170,25 @@ func registerMetrics() { // Cache BlockCacheMiss: prometheus.NewGaugeFrom(stdprometheus.GaugeOpts{ - Namespace: "rocksdb", + Namespace: namespace, Subsystem: "cache", Name: "block_cache_miss", Help: "block_cache_miss == block_cache_index_miss + block_cache_filter_miss + block_cache_data_miss", }, labels), BlockCacheHit: prometheus.NewGaugeFrom(stdprometheus.GaugeOpts{ - Namespace: "rocksdb", + Namespace: namespace, Subsystem: "cache", Name: "block_cache_hit", Help: "block_cache_hit == block_cache_index_hit + block_cache_filter_hit + block_cache_data_hit", }, labels), BlockCacheAdd: prometheus.NewGaugeFrom(stdprometheus.GaugeOpts{ - Namespace: "rocksdb", + Namespace: namespace, Subsystem: "cache", Name: "block_cache_add", Help: "number of blocks added to block cache", }, labels), BlockCacheAddFailures: prometheus.NewGaugeFrom(stdprometheus.GaugeOpts{ - Namespace: "rocksdb", + Namespace: namespace, Subsystem: "cache", Name: "block_cache_add_failures", Help: "number of failures when adding blocks to block cache", @@ -191,57 +196,57 @@ func registerMetrics() { // Detailed Cache BlockCacheIndexMiss: prometheus.NewGaugeFrom(stdprometheus.GaugeOpts{ - Namespace: "rocksdb", + Namespace: namespace, Subsystem: "detailed_cache", Name: "block_cache_index_miss", Help: "", }, labels), BlockCacheIndexHit: prometheus.NewGaugeFrom(stdprometheus.GaugeOpts{ - Namespace: "rocksdb", + Namespace: namespace, Subsystem: "detailed_cache", Name: "block_cache_index_hit", Help: "", }, labels), BlockCacheIndexBytesInsert: prometheus.NewGaugeFrom(stdprometheus.GaugeOpts{ - Namespace: "rocksdb", + Namespace: namespace, Subsystem: "detailed_cache", Name: "block_cache_index_bytes_insert", Help: "", }, labels), BlockCacheFilterMiss: prometheus.NewGaugeFrom(stdprometheus.GaugeOpts{ - Namespace: "rocksdb", + Namespace: namespace, Subsystem: "detailed_cache", Name: "block_cache_filter_miss", Help: "", }, labels), BlockCacheFilterHit: prometheus.NewGaugeFrom(stdprometheus.GaugeOpts{ - Namespace: "rocksdb", + Namespace: namespace, Subsystem: "detailed_cache", Name: "block_cache_filter_hit", Help: "", }, labels), BlockCacheFilterBytesInsert: prometheus.NewGaugeFrom(stdprometheus.GaugeOpts{ - Namespace: "rocksdb", + Namespace: namespace, Subsystem: "detailed_cache", Name: "block_cache_filter_bytes_insert", Help: "", }, labels), BlockCacheDataMiss: prometheus.NewGaugeFrom(stdprometheus.GaugeOpts{ - Namespace: "rocksdb", + Namespace: namespace, Subsystem: "detailed_cache", Name: "block_cache_data_miss", Help: "", }, labels), BlockCacheDataHit: prometheus.NewGaugeFrom(stdprometheus.GaugeOpts{ - Namespace: "rocksdb", + Namespace: namespace, Subsystem: "detailed_cache", Name: "block_cache_data_hit", Help: "", }, labels), BlockCacheDataBytesInsert: prometheus.NewGaugeFrom(stdprometheus.GaugeOpts{ - Namespace: "rocksdb", + Namespace: namespace, Subsystem: "detailed_cache", Name: "block_cache_data_bytes_insert", Help: "", @@ -249,62 +254,62 @@ func registerMetrics() { // Latency DBGetMicrosP50: prometheus.NewGaugeFrom(stdprometheus.GaugeOpts{ - Namespace: "rocksdb", + Namespace: namespace, Subsystem: "latency", Name: "db_get_micros_p50", Help: "", }, labels), DBGetMicrosP95: prometheus.NewGaugeFrom(stdprometheus.GaugeOpts{ - Namespace: "rocksdb", + Namespace: namespace, Subsystem: "latency", Name: "db_get_micros_p95", Help: "", }, labels), DBGetMicrosP99: prometheus.NewGaugeFrom(stdprometheus.GaugeOpts{ - Namespace: "rocksdb", + Namespace: namespace, Subsystem: "latency", Name: "db_get_micros_p99", Help: "", }, labels), DBGetMicrosP100: prometheus.NewGaugeFrom(stdprometheus.GaugeOpts{ - Namespace: "rocksdb", + Namespace: namespace, Subsystem: "latency", Name: "db_get_micros_p100", Help: "", }, labels), DBGetMicrosCount: prometheus.NewGaugeFrom(stdprometheus.GaugeOpts{ - Namespace: "rocksdb", + Namespace: namespace, Subsystem: "latency", Name: "db_get_micros_count", Help: "", }, labels), DBWriteMicrosP50: prometheus.NewGaugeFrom(stdprometheus.GaugeOpts{ - Namespace: "rocksdb", + Namespace: namespace, Subsystem: "latency", Name: "db_write_micros_p50", Help: "", }, labels), DBWriteMicrosP95: prometheus.NewGaugeFrom(stdprometheus.GaugeOpts{ - Namespace: "rocksdb", + Namespace: namespace, Subsystem: "latency", Name: "db_write_micros_p95", Help: "", }, labels), DBWriteMicrosP99: prometheus.NewGaugeFrom(stdprometheus.GaugeOpts{ - Namespace: "rocksdb", + Namespace: namespace, Subsystem: "latency", Name: "db_write_micros_p99", Help: "", }, labels), DBWriteMicrosP100: prometheus.NewGaugeFrom(stdprometheus.GaugeOpts{ - Namespace: "rocksdb", + Namespace: namespace, Subsystem: "latency", Name: "db_write_micros_p100", Help: "", }, labels), DBWriteMicrosCount: prometheus.NewGaugeFrom(stdprometheus.GaugeOpts{ - Namespace: "rocksdb", + Namespace: namespace, Subsystem: "latency", Name: "db_write_micros_count", Help: "", @@ -312,44 +317,44 @@ func registerMetrics() { // Write Stall StallMicros: prometheus.NewGaugeFrom(stdprometheus.GaugeOpts{ - Namespace: "rocksdb", + Namespace: namespace, Subsystem: "stall", Name: "stall_micros", Help: "Writer has to wait for compaction or flush to finish.", }, labels), DBWriteStallP50: prometheus.NewGaugeFrom(stdprometheus.GaugeOpts{ - Namespace: "rocksdb", + Namespace: namespace, Subsystem: "stall", Name: "db_write_stall_p50", Help: "", }, labels), DBWriteStallP95: prometheus.NewGaugeFrom(stdprometheus.GaugeOpts{ - Namespace: "rocksdb", + Namespace: namespace, Subsystem: "stall", Name: "db_write_stall_p95", Help: "", }, labels), DBWriteStallP99: prometheus.NewGaugeFrom(stdprometheus.GaugeOpts{ - Namespace: "rocksdb", + Namespace: namespace, Subsystem: "stall", Name: "db_write_stall_p99", Help: "", }, labels), DBWriteStallP100: prometheus.NewGaugeFrom(stdprometheus.GaugeOpts{ - Namespace: "rocksdb", + Namespace: namespace, Subsystem: "stall", Name: "db_write_stall_p100", Help: "", }, labels), DBWriteStallCount: prometheus.NewGaugeFrom(stdprometheus.GaugeOpts{ - Namespace: "rocksdb", + Namespace: namespace, Subsystem: "stall", Name: "db_write_stall_count", Help: "", }, labels), DBWriteStallSum: prometheus.NewGaugeFrom(stdprometheus.GaugeOpts{ - Namespace: "rocksdb", + Namespace: namespace, Subsystem: "stall", Name: "db_write_stall_sum", Help: "", @@ -357,19 +362,19 @@ func registerMetrics() { // Bloom Filter BloomFilterUseful: prometheus.NewGaugeFrom(stdprometheus.GaugeOpts{ - Namespace: "rocksdb", + Namespace: namespace, Subsystem: "filter", Name: "bloom_filter_useful", Help: "number of times bloom filter has avoided file reads, i.e., negatives.", }, labels), BloomFilterFullPositive: prometheus.NewGaugeFrom(stdprometheus.GaugeOpts{ - Namespace: "rocksdb", + Namespace: namespace, Subsystem: "filter", Name: "bloom_filter_full_positive", Help: "number of times bloom FullFilter has not avoided the reads.", }, labels), BloomFilterFullTruePositive: prometheus.NewGaugeFrom(stdprometheus.GaugeOpts{ - Namespace: "rocksdb", + Namespace: namespace, Subsystem: "filter", Name: "bloom_filter_full_true_positive", Help: "number of times bloom FullFilter has not avoided the reads and data actually exist.", @@ -377,44 +382,44 @@ func registerMetrics() { // LSM Tree Stats LastLevelReadBytes: prometheus.NewGaugeFrom(stdprometheus.GaugeOpts{ - Namespace: "rocksdb", + Namespace: namespace, Subsystem: "lsm", Name: "last_level_read_bytes", Help: "", }, labels), LastLevelReadCount: prometheus.NewGaugeFrom(stdprometheus.GaugeOpts{ - Namespace: "rocksdb", + Namespace: namespace, Subsystem: "lsm", Name: "last_level_read_count", Help: "", }, labels), NonLastLevelReadBytes: prometheus.NewGaugeFrom(stdprometheus.GaugeOpts{ - Namespace: "rocksdb", + Namespace: namespace, Subsystem: "lsm", Name: "non_last_level_read_bytes", Help: "", }, labels), NonLastLevelReadCount: prometheus.NewGaugeFrom(stdprometheus.GaugeOpts{ - Namespace: "rocksdb", + Namespace: namespace, Subsystem: "lsm", Name: "non_last_level_read_count", Help: "", }, labels), GetHitL0: prometheus.NewGaugeFrom(stdprometheus.GaugeOpts{ - Namespace: "rocksdb", + Namespace: namespace, Subsystem: "lsm", Name: "get_hit_l0", Help: "number of Get() queries served by L0", }, labels), GetHitL1: prometheus.NewGaugeFrom(stdprometheus.GaugeOpts{ - Namespace: "rocksdb", + Namespace: namespace, Subsystem: "lsm", Name: "get_hit_l1", Help: "number of Get() queries served by L1", }, labels), GetHitL2AndUp: prometheus.NewGaugeFrom(stdprometheus.GaugeOpts{ - Namespace: "rocksdb", + Namespace: namespace, Subsystem: "lsm", Name: "get_hit_l2_and_up", Help: "number of Get() queries served by L2 and up", @@ -423,77 +428,77 @@ func registerMetrics() { } // report reports metrics to prometheus based on rocksdb props and stats -func (m *Metrics) report(props *properties, stats *stats) { +func (m *Metrics) report(dbName string, props *properties, stats *stats) { // Keys - m.NumberKeysWritten.Set(float64(stats.NumberKeysWritten)) - m.NumberKeysRead.Set(float64(stats.NumberKeysRead)) - m.NumberKeysUpdated.Set(float64(stats.NumberKeysUpdated)) - m.EstimateNumKeys.Set(float64(props.EstimateNumKeys)) + m.NumberKeysWritten.With(dbNameMetricLabelName, dbName).Set(float64(stats.NumberKeysWritten)) + m.NumberKeysRead.With(dbNameMetricLabelName, dbName).Set(float64(stats.NumberKeysRead)) + m.NumberKeysUpdated.With(dbNameMetricLabelName, dbName).Set(float64(stats.NumberKeysUpdated)) + m.EstimateNumKeys.With(dbNameMetricLabelName, dbName).Set(float64(props.EstimateNumKeys)) // Files - m.NumberFileOpens.Set(float64(stats.NumberFileOpens)) - m.NumberFileErrors.Set(float64(stats.NumberFileErrors)) + m.NumberFileOpens.With(dbNameMetricLabelName, dbName).Set(float64(stats.NumberFileOpens)) + m.NumberFileErrors.With(dbNameMetricLabelName, dbName).Set(float64(stats.NumberFileErrors)) // Memory - m.BlockCacheUsage.Set(float64(props.BlockCacheUsage)) - m.EstimateTableReadersMem.Set(float64(props.EstimateTableReadersMem)) - m.CurSizeAllMemTables.Set(float64(props.CurSizeAllMemTables)) - m.BlockCachePinnedUsage.Set(float64(props.BlockCachePinnedUsage)) + m.BlockCacheUsage.With(dbNameMetricLabelName, dbName).Set(float64(props.BlockCacheUsage)) + m.EstimateTableReadersMem.With(dbNameMetricLabelName, dbName).Set(float64(props.EstimateTableReadersMem)) + m.CurSizeAllMemTables.With(dbNameMetricLabelName, dbName).Set(float64(props.CurSizeAllMemTables)) + m.BlockCachePinnedUsage.With(dbNameMetricLabelName, dbName).Set(float64(props.BlockCachePinnedUsage)) // Cache - m.BlockCacheMiss.Set(float64(stats.BlockCacheMiss)) - m.BlockCacheHit.Set(float64(stats.BlockCacheHit)) - m.BlockCacheAdd.Set(float64(stats.BlockCacheAdd)) - m.BlockCacheAddFailures.Set(float64(stats.BlockCacheAddFailures)) + m.BlockCacheMiss.With(dbNameMetricLabelName, dbName).Set(float64(stats.BlockCacheMiss)) + m.BlockCacheHit.With(dbNameMetricLabelName, dbName).Set(float64(stats.BlockCacheHit)) + m.BlockCacheAdd.With(dbNameMetricLabelName, dbName).Set(float64(stats.BlockCacheAdd)) + m.BlockCacheAddFailures.With(dbNameMetricLabelName, dbName).Set(float64(stats.BlockCacheAddFailures)) // Detailed Cache - m.BlockCacheIndexMiss.Set(float64(stats.BlockCacheIndexMiss)) - m.BlockCacheIndexHit.Set(float64(stats.BlockCacheIndexHit)) - m.BlockCacheIndexBytesInsert.Set(float64(stats.BlockCacheIndexBytesInsert)) + m.BlockCacheIndexMiss.With(dbNameMetricLabelName, dbName).Set(float64(stats.BlockCacheIndexMiss)) + m.BlockCacheIndexHit.With(dbNameMetricLabelName, dbName).Set(float64(stats.BlockCacheIndexHit)) + m.BlockCacheIndexBytesInsert.With(dbNameMetricLabelName, dbName).Set(float64(stats.BlockCacheIndexBytesInsert)) - m.BlockCacheFilterMiss.Set(float64(stats.BlockCacheFilterMiss)) - m.BlockCacheFilterHit.Set(float64(stats.BlockCacheFilterHit)) - m.BlockCacheFilterBytesInsert.Set(float64(stats.BlockCacheFilterBytesInsert)) + m.BlockCacheFilterMiss.With(dbNameMetricLabelName, dbName).Set(float64(stats.BlockCacheFilterMiss)) + m.BlockCacheFilterHit.With(dbNameMetricLabelName, dbName).Set(float64(stats.BlockCacheFilterHit)) + m.BlockCacheFilterBytesInsert.With(dbNameMetricLabelName, dbName).Set(float64(stats.BlockCacheFilterBytesInsert)) - m.BlockCacheDataMiss.Set(float64(stats.BlockCacheDataMiss)) - m.BlockCacheDataHit.Set(float64(stats.BlockCacheDataHit)) - m.BlockCacheDataBytesInsert.Set(float64(stats.BlockCacheDataBytesInsert)) + m.BlockCacheDataMiss.With(dbNameMetricLabelName, dbName).Set(float64(stats.BlockCacheDataMiss)) + m.BlockCacheDataHit.With(dbNameMetricLabelName, dbName).Set(float64(stats.BlockCacheDataHit)) + m.BlockCacheDataBytesInsert.With(dbNameMetricLabelName, dbName).Set(float64(stats.BlockCacheDataBytesInsert)) // Latency - m.DBGetMicrosP50.Set(stats.DBGetMicros.P50) - m.DBGetMicrosP95.Set(stats.DBGetMicros.P95) - m.DBGetMicrosP99.Set(stats.DBGetMicros.P99) - m.DBGetMicrosP100.Set(stats.DBGetMicros.P100) - m.DBGetMicrosCount.Set(stats.DBGetMicros.Count) - - m.DBWriteMicrosP50.Set(stats.DBWriteMicros.P50) - m.DBWriteMicrosP95.Set(stats.DBWriteMicros.P95) - m.DBWriteMicrosP99.Set(stats.DBWriteMicros.P99) - m.DBWriteMicrosP100.Set(stats.DBWriteMicros.P100) - m.DBWriteMicrosCount.Set(stats.DBWriteMicros.Count) + m.DBGetMicrosP50.With(dbNameMetricLabelName, dbName).Set(stats.DBGetMicros.P50) + m.DBGetMicrosP95.With(dbNameMetricLabelName, dbName).Set(stats.DBGetMicros.P95) + m.DBGetMicrosP99.With(dbNameMetricLabelName, dbName).Set(stats.DBGetMicros.P99) + m.DBGetMicrosP100.With(dbNameMetricLabelName, dbName).Set(stats.DBGetMicros.P100) + m.DBGetMicrosCount.With(dbNameMetricLabelName, dbName).Set(stats.DBGetMicros.Count) + + m.DBWriteMicrosP50.With(dbNameMetricLabelName, dbName).Set(stats.DBWriteMicros.P50) + m.DBWriteMicrosP95.With(dbNameMetricLabelName, dbName).Set(stats.DBWriteMicros.P95) + m.DBWriteMicrosP99.With(dbNameMetricLabelName, dbName).Set(stats.DBWriteMicros.P99) + m.DBWriteMicrosP100.With(dbNameMetricLabelName, dbName).Set(stats.DBWriteMicros.P100) + m.DBWriteMicrosCount.With(dbNameMetricLabelName, dbName).Set(stats.DBWriteMicros.Count) // Write Stall - m.StallMicros.Set(float64(stats.StallMicros)) + m.StallMicros.With(dbNameMetricLabelName, dbName).Set(float64(stats.StallMicros)) - m.DBWriteStallP50.Set(stats.DBWriteStallHistogram.P50) - m.DBWriteStallP95.Set(stats.DBWriteStallHistogram.P95) - m.DBWriteStallP99.Set(stats.DBWriteStallHistogram.P99) - m.DBWriteStallP100.Set(stats.DBWriteStallHistogram.P100) - m.DBWriteStallCount.Set(stats.DBWriteStallHistogram.Count) - m.DBWriteStallSum.Set(stats.DBWriteStallHistogram.Sum) + m.DBWriteStallP50.With(dbNameMetricLabelName, dbName).Set(stats.DBWriteStallHistogram.P50) + m.DBWriteStallP95.With(dbNameMetricLabelName, dbName).Set(stats.DBWriteStallHistogram.P95) + m.DBWriteStallP99.With(dbNameMetricLabelName, dbName).Set(stats.DBWriteStallHistogram.P99) + m.DBWriteStallP100.With(dbNameMetricLabelName, dbName).Set(stats.DBWriteStallHistogram.P100) + m.DBWriteStallCount.With(dbNameMetricLabelName, dbName).Set(stats.DBWriteStallHistogram.Count) + m.DBWriteStallSum.With(dbNameMetricLabelName, dbName).Set(stats.DBWriteStallHistogram.Sum) // Bloom Filter - m.BloomFilterUseful.Set(float64(stats.BloomFilterUseful)) - m.BloomFilterFullPositive.Set(float64(stats.BloomFilterFullPositive)) - m.BloomFilterFullTruePositive.Set(float64(stats.BloomFilterFullTruePositive)) + m.BloomFilterUseful.With(dbNameMetricLabelName, dbName).Set(float64(stats.BloomFilterUseful)) + m.BloomFilterFullPositive.With(dbNameMetricLabelName, dbName).Set(float64(stats.BloomFilterFullPositive)) + m.BloomFilterFullTruePositive.With(dbNameMetricLabelName, dbName).Set(float64(stats.BloomFilterFullTruePositive)) // LSM Tree Stats - m.LastLevelReadBytes.Set(float64(stats.LastLevelReadBytes)) - m.LastLevelReadCount.Set(float64(stats.LastLevelReadCount)) - m.NonLastLevelReadBytes.Set(float64(stats.NonLastLevelReadBytes)) - m.NonLastLevelReadCount.Set(float64(stats.NonLastLevelReadCount)) - - m.GetHitL0.Set(float64(stats.GetHitL0)) - m.GetHitL1.Set(float64(stats.GetHitL1)) - m.GetHitL2AndUp.Set(float64(stats.GetHitL2AndUp)) + m.LastLevelReadBytes.With(dbNameMetricLabelName, dbName).Set(float64(stats.LastLevelReadBytes)) + m.LastLevelReadCount.With(dbNameMetricLabelName, dbName).Set(float64(stats.LastLevelReadCount)) + m.NonLastLevelReadBytes.With(dbNameMetricLabelName, dbName).Set(float64(stats.NonLastLevelReadBytes)) + m.NonLastLevelReadCount.With(dbNameMetricLabelName, dbName).Set(float64(stats.NonLastLevelReadCount)) + + m.GetHitL0.With(dbNameMetricLabelName, dbName).Set(float64(stats.GetHitL0)) + m.GetHitL1.With(dbNameMetricLabelName, dbName).Set(float64(stats.GetHitL1)) + m.GetHitL2AndUp.With(dbNameMetricLabelName, dbName).Set(float64(stats.GetHitL2AndUp)) } diff --git a/opendb.go b/opendb.go index 35e49ab..f59eee6 100644 --- a/opendb.go +++ b/opendb.go @@ -4,15 +4,12 @@ package opendb import ( - "path/filepath" - dbm "github.com/cometbft/cometbft-db" "github.com/cosmos/cosmos-sdk/server/types" ) // OpenDB is a copy of default DBOpener function used by ethermint, see for details: // https://github.com/evmos/ethermint/blob/07cf2bd2b1ce9bdb2e44ec42a39e7239292a14af/server/start.go#L647 -func OpenDB(_ types.AppOptions, home string, backendType dbm.BackendType) (dbm.DB, error) { - dataDir := filepath.Join(home, "data") - return dbm.NewDB("application", backendType, dataDir) +func OpenDB(appOpts types.AppOptions, dataDir string, dbName string, backendType dbm.BackendType) (dbm.DB, error) { + return dbm.NewDB(dbName, backendType, dataDir) } diff --git a/opendb_rocksdb.go b/opendb_rocksdb.go index d4c8f95..492e33c 100644 --- a/opendb_rocksdb.go +++ b/opendb_rocksdb.go @@ -78,19 +78,18 @@ const ( asyncIOReadOptName = "rocksdb.read-async-io" ) -func OpenDB(appOpts types.AppOptions, home string, backendType dbm.BackendType) (dbm.DB, error) { - dataDir := filepath.Join(home, "data") +func OpenDB(appOpts types.AppOptions, dataDir string, dbName string, backendType dbm.BackendType) (dbm.DB, error) { if backendType == dbm.RocksDBBackend { - return openRocksdb(dataDir, appOpts) + return openRocksdb(dataDir, dbName, appOpts) } - return dbm.NewDB("application", backendType, dataDir) + return dbm.NewDB(dbName, backendType, dataDir) } // openRocksdb loads existing options, overrides some of them with appOpts and opens database // option will be overridden only in case if it explicitly specified in appOpts -func openRocksdb(dir string, appOpts types.AppOptions) (dbm.DB, error) { - optionsPath := filepath.Join(dir, "application.db") +func openRocksdb(dir string, dbName string, appOpts types.AppOptions) (dbm.DB, error) { + optionsPath := filepath.Join(dir, dbName+".db") dbOpts, cfOpts, err := LoadLatestOptions(optionsPath) if err != nil { return nil, err @@ -109,7 +108,7 @@ func openRocksdb(dir string, appOpts types.AppOptions) (dbm.DB, error) { reportMetricsIntervalSecs = defaultReportMetricsIntervalSecs } - return newRocksDBWithOptions("application", dir, dbOpts, cfOpts, readOpts, enableMetrics, reportMetricsIntervalSecs) + return newRocksDBWithOptions(dbName, dir, dbOpts, cfOpts, readOpts, enableMetrics, reportMetricsIntervalSecs) } // LoadLatestOptions loads and returns database and column family options @@ -292,7 +291,7 @@ func bbtoFromAppOpts(appOpts types.AppOptions) *grocksdb.BlockBasedTableOptions // newRocksDBWithOptions opens rocksdb with provided database and column family options // newRocksDBWithOptions expects that db has only one column family named default func newRocksDBWithOptions( - name string, + dbName string, dir string, dbOpts *grocksdb.Options, cfOpts *grocksdb.Options, @@ -300,7 +299,7 @@ func newRocksDBWithOptions( enableMetrics bool, reportMetricsIntervalSecs int64, ) (*dbm.RocksDB, error) { - dbPath := filepath.Join(dir, name+".db") + dbPath := filepath.Join(dir, dbName+".db") // Ensure path exists if err := os.MkdirAll(dbPath, 0755); err != nil { @@ -319,7 +318,7 @@ func newRocksDBWithOptions( if enableMetrics { registerMetrics() - go reportMetrics(db, time.Second*time.Duration(reportMetricsIntervalSecs)) + go reportMetrics(dbName, db, time.Second*time.Duration(reportMetricsIntervalSecs)) } wo := grocksdb.NewDefaultWriteOptions() @@ -360,7 +359,7 @@ func defaultBBTO() *grocksdb.BlockBasedTableOptions { // reportMetrics periodically requests stats from rocksdb and reports to prometheus // NOTE: should be launched as a goroutine -func reportMetrics(db *grocksdb.DB, interval time.Duration) { +func reportMetrics(dbName string, db *grocksdb.DB, interval time.Duration) { ticker := time.NewTicker(interval) for { select { @@ -370,7 +369,10 @@ func reportMetrics(db *grocksdb.DB, interval time.Duration) { continue } - rocksdbMetrics.report(props, stats) + if rocksdbMetrics == nil { + continue + } + rocksdbMetrics.report(dbName, props, stats) } } } diff --git a/opendb_rocksdb_test.go b/opendb_rocksdb_test.go index a730e2d..c7ec03e 100644 --- a/opendb_rocksdb_test.go +++ b/opendb_rocksdb_test.go @@ -12,6 +12,8 @@ import ( "github.com/stretchr/testify/require" ) +const defaultDBName = "application" + type mockAppOptions struct { opts map[string]interface{} } @@ -79,7 +81,7 @@ func TestOpenRocksdb(t *testing.T) { require.NoError(t, err) }() - db, err := openRocksdb(dir, tc.mockAppOptions) + db, err := openRocksdb(dir, defaultDBName, tc.mockAppOptions) require.NoError(t, err) require.NoError(t, db.Close()) @@ -104,7 +106,7 @@ func TestOpenRocksdb(t *testing.T) { }() mockAppOpts := newMockAppOptions(map[string]interface{}{}) - db, err := openRocksdb(dir, mockAppOpts) + db, err := openRocksdb(dir, defaultDBName, mockAppOpts) require.NoError(t, err) require.NoError(t, db.Close())