diff --git a/src/database/engine.rs b/src/database/engine.rs index 7fd48a7d9..a0a99ad60 100644 --- a/src/database/engine.rs +++ b/src/database/engine.rs @@ -6,7 +6,6 @@ mod files; mod logger; mod memory_usage; -pub use memory_usage::MemoryUsage; mod open; mod repair; diff --git a/src/database/engine/memory_usage.rs b/src/database/engine/memory_usage.rs index b3fe44c54..e13166d1c 100644 --- a/src/database/engine/memory_usage.rs +++ b/src/database/engine/memory_usage.rs @@ -10,13 +10,13 @@ pub struct MemoryUsage { pub mem_table_unflushed: u64, pub mem_table_readers_total: u64, pub row_cache: u64, - pub col_caches: Vec<(String, u64)>, } impl super::Engine { pub fn memory_usage(&self) -> Result { let mut res = String::new(); let stats = self.memory_usage_stats()?; + let col_caches = self.col_cache_usage()?; let mibs = |input| f64::from(u32::try_from(input / 1024).unwrap_or(0)) / 1024.0; writeln!( res, @@ -28,7 +28,7 @@ pub fn memory_usage(&self) -> Result { mibs(stats.row_cache), )?; - for (name, usage) in stats.col_caches { + for (name, usage) in col_caches { writeln!(res, "{name} cache: {:.2} MiB", mibs(usage))?; } @@ -40,20 +40,20 @@ pub fn memory_usage_stats(&self) -> Result { get_memory_usage_stats(Some(&[&self.db]), Some(&[&*self.ctx.row_cache.lock()])) .or_else(or_else)?; - let col_caches = self - .ctx - .col_cache - .lock() - .iter() - .map(|(name, cache)| Ok((name.clone(), u64::try_from(cache.get_usage())?))) - .collect::>()?; - Ok(MemoryUsage { mem_table_total: stats.mem_table_total, mem_table_unflushed: stats.mem_table_unflushed, mem_table_readers_total: stats.mem_table_readers_total, row_cache: u64::try_from(self.ctx.row_cache.lock().get_usage())?, - col_caches, }) } + + pub fn col_cache_usage(&self) -> Result> { + self.ctx + .col_cache + .lock() + .iter() + .map(|(name, cache)| Ok((name.clone(), u64::try_from(cache.get_usage())?))) + .collect() + } } diff --git a/src/database/mod.rs b/src/database/mod.rs index e6585319c..fcc4f4df7 100644 --- a/src/database/mod.rs +++ b/src/database/mod.rs @@ -33,7 +33,6 @@ pub use self::{ de::{Ignore, IgnoreAll}, deserialized::Deserialized, - engine::MemoryUsage, handle::Handle, keyval::{KeyVal, Slice, serialize_key, serialize_val}, map::{Get, Map, Qry, compact}, diff --git a/src/service/metrics.rs b/src/service/metrics.rs index 4a25c4d23..a1291de06 100644 --- a/src/service/metrics.rs +++ b/src/service/metrics.rs @@ -1,20 +1,12 @@ -use std::{ - sync::{Arc, Mutex}, - time::{Duration, Instant}, -}; +use std::sync::Arc; use conduwuit::{ metrics::{AsyncInstrument, KeyValue}, utils::millis_since_unix_epoch, }; -use database::MemoryUsage; use crate::Services; -/// Both database memory gauges are collected in the same scrape, so the -/// statistics are shared between them for this long. -const MEMORY_USAGE_TTL: Duration = Duration::from_secs(1); - impl Services { pub(crate) fn register_metrics(self: &Arc) { self.gauge( @@ -80,14 +72,12 @@ pub(crate) fn register_metrics(self: &Arc) { }, ); - let memory = Arc::new(MemoryUsageCache::default()); - let block_cache_memory = memory.clone(); self.gauge( "continuwuity.database.memory", "RocksDB memory usage by component", "By", - move |services, observer| { - let Some(usage) = memory.get(services) else { + |services, observer| { + let Ok(usage) = services.db.db.memory_usage_stats() else { return; }; @@ -106,13 +96,13 @@ pub(crate) fn register_metrics(self: &Arc) { "continuwuity.database.block_cache", "RocksDB block cache usage by column family", "By", - move |services, observer| { - let Some(usage) = block_cache_memory.get(services) else { + |services, observer| { + let Ok(col_caches) = services.db.db.col_cache_usage() else { return; }; - for (column, bytes) in &usage.col_caches { - observer.observe(*bytes, &[KeyValue::new("column", column.clone())]); + for (column, bytes) in col_caches { + observer.observe(bytes, &[KeyValue::new("column", column)]); } }, ); @@ -173,24 +163,6 @@ fn gauge( } } -#[derive(Default)] -struct MemoryUsageCache(Mutex)>>); - -impl MemoryUsageCache { - fn get(&self, services: &Services) -> Option> { - let mut cached = self.0.lock().expect("locked"); - if let Some((at, usage)) = &*cached { - if at.elapsed() < MEMORY_USAGE_TTL { - return Some(usage.clone()); - } - } - - let usage = Arc::new(services.db.db.memory_usage_stats().ok()?); - *cached = Some((Instant::now(), usage.clone())); - Some(usage) - } -} - /// Cheap estimate from RocksDB properties, unlike iterating the column. fn estimate_keys(services: &Services, map: &'static str) -> Option { services