From f1d7c214785a0483c1c3049b1596168052468b78 Mon Sep 17 00:00:00 2001 From: sneak Date: Thu, 1 Jan 2026 06:38:15 -0800 Subject: [PATCH] Run WAL checkpoint on startup with logging Explicitly checkpoint the WAL on database initialization to consolidate any large WAL file from previous runs. Log the checkpoint results to help diagnose issues. --- internal/database/database.go | 30 +++++++++++++++++++++--------- 1 file changed, 21 insertions(+), 9 deletions(-) diff --git a/internal/database/database.go b/internal/database/database.go index 1896d1b..8e20ce1 100644 --- a/internal/database/database.go +++ b/internal/database/database.go @@ -106,14 +106,13 @@ func New(cfg *config.Config, logger *logger.Logger) (*Database, error) { func (d *Database) Initialize() error { // Set SQLite pragmas for performance pragmas := []string{ - "PRAGMA journal_mode=WAL", // Write-Ahead Logging - "PRAGMA synchronous=OFF", // Don't wait for disk writes - "PRAGMA cache_size=-3145728", // 3GB cache (upper limit for 2.4GB DB) - "PRAGMA temp_store=MEMORY", // Use memory for temp tables - "PRAGMA wal_checkpoint(TRUNCATE)", // Checkpoint and truncate WAL now - "PRAGMA busy_timeout=5000", // 5 second busy timeout - "PRAGMA analysis_limit=0", // Disable automatic ANALYZE - "PRAGMA auto_vacuum=INCREMENTAL", // Enable incremental vacuum + "PRAGMA journal_mode=WAL", // Write-Ahead Logging + "PRAGMA synchronous=OFF", // Don't wait for disk writes + "PRAGMA cache_size=-3145728", // 3GB cache (upper limit for 2.4GB DB) + "PRAGMA temp_store=MEMORY", // Use memory for temp tables + "PRAGMA busy_timeout=5000", // 5 second busy timeout + "PRAGMA analysis_limit=0", // Disable automatic ANALYZE + "PRAGMA auto_vacuum=INCREMENTAL", // Enable incremental vacuum } for _, pragma := range pragmas { @@ -122,7 +121,20 @@ func (d *Database) Initialize() error { } } - err := d.exec(dbSchema) + // Run WAL checkpoint on startup to consolidate any existing WAL + var walPages, checkpointedPages, movedPages int + err := d.db.QueryRow("PRAGMA wal_checkpoint(TRUNCATE)").Scan(&walPages, &checkpointedPages, &movedPages) + if err != nil { + d.logger.Warn("Failed to checkpoint WAL on startup", "error", err) + } else { + d.logger.Info("WAL checkpoint on startup", + "wal_pages", walPages, + "checkpointed", checkpointedPages, + "moved", movedPages, + ) + } + + err = d.exec(dbSchema) if err != nil { return err }