From 77ae79396f944c0c6d87f522e300fcc2c9a2396a Mon Sep 17 00:00:00 2001 From: Ginger Date: Tue, 16 Dec 2025 09:49:13 -0500 Subject: [PATCH] feat: Use OptimisticTransactionDB for the database engine --- src/core/config/mod.rs | 6 ------ src/database/engine.rs | 14 ++------------ src/database/engine/backup.rs | 3 +-- src/database/engine/memory_usage.rs | 17 +++++++++++------ src/database/engine/open.rs | 11 +---------- src/database/map/insert.rs | 2 +- src/database/mod.rs | 8 -------- src/service/emergency/mod.rs | 4 ---- src/service/globals/mod.rs | 3 --- src/service/services.rs | 4 ++-- 10 files changed, 18 insertions(+), 54 deletions(-) diff --git a/src/core/config/mod.rs b/src/core/config/mod.rs index fbb29357..14b6066c 100644 --- a/src/core/config/mod.rs +++ b/src/core/config/mod.rs @@ -1224,12 +1224,6 @@ pub struct Config { #[serde(default)] pub rocksdb_repair: bool, - #[serde(default)] - pub rocksdb_read_only: bool, - - #[serde(default)] - pub rocksdb_secondary: bool, - /// Enables idle CPU priority for compaction thread. This is not enabled by /// default to prevent compaction from falling too far behind on busy /// systems. diff --git a/src/database/engine.rs b/src/database/engine.rs index 38dd7512..badfeab4 100644 --- a/src/database/engine.rs +++ b/src/database/engine.rs @@ -19,7 +19,7 @@ use std::{ use conduwuit::{Err, Result, debug, info, warn}; use rocksdb::{ - AsColumnFamilyRef, BoundColumnFamily, DBCommon, DBWithThreadMode, MultiThreaded, + AsColumnFamilyRef, BoundColumnFamily, DBCommon, MultiThreaded, OptimisticTransactionDB, WaitForCompactOptions, }; @@ -33,13 +33,11 @@ pub struct Engine { pub(crate) db: Db, pub(crate) pool: Arc, pub(crate) ctx: Arc, - pub(super) read_only: bool, - pub(super) secondary: bool, pub(crate) checksums: bool, corks: AtomicU32, } -pub(crate) type Db = DBWithThreadMode; +pub(crate) type Db = OptimisticTransactionDB; impl Engine { #[tracing::instrument( @@ -129,14 +127,6 @@ impl Engine { sequence } - - #[inline] - #[must_use] - pub fn is_read_only(&self) -> bool { self.secondary || self.read_only } - - #[inline] - #[must_use] - pub fn is_secondary(&self) -> bool { self.secondary } } impl Drop for Engine { diff --git a/src/database/engine/backup.rs b/src/database/engine/backup.rs index 4cdb6172..8626d7e4 100644 --- a/src/database/engine/backup.rs +++ b/src/database/engine/backup.rs @@ -12,9 +12,8 @@ pub fn backup(&self) -> Result { let mut engine = self.backup_engine()?; let config = &self.ctx.server.config; if config.database_backups_to_keep > 0 { - let flush = !self.is_read_only(); engine - .create_new_backup_flush(&self.db, flush) + .create_new_backup_flush(&self.db, true) .map_err(map_err)?; let engine_info = engine.get_backup_info(); diff --git a/src/database/engine/memory_usage.rs b/src/database/engine/memory_usage.rs index 21af35c8..3acdf969 100644 --- a/src/database/engine/memory_usage.rs +++ b/src/database/engine/memory_usage.rs @@ -1,7 +1,7 @@ use std::fmt::Write; use conduwuit::{Result, implement}; -use rocksdb::perf::get_memory_usage_stats; +use rocksdb::perf::MemoryUsageBuilder; use super::Engine; use crate::or_else; @@ -9,16 +9,21 @@ use crate::or_else; #[implement(Engine)] pub fn memory_usage(&self) -> Result { let mut res = String::new(); - let stats = get_memory_usage_stats(Some(&[&self.db]), Some(&[&*self.ctx.row_cache.lock()])) - .or_else(or_else)?; + + let mut builder = MemoryUsageBuilder::new().or_else(or_else)?; + builder.add_db(&self.db); + builder.add_cache(&self.ctx.row_cache.lock()); + + let usage = builder.build().or_else(or_else)?; + let mibs = |input| f64::from(u32::try_from(input / 1024).unwrap_or(0)) / 1024.0; writeln!( res, "Memory buffers: {:.2} MiB\nPending write: {:.2} MiB\nTable readers: {:.2} MiB\nRow \ cache: {:.2} MiB", - mibs(stats.mem_table_total), - mibs(stats.mem_table_unflushed), - mibs(stats.mem_table_readers_total), + mibs(usage.approximate_mem_table_total()), + mibs(usage.approximate_mem_table_unflushed()), + mibs(usage.approximate_mem_table_readers_total()), mibs(u64::try_from(self.ctx.row_cache.lock().get_usage())?), )?; diff --git a/src/database/engine/open.rs b/src/database/engine/open.rs index 7b9d93c2..04690133 100644 --- a/src/database/engine/open.rs +++ b/src/database/engine/open.rs @@ -35,14 +35,7 @@ pub(crate) async fn open(ctx: Arc, desc: &[Descriptor]) -> Result, desc: &[Descriptor]) -> Result + Sized + Debug + 'a, V: AsRef<[u8]> + Sized + 'a, { - let mut batch = WriteBatchWithTransaction::::default(); + let mut batch = WriteBatchWithTransaction::::default(); for (key, val) in iter { batch.put_cf(&self.cf(), key.as_ref(), val.as_ref()); } diff --git a/src/database/mod.rs b/src/database/mod.rs index 7932fbcb..a3f03b27 100644 --- a/src/database/mod.rs +++ b/src/database/mod.rs @@ -77,14 +77,6 @@ impl Database { #[inline] pub fn keys(&self) -> impl Iterator + Send + '_ { self.maps.keys() } - - #[inline] - #[must_use] - pub fn is_read_only(&self) -> bool { self.db.is_read_only() } - - #[inline] - #[must_use] - pub fn is_secondary(&self) -> bool { self.db.is_secondary() } } impl Index<&str> for Database { diff --git a/src/service/emergency/mod.rs b/src/service/emergency/mod.rs index f8ecbb3e..9dc6fbe4 100644 --- a/src/service/emergency/mod.rs +++ b/src/service/emergency/mod.rs @@ -37,10 +37,6 @@ impl crate::Service for Service { } async fn worker(self: Arc) -> Result { - if self.services.globals.is_read_only() { - return Ok(()); - } - if self.services.config.ldap.enable { warn!("emergency password feature not available with LDAP enabled."); return Ok(()); diff --git a/src/service/globals/mod.rs b/src/service/globals/mod.rs index f5c99158..5c8f5b5d 100644 --- a/src/service/globals/mod.rs +++ b/src/service/globals/mod.rs @@ -171,7 +171,4 @@ impl Service { pub fn server_is_ours(&self, server_name: &ServerName) -> bool { server_name == self.server_name() } - - #[inline] - pub fn is_read_only(&self) -> bool { self.db.db.is_read_only() } } diff --git a/src/service/services.rs b/src/service/services.rs index 642f61c7..1148f9d8 100644 --- a/src/service/services.rs +++ b/src/service/services.rs @@ -130,7 +130,7 @@ impl Services { // reset dormant online/away statuses to offline, and set the server user as // online - if self.server.config.allow_local_presence && !self.db.is_read_only() { + if self.server.config.allow_local_presence { self.presence.unset_all_presence().await; _ = self .presence @@ -146,7 +146,7 @@ impl Services { info!("Shutting down services..."); // set the server user as offline - if self.server.config.allow_local_presence && !self.db.is_read_only() { + if self.server.config.allow_local_presence { _ = self .presence .ping_presence(&self.globals.server_user, &ruma::presence::PresenceState::Offline)