Skip to content

Filter out WiredTiger LSM tree metrics — MongoDB exclusively uses B-Tree, these are always zero #1247

@vyalamar

Description

@vyalamar

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) or column_store_* (non-zero with columnstore indexes on MongoDB 7.0+), no MongoDB feature or configuration can activate WiredTiger LSM code paths.

To Reproduce

  1. Start mongodb_exporter with collstats and diagnosticdata collectors enabled (the defaults):
    mongodb_exporter --mongodb.uri=mongodb://localhost:27017 \
      --collector.collstats \
      --collector.diagnosticdata
    
  2. Scrape the /metrics endpoint and filter for LSM:
    curl -s http://localhost:9216/metrics | grep -v '^#' | grep -i '_LSM_' | wc -l
    # Result: ~85 (varies with number of collections)
  3. 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.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions