-
Notifications
You must be signed in to change notification settings - Fork 455
Filter out WiredTiger LSM tree metrics — MongoDB exclusively uses B-Tree, these are always zero #1247
Description
Describe the bug
The exporter emits WiredTiger LSM (Log-Structured Merge) tree statistics from collStats, serverStatus, and oplog responses. These metrics are structurally impossible to ever be non-zero in any MongoDB deployment.
MongoDB exclusively uses WiredTiger's B-Tree (type=file) data structure. There is no mongod configuration option, no storage engine parameter, and no version of MongoDB that has ever supported LSM trees. WiredTiger's internal stats struct includes counters for all data structure types it supports (B-Tree, LSM, column store) regardless of which one the actual table uses. The exporter walks the BSON response and turns every field into a Prometheus metric without filtering out inapplicable ones.
Result: 85 always-zero LSM series per scrape on a deployment with 71 collections. These are 12 unique WiredTiger LSM stat types repeated across 4 sources:
| Source | LSM series | Collector |
|---|---|---|
config.transactions collStats |
36 | --collector.collstats |
config.image_collection collStats |
24 | --collector.collstats |
serverStatus.wiredTiger |
13 | --collector.diagnosticdata |
| oplog collStats | 12 | oplog stats |
| Total | 85 |
The 12 unique LSM stat types are:
LSM_bloom_filter_false_positives
LSM_bloom_filter_hits
LSM_bloom_filter_misses
LSM_bloom_filter_pages_evicted_from_cache
LSM_bloom_filter_pages_read_into_cache
LSM_bloom_filters_in_the_LSM_tree
LSM_chunks_in_the_LSM_tree
LSM_highest_merge_generation_in_the_LSM_tree
LSM_queries_that_could_have_benefited_from_a_Bloom_filter_that_did_not_exist
LSM_sleep_for_LSM_checkpoint_throttle
LSM_sleep_for_LSM_merge_throttle
LSM_total_size_of_bloom_filters
Plus one from serverStatus: mongodb_ss_wt_thread_yield_connection_close_yielded_for_lsm_manager_shutdown
This matters because:
- Deployments using per-target series limits (e.g., VMAgent
seriesLimitPerTarget) have dead LSM series consuming budget that could displace meaningful metrics like replication lag or opcounters. - These are not "currently zero" — they are architecturally impossible to be non-zero. Unlike
queryableEncryptionLatencyMicros(non-zero if QE is enabled) orcolumn_store_*(non-zero with columnstore indexes on MongoDB 7.0+), no MongoDB feature or configuration can activate WiredTiger LSM code paths.
To Reproduce
- Start
mongodb_exporterwith collstats and diagnosticdata collectors enabled (the defaults):mongodb_exporter --mongodb.uri=mongodb://localhost:27017 \ --collector.collstats \ --collector.diagnosticdata - Scrape the
/metricsendpoint and filter for LSM:curl -s http://localhost:9216/metrics | grep -v '^#' | grep -i '_LSM_' | wc -l # Result: ~85 (varies with number of collections)
- Verify all are zero:
curl -s http://localhost:9216/metrics | grep -v '^#' | grep -i '_LSM_' \ | awk '{if($NF!="0") print "NON-ZERO: "$0}' # Result: (empty — no output, all are zero)
Expected behavior
WiredTiger LSM tree stats should not be emitted as Prometheus metrics. MongoDB hardcodes B-Tree (type=file) when creating WiredTiger tables. The LSM code paths inside WiredTiger are dead code in the MongoDB context. These counters can never be incremented.
A filter like the following in the metric-building code would eliminate them:
func shouldSkipWTStat(name string) bool {
lower := strings.ToLower(name)
return strings.Contains(lower, "_lsm_") || strings.Contains(lower, "_lsm ")
}This would affect the metric-building loops in the collstats, diagnostic_data, and oplog collectors.
Scope note: This issue is intentionally scoped to LSM only. Other WiredTiger stats that are zero on many deployments but could be non-zero in valid configurations are excluded:
column_store_*— MongoDB 7.0+ supports columnstore indexes which use WiredTiger column store. Not safe to unconditionally filter.queryableEncryptionLatencyMicros— non-zero when Queryable Encryption is enabled. Not safe to unconditionally filter.
Logs
Sample metrics output showing always-zero LSM series:
mongodb_config_transactions_stats_storageStats_wiredTiger_LSM_bloom_filter_hits 0
mongodb_config_transactions_stats_storageStats_wiredTiger_LSM_chunks_in_the_LSM_tree 0
mongodb_config_transactions_stats_storageStats_indexDetails_index_name_LSM_bloom_filter_false_positives 0
mongodb_config_transactions_stats_storageStats_indexDetails_index_name_LSM_queries_that_could_have_benefited_from_a_Bloom_filter_that_did_not_exist 0
mongodb_config_image_collection_stats_storageStats_wiredTiger_LSM_bloom_filter_misses 0
mongodb_oplog_stats_wt_LSM_bloom_filter_hits 0
mongodb_oplog_stats_wt_LSM_chunks_in_the_LSM_tree 0
mongodb_ss_wt_historyStorageStats_LSM_bloom_filter_false_positives 0
mongodb_ss_wt_thread_yield_connection_close_yielded_for_lsm_manager_shutdown 0
Full exporter output: 9,926 total series, 6,395 zero-valued (64%). The 85 LSM series above are part of the zero-valued set and are the subset that are not just "currently zero" but "architecturally cannot be non-zero."
Environment
- OS: Ubuntu 22.04.5 LTS (Jammy Jellyfish), kernel 5.15.0-72-generic, x86_64
- Environment: Kubernetes (3-member MongoDB replica set, exporter running as sidecar)
- MongoDB version: 8.0
- mongodb_exporter version: v0.47.2 (commit 43a703c, build date 2025-11-25)
- WiredTiger: B-Tree row-store (default, the only option MongoDB supports)
- Deployment: 71 user collections across 9 databases
Additional context
The total exporter output on this deployment is 9,926 series. On deployments with per-target series limits, the exporter already exceeds common caps. Dead LSM series that survive the limit displace actually useful metrics. The 85 series are small individually, but they represent a broader pattern — the exporter faithfully exports every WiredTiger internal stat without checking whether the stat is applicable to the table type MongoDB uses.
The proposed fix is ~8 lines of Go and eliminates 85 series. Happy to submit a PR if this approach is acceptable.