deltachat/sql/pool/
wal_checkpoint.rs1use anyhow::{Result, ensure};
4use std::sync::Arc;
5use std::time::Duration;
6
7use crate::sql::Sql;
8use crate::tools::{Time, time_elapsed};
9
10use super::Pool;
11
12#[derive(Debug)]
14pub(crate) struct WalCheckpointStats {
15 pub total_duration: Duration,
17
18 pub writers_blocked_duration: Duration,
20
21 pub readers_blocked_duration: Duration,
23
24 pub pages_total: i64,
26
27 pub pages_checkpointed: i64,
33}
34
35pub(super) async fn wal_checkpoint(pool: &Pool) -> Result<WalCheckpointStats> {
37 let _guard = pool.inner.wal_checkpoint_mutex.lock().await;
38 let t_start = Time::now();
39
40 let query_only = true;
42 let conn = pool.get(query_only).await?;
43 tokio::task::block_in_place(|| {
44 conn.query_row("PRAGMA table_list", [], |_| Ok(()))?;
48 conn.query_row("PRAGMA wal_checkpoint(PASSIVE)", [], |_| Ok(()))
49 })?;
50
51 const _: () = assert!(Sql::N_DB_CONNECTIONS > 1, "Deadlock possible");
53 let _write_lock = Arc::clone(&pool.inner.write_mutex).lock_owned().await;
54 let t_writers_blocked = Time::now();
55 let mut read_conns = Vec::with_capacity(crate::sql::Sql::N_DB_CONNECTIONS - 1);
61 for _ in 0..(crate::sql::Sql::N_DB_CONNECTIONS - 1) {
62 read_conns.push(pool.get(query_only).await?);
63 }
64 read_conns.clear();
65 let (pages_total, pages_checkpointed) = tokio::task::block_in_place(|| {
67 conn.query_row("PRAGMA wal_checkpoint(FULL)", [], |row| {
68 let pages_total: i64 = row.get(1)?;
69 let pages_checkpointed: i64 = row.get(2)?;
70 Ok((pages_total, pages_checkpointed))
71 })
72 })?;
73 for _ in 0..(crate::sql::Sql::N_DB_CONNECTIONS - 1) {
75 read_conns.push(pool.get(query_only).await?);
76 }
77 let t_readers_blocked = Time::now();
78 tokio::task::block_in_place(|| {
79 let blocked = conn.query_row("PRAGMA wal_checkpoint(TRUNCATE)", [], |row| {
80 let blocked: i64 = row.get(0)?;
81 Ok(blocked)
82 })?;
83 ensure!(blocked == 0);
84 Ok(())
85 })?;
86 Ok(WalCheckpointStats {
87 total_duration: time_elapsed(&t_start),
88 writers_blocked_duration: time_elapsed(&t_writers_blocked),
89 readers_blocked_duration: time_elapsed(&t_readers_blocked),
90 pages_total,
91 pages_checkpointed,
92 })
93}