Skip to content

Commit 8701bcc

Browse files
committed
Add exporter for RocksDB context metrics
Signed-off-by: Vladimir Buyanov <[email protected]>
1 parent 281aec8 commit 8701bcc

File tree

3 files changed

+275
-0
lines changed

3 files changed

+275
-0
lines changed

README.md

+1
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,7 @@ collect.info_schema.processlist | 5.1 | C
109109
collect.info_schema.processlist.min_time | 5.1 | Minimum time a thread must be in each state to be counted. (default: 0)
110110
collect.info_schema.query_response_time | 5.5 | Collect query response time distribution if query_response_time_stats is ON.
111111
collect.info_schema.replica_host | 5.6 | Collect metrics from information_schema.replica_host_status.
112+
collect.info_schema.rocksdb_perf_context | 5.6 | Collect RocksDB metrics from information_schema.ROCKSDB_PERF_CONTEXT.
112113
collect.info_schema.tables | 5.1 | Collect metrics from information_schema.tables.
113114
collect.info_schema.tables.databases | 5.1 | The list of databases to collect table stats for, or '`*`' for all.
114115
collect.info_schema.tablestats | 5.1 | If running with userstat=1, set to true to collect table statistics.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,273 @@
1+
// Copyright 2025 The Prometheus Authors
2+
// Licensed under the Apache License, Version 2.0 (the "License");
3+
// you may not use this file except in compliance with the License.
4+
// You may obtain a copy of the License at
5+
//
6+
// http://www.apache.org/licenses/LICENSE-2.0
7+
//
8+
// Unless required by applicable law or agreed to in writing, software
9+
// distributed under the License is distributed on an "AS IS" BASIS,
10+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11+
// See the License for the specific language governing permissions and
12+
// limitations under the License.
13+
14+
// Scrape `information_schema.ROCKSDB_PERF_CONTEXT`.
15+
16+
package collector
17+
18+
import (
19+
"context"
20+
"log/slog"
21+
22+
"github.com/prometheus/client_golang/prometheus"
23+
)
24+
25+
const rocksdbPerfContextQuery = `
26+
SELECT
27+
TABLE_SCHEMA,
28+
TABLE_NAME,
29+
ifnull(PARTITION_NAME, ''),
30+
STAT_TYPE,
31+
VALUE
32+
FROM information_schema.ROCKSDB_PERF_CONTEXT
33+
`
34+
35+
// Metric descriptors.
36+
var informationSchemaRocksDBLabels = []string{"schema", "table", "part"}
37+
var informationSchemaRocksDBPerfContextMetrics = map[string]struct {
38+
vtype prometheus.ValueType
39+
desc *prometheus.Desc
40+
}{
41+
"USER_KEY_COMPARISON_COUNT": {
42+
prometheus.CounterValue,
43+
prometheus.NewDesc(
44+
prometheus.BuildFQName(namespace, informationSchema, "rocksdb_perf_context_user_key_comparison_count"),
45+
"Total number of user key comparisons performed in binary search.",
46+
informationSchemaRocksDBLabels, nil,
47+
),
48+
},
49+
"BLOCK_CACHE_HIT_COUNT": {
50+
prometheus.CounterValue,
51+
prometheus.NewDesc(
52+
prometheus.BuildFQName(namespace, informationSchema, "rocksdb_perf_context_block_cache_hit_count"),
53+
"Total number of block read operations from cache.",
54+
informationSchemaRocksDBLabels, nil,
55+
),
56+
},
57+
"BLOCK_READ_COUNT": {
58+
prometheus.CounterValue,
59+
prometheus.NewDesc(
60+
prometheus.BuildFQName(namespace, informationSchema, "rocksdb_perf_context_block_read_count"),
61+
"Total number of block read operations from disk.",
62+
informationSchemaRocksDBLabels, nil,
63+
),
64+
},
65+
"BLOCK_READ_BYTE": {
66+
prometheus.CounterValue,
67+
prometheus.NewDesc(
68+
prometheus.BuildFQName(namespace, informationSchema, "rocksdb_perf_context_block_read_byte"),
69+
"Total number of bytes read from disk.",
70+
informationSchemaRocksDBLabels, nil,
71+
),
72+
},
73+
"GET_READ_BYTES": {
74+
prometheus.CounterValue,
75+
prometheus.NewDesc(
76+
prometheus.BuildFQName(namespace, informationSchema, "rocksdb_perf_context_get_read_bytes"),
77+
"Number of bytes read during Get operations.",
78+
informationSchemaRocksDBLabels, nil,
79+
),
80+
},
81+
"MULTIGET_READ_BYTES": {
82+
prometheus.CounterValue,
83+
prometheus.NewDesc(
84+
prometheus.BuildFQName(namespace, informationSchema, "rocksdb_perf_context_multiget_read_bytes"),
85+
"Number of bytes read during MultiGet operations.",
86+
informationSchemaRocksDBLabels, nil,
87+
),
88+
},
89+
"ITER_READ_BYTES": {
90+
prometheus.CounterValue,
91+
prometheus.NewDesc(
92+
prometheus.BuildFQName(namespace, informationSchema, "rocksdb_perf_context_iter_read_bytes"),
93+
"Number of bytes read during iterator operations.",
94+
informationSchemaRocksDBLabels, nil,
95+
),
96+
},
97+
"INTERNAL_KEY_SKIPPED_COUNT": {
98+
prometheus.CounterValue,
99+
prometheus.NewDesc(
100+
prometheus.BuildFQName(namespace, informationSchema, "rocksdb_perf_context_internal_key_skipped_count"),
101+
"Count of internal keys skipped during operations.",
102+
informationSchemaRocksDBLabels, nil,
103+
),
104+
},
105+
"INTERNAL_DELETE_SKIPPED_COUNT": {
106+
prometheus.CounterValue,
107+
prometheus.NewDesc(
108+
prometheus.BuildFQName(namespace, informationSchema, "rocksdb_perf_context_internal_delete_skipped_count"),
109+
"Count of internal delete operations that were skipped.",
110+
informationSchemaRocksDBLabels, nil,
111+
),
112+
},
113+
"INTERNAL_RECENT_SKIPPED_COUNT": {
114+
prometheus.CounterValue,
115+
prometheus.NewDesc(
116+
prometheus.BuildFQName(namespace, informationSchema, "rocksdb_perf_context_internal_recent_skipped_count"),
117+
"Count of recently skipped internal operations.",
118+
informationSchemaRocksDBLabels, nil,
119+
),
120+
},
121+
"INTERNAL_MERGE_COUNT": {
122+
prometheus.CounterValue,
123+
prometheus.NewDesc(
124+
prometheus.BuildFQName(namespace, informationSchema, "rocksdb_perf_context_internal_merge_count"),
125+
"Total number of internal merge operations.",
126+
informationSchemaRocksDBLabels, nil,
127+
),
128+
},
129+
"GET_FROM_MEMTABLE_COUNT": {
130+
prometheus.CounterValue,
131+
prometheus.NewDesc(
132+
prometheus.BuildFQName(namespace, informationSchema, "rocksdb_perf_context_get_from_memtable_count"),
133+
"Number of Get operations served from the memtable.",
134+
informationSchemaRocksDBLabels, nil,
135+
),
136+
},
137+
"SEEK_ON_MEMTABLE_COUNT": {
138+
prometheus.CounterValue,
139+
prometheus.NewDesc(
140+
prometheus.BuildFQName(namespace, informationSchema, "rocksdb_perf_context_seek_on_memtable_count"),
141+
"Count of seek operations in the memtable.",
142+
informationSchemaRocksDBLabels, nil,
143+
),
144+
},
145+
"NEXT_ON_MEMTABLE_COUNT": {
146+
prometheus.CounterValue,
147+
prometheus.NewDesc(
148+
prometheus.BuildFQName(namespace, informationSchema, "rocksdb_perf_context_next_on_memtable_count"),
149+
"Count of next operations in the memtable.",
150+
informationSchemaRocksDBLabels, nil,
151+
),
152+
},
153+
"PREV_ON_MEMTABLE_COUNT": {
154+
prometheus.CounterValue,
155+
prometheus.NewDesc(
156+
prometheus.BuildFQName(namespace, informationSchema, "rocksdb_perf_context_prev_on_memtable_count"),
157+
"Count of previous operations in the memtable.",
158+
informationSchemaRocksDBLabels, nil,
159+
),
160+
},
161+
"SEEK_CHILD_SEEK_COUNT": {
162+
prometheus.CounterValue,
163+
prometheus.NewDesc(
164+
prometheus.BuildFQName(namespace, informationSchema, "rocksdb_perf_context_seek_child_seek_count"),
165+
"Count of child seek operations in RocksDB.",
166+
informationSchemaRocksDBLabels, nil,
167+
),
168+
},
169+
"BLOOM_MEMTABLE_HIT_COUNT": {
170+
prometheus.CounterValue,
171+
prometheus.NewDesc(
172+
prometheus.BuildFQName(namespace, informationSchema, "rocksdb_perf_context_bloom_memtable_hit_count"),
173+
"Count of successful hits in the bloom filter for memtable searches.",
174+
informationSchemaRocksDBLabels, nil,
175+
),
176+
},
177+
"BLOOM_MEMTABLE_MISS_COUNT": {
178+
prometheus.CounterValue,
179+
prometheus.NewDesc(
180+
prometheus.BuildFQName(namespace, informationSchema, "rocksdb_perf_context_bloom_memtable_miss_count"),
181+
"Count of misses in the bloom filter for memtable searches.",
182+
informationSchemaRocksDBLabels, nil,
183+
),
184+
},
185+
"BLOOM_SST_HIT_COUNT": {
186+
prometheus.CounterValue,
187+
prometheus.NewDesc(
188+
prometheus.BuildFQName(namespace, informationSchema, "rocksdb_perf_context_bloom_sst_hit_count"),
189+
"Count of successful hits in the bloom filter for SSTable searches.",
190+
informationSchemaRocksDBLabels, nil,
191+
),
192+
},
193+
"BLOOM_SST_MISS_COUNT": {
194+
prometheus.CounterValue,
195+
prometheus.NewDesc(
196+
prometheus.BuildFQName(namespace, informationSchema, "rocksdb_perf_context_bloom_sst_miss_count"),
197+
"Count of misses in the bloom filter for SSTable searches.",
198+
informationSchemaRocksDBLabels, nil,
199+
),
200+
},
201+
"KEY_LOCK_WAIT_COUNT": {
202+
prometheus.CounterValue,
203+
prometheus.NewDesc(
204+
prometheus.BuildFQName(namespace, informationSchema, "rocksdb_perf_context_key_lock_wait_count"),
205+
"Count of key lock wait events in RocksDB.",
206+
informationSchemaRocksDBLabels, nil,
207+
),
208+
},
209+
"IO_BYTES_WRITTEN": {
210+
prometheus.CounterValue,
211+
prometheus.NewDesc(
212+
prometheus.BuildFQName(namespace, informationSchema, "rocksdb_perf_context_io_bytes_written"),
213+
"Total number of bytes written by I/O operations in RocksDB.",
214+
informationSchemaRocksDBLabels, nil,
215+
),
216+
},
217+
"IO_BYTES_READ": {
218+
prometheus.CounterValue,
219+
prometheus.NewDesc(
220+
prometheus.BuildFQName(namespace, informationSchema, "rocksdb_perf_context_io_bytes_read"),
221+
"Total number of bytes read by I/O operations in RocksDB.",
222+
informationSchemaRocksDBLabels, nil,
223+
),
224+
},
225+
}
226+
227+
// ScrapeInnodbCmp collects from `information_schema.innodb_cmp`.
228+
type ScrapeRocksDBPerfContext struct{}
229+
230+
// Name of the Scraper. Should be unique.
231+
func (ScrapeRocksDBPerfContext) Name() string {
232+
return informationSchema + ".rocksdb_perf_context"
233+
}
234+
235+
// Help describes the role of the Scraper.
236+
func (ScrapeRocksDBPerfContext) Help() string {
237+
return "Collect metrics from information_schema.ROCKSDB_PERF_CONTEXT"
238+
}
239+
240+
// Version of MySQL from which scraper is available.
241+
func (ScrapeRocksDBPerfContext) Version() float64 {
242+
return 5.6
243+
}
244+
245+
// Scrape collects data from database connection and sends it over channel as prometheus metric.
246+
func (ScrapeRocksDBPerfContext) Scrape(ctx context.Context, instance *instance, ch chan<- prometheus.Metric, logger *slog.Logger) error {
247+
db := instance.getDB()
248+
informationSchemaInnodbCmpMemRows, err := db.QueryContext(ctx, rocksdbPerfContextQuery)
249+
if err != nil {
250+
return err
251+
}
252+
defer informationSchemaInnodbCmpMemRows.Close()
253+
254+
var (
255+
schema, table, part, stat string
256+
value float64
257+
)
258+
259+
for informationSchemaInnodbCmpMemRows.Next() {
260+
if err := informationSchemaInnodbCmpMemRows.Scan(
261+
&schema, &table, &part, &stat, &value,
262+
); err != nil {
263+
return err
264+
}
265+
if v, ok := informationSchemaRocksDBPerfContextMetrics[stat]; ok {
266+
ch <- prometheus.MustNewConstMetric(v.desc, v.vtype, value, schema, table, part)
267+
}
268+
}
269+
return nil
270+
}
271+
272+
// check interface
273+
var _ Scraper = ScrapeRocksDBPerfContext{}

mysqld_exporter.go

+1
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,7 @@ var scrapers = map[collector.Scraper]bool{
104104
collector.ScrapeHeartbeat{}: false,
105105
collector.ScrapeSlaveHosts{}: false,
106106
collector.ScrapeReplicaHost{}: false,
107+
collector.ScrapeRocksDBPerfContext{}: false,
107108
}
108109

109110
func filterScrapers(scrapers []collector.Scraper, collectParams []string) []collector.Scraper {

0 commit comments

Comments
 (0)