mirror of
https://github.com/scsibug/nostr-rs-relay.git
synced 2024-11-22 09:09:07 -05:00
feat: perform full checkpoints and truncate WAL every 2k events
This commit is contained in:
parent
ea204761c9
commit
168cf513ac
60
src/db.rs
60
src/db.rs
|
@ -38,9 +38,10 @@ pub struct SubmittedEvent {
|
||||||
|
|
||||||
/// Database file
|
/// Database file
|
||||||
pub const DB_FILE: &str = "nostr.db";
|
pub const DB_FILE: &str = "nostr.db";
|
||||||
/// How many persisted events before optimization is triggered
|
/// How many persisted events before DB maintenannce is triggered.
|
||||||
pub const EVENT_COUNT_OPTIMIZE_TRIGGER: usize = 500;
|
pub const EVENT_COUNT_MAINTENANCE_TRIGGER: usize = 2000;
|
||||||
/// How many persisted events before we pause for backups
|
/// How many persisted events before we pause for backups.
|
||||||
|
/// It isn't clear this is enough to make the online backup API work yet.
|
||||||
pub const EVENT_COUNT_BACKUP_PAUSE_TRIGGER: usize = 1000;
|
pub const EVENT_COUNT_BACKUP_PAUSE_TRIGGER: usize = 1000;
|
||||||
|
|
||||||
/// Build a database connection pool.
|
/// Build a database connection pool.
|
||||||
|
@ -95,6 +96,38 @@ pub fn optimize_db(conn: &mut PooledConnection) -> Result<()> {
|
||||||
conn.execute_batch("PRAGMA optimize;")?;
|
conn.execute_batch("PRAGMA optimize;")?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
#[derive(Debug)]
|
||||||
|
enum SqliteReturnStatus {
|
||||||
|
SqliteOk,
|
||||||
|
SqliteBusy,
|
||||||
|
SqliteError,
|
||||||
|
SqliteOther(u64),
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Checkpoint/Truncate WAL
|
||||||
|
pub fn checkpoint_db(conn: &mut PooledConnection) -> Result<()> {
|
||||||
|
let query = "PRAGMA wal_checkpoint(TRUNCATE);";
|
||||||
|
let start = Instant::now();
|
||||||
|
let (cp_result, wal_size, _frames_checkpointed) = conn.query_row(query, [], |row| {
|
||||||
|
let checkpoint_result: u64 = row.get(0)?;
|
||||||
|
let wal_size: u64 = row.get(1)?;
|
||||||
|
let frames_checkpointed: u64 = row.get(2)?;
|
||||||
|
Ok((checkpoint_result, wal_size, frames_checkpointed))
|
||||||
|
})?;
|
||||||
|
let result = match cp_result {
|
||||||
|
0 => SqliteReturnStatus::SqliteOk,
|
||||||
|
1 => SqliteReturnStatus::SqliteBusy,
|
||||||
|
2 => SqliteReturnStatus::SqliteError,
|
||||||
|
x => SqliteReturnStatus::SqliteOther(x),
|
||||||
|
};
|
||||||
|
info!(
|
||||||
|
"checkpoint ran in {:?} (result: {:?}, WAL size: {})",
|
||||||
|
start.elapsed(),
|
||||||
|
result,
|
||||||
|
wal_size
|
||||||
|
);
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
/// Spawn a database writer that persists events to the SQLite store.
|
/// Spawn a database writer that persists events to the SQLite store.
|
||||||
pub async fn db_writer(
|
pub async fn db_writer(
|
||||||
|
@ -135,9 +168,12 @@ pub async fn db_writer(
|
||||||
let rps_setting = settings.limits.messages_per_sec;
|
let rps_setting = settings.limits.messages_per_sec;
|
||||||
let mut most_recent_rate_limit = Instant::now();
|
let mut most_recent_rate_limit = Instant::now();
|
||||||
let mut lim_opt = None;
|
let mut lim_opt = None;
|
||||||
// Keep rough track of events so we can run optimize eventually.
|
// Keep rough track of events so we can run maintenance
|
||||||
let mut optimize_counter: usize = 0;
|
// eventually.
|
||||||
// Constant writing has interfered with online backups. Keep track of how long since we've given the backups a chance to run.
|
let mut maintenance_counter: usize = 0;
|
||||||
|
// Constant writing has interfered with online backups. Keep
|
||||||
|
// track of how long since we've given the backups a chance to
|
||||||
|
// run.
|
||||||
let mut backup_pause_counter: usize = 0;
|
let mut backup_pause_counter: usize = 0;
|
||||||
let clock = governor::clock::QuantaClock::default();
|
let clock = governor::clock::QuantaClock::default();
|
||||||
if let Some(rps) = rps_setting {
|
if let Some(rps) = rps_setting {
|
||||||
|
@ -279,12 +315,14 @@ pub async fn db_writer(
|
||||||
backup_pause_counter = 0
|
backup_pause_counter = 0
|
||||||
}
|
}
|
||||||
|
|
||||||
// Use this as a trigger to do optimization
|
// Use this as a trigger to do optimization & checkpointing
|
||||||
optimize_counter += 1;
|
maintenance_counter += 1;
|
||||||
if optimize_counter > EVENT_COUNT_OPTIMIZE_TRIGGER {
|
if maintenance_counter > EVENT_COUNT_MAINTENANCE_TRIGGER {
|
||||||
info!("running database optimizer");
|
debug!("running database optimizer");
|
||||||
optimize_counter = 0;
|
maintenance_counter = 0;
|
||||||
optimize_db(&mut pool.get()?).ok();
|
optimize_db(&mut pool.get()?).ok();
|
||||||
|
debug!("running wal_checkpoint(TRUNCATE)");
|
||||||
|
checkpoint_db(&mut pool.get()?).ok();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user