mirror of
https://github.com/openai/codex.git
synced 2026-11-07 20:30:33 +00:00
Reclaim unused SQLite log database pages in the background (#49069)
## Why Deleting logs leaves free SQLite pages available for reuse without shrinking the database file. Reclaim excess free space while preserving a reserve for future writes. ## What changed - Start a background incremental-vacuum worker with `StateRuntime`, enabling reclamation only for the logs database. Use a per-home file lock to select one worker and wait for it to finish during shutdown. - Reclaim pages when at least 64 MiB and 25% of the database are free, preserving a reserve of at least 16 MiB or 10% of the database. - Use short transactions with page and cooperative time budgets, defer work on contention, and reduce batch sizes with exponential backoff when interrupted passes make no progress. - Record reclamation counts, durations, and reclaimed pages in telemetry. ## Testing Add a regression test that interrupts a vacuum commit, verifies foreground writes can resume without data loss, then confirms a resumed pass shrinks the database and passes `PRAGMA integrity_check`. GitOrigin-RevId: 8421f87b0aeef6540eda5690c84216906673c72e
This commit is contained in:
committed by
copyberry
parent
5a5a4aa796
commit
33a0f766a6
@@ -7,7 +7,7 @@
|
||||
|
||||
use crate::DbTelemetry;
|
||||
use crate::migrations::repair_legacy_recency_migration_version;
|
||||
use crate::runtime::RuntimeDbInitError;
|
||||
use crate::runtime::recovery::RuntimeDbInitError;
|
||||
use crate::telemetry;
|
||||
use crate::telemetry::DbKind;
|
||||
use codex_utils_absolute_path::AbsolutePathBuf;
|
||||
@@ -38,6 +38,9 @@ struct RuntimeDbSpec {
|
||||
kind: DbKind,
|
||||
open_phase: &'static str,
|
||||
migrate_phase: &'static str,
|
||||
/// Opt in only after auditing writers for deferred read-to-write upgrades:
|
||||
/// an intervening reclamation commit can make those fail with SQLITE_BUSY_SNAPSHOT.
|
||||
background_reclamation: bool,
|
||||
}
|
||||
|
||||
impl RuntimeDbSpec {
|
||||
@@ -52,6 +55,7 @@ const STATE_DB: RuntimeDbSpec = RuntimeDbSpec {
|
||||
kind: DbKind::State,
|
||||
open_phase: "open_state",
|
||||
migrate_phase: "migrate_state",
|
||||
background_reclamation: false,
|
||||
};
|
||||
|
||||
const LOGS_DB: RuntimeDbSpec = RuntimeDbSpec {
|
||||
@@ -60,6 +64,8 @@ const LOGS_DB: RuntimeDbSpec = RuntimeDbSpec {
|
||||
kind: DbKind::Logs,
|
||||
open_phase: "open_logs",
|
||||
migrate_phase: "migrate_logs",
|
||||
// Log transactions write before reading, so they already hold the writer lock.
|
||||
background_reclamation: true,
|
||||
};
|
||||
|
||||
const GOALS_DB: RuntimeDbSpec = RuntimeDbSpec {
|
||||
@@ -68,6 +74,7 @@ const GOALS_DB: RuntimeDbSpec = RuntimeDbSpec {
|
||||
kind: DbKind::Goals,
|
||||
open_phase: "open_goals",
|
||||
migrate_phase: "migrate_goals",
|
||||
background_reclamation: false,
|
||||
};
|
||||
|
||||
const MEMORIES_DB: RuntimeDbSpec = RuntimeDbSpec {
|
||||
@@ -76,11 +83,13 @@ const MEMORIES_DB: RuntimeDbSpec = RuntimeDbSpec {
|
||||
kind: DbKind::Memories,
|
||||
open_phase: "open_memories",
|
||||
migrate_phase: "migrate_memories",
|
||||
background_reclamation: false,
|
||||
};
|
||||
|
||||
const MEMORIES_V2_DB: RuntimeDbSpec = RuntimeDbSpec {
|
||||
label: "memories v2 DB",
|
||||
filename: "memories_v2_1.sqlite",
|
||||
background_reclamation: false,
|
||||
..MEMORIES_DB
|
||||
};
|
||||
|
||||
@@ -90,6 +99,7 @@ const QUEUE_DB: RuntimeDbSpec = RuntimeDbSpec {
|
||||
kind: DbKind::Queue,
|
||||
open_phase: "open_queue",
|
||||
migrate_phase: "migrate_queue",
|
||||
background_reclamation: false,
|
||||
};
|
||||
|
||||
const THREAD_HISTORY_DB: RuntimeDbSpec = RuntimeDbSpec {
|
||||
@@ -98,6 +108,7 @@ const THREAD_HISTORY_DB: RuntimeDbSpec = RuntimeDbSpec {
|
||||
kind: DbKind::ThreadHistory,
|
||||
open_phase: "open_thread_history",
|
||||
migrate_phase: "migrate_thread_history",
|
||||
background_reclamation: false,
|
||||
};
|
||||
|
||||
const RUNTIME_DBS: [RuntimeDbSpec; 7] = [
|
||||
@@ -114,6 +125,7 @@ const RUNTIME_DBS: [RuntimeDbSpec; 7] = [
|
||||
pub struct RuntimeDbPath {
|
||||
pub label: &'static str,
|
||||
pub path: PathBuf,
|
||||
pub(crate) background_reclamation: bool,
|
||||
}
|
||||
|
||||
/// Resolved configuration shared by all Codex SQLite connections.
|
||||
@@ -185,6 +197,7 @@ impl SqliteConfig {
|
||||
.map(|spec| RuntimeDbPath {
|
||||
label: spec.label,
|
||||
path: spec.path(self.home()),
|
||||
background_reclamation: spec.background_reclamation,
|
||||
})
|
||||
.collect()
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user