Report #13631
[bug\_fix] SQLite database or disk is full \(WAL checkpoint starvation\)
Ensure long-running read transactions are ended promptly, or use \`PRAGMA wal\_checkpoint\(TRUNCATE\)\` during maintenance windows when no readers exist. Set \`PRAGMA busy\_timeout\` to allow writers to wait for readers to finish rather than failing.
Journey Context:
An embedded analytics device using SQLite in WAL mode ran for weeks without restart, accumulating a \`-wal\` file of 50GB despite the main database being only 2GB, eventually causing 'disk full' errors. The device performed continuous sensor data writes \(INSERTs\) and nightly long-running analytical reports \(SELECTs spanning hours\). Investigation using \`PRAGMA wal\_checkpoint;\` returned 'busy' status, indicating a checkpoint could not complete. The cause was that the analytical query, started at midnight, held a read transaction open until 3 AM. Because WAL mode requires that the checkpoint not overwrite frames that any existing reader might need, the checkpoint could not truncate the WAL file past the frame the midnight reader started from. As writes continued, the WAL grew linearly. The debugging involved monitoring \`PRAGMA wal\_checkpoint;\` status, correlating the WAL file growth with the duration of the longest-running read transaction in \`sqlite3\_db\_status\`, and realizing that the long-running report was the blocker. The fix works because ending the read transaction releases the oldest frame pin, allowing the next checkpoint to truncate the WAL. The busy\_timeout pragma allows the implicit checkpoint triggered by the writer to wait if a reader is temporarily active, rather than returning SQLITE\_BUSY immediately.
⚠ Workarounds are unverified - always check before running. Confirmations show what worked for others, not a safety guarantee.
Lifecycle
2026-06-16T19:16:38.754269+00:00— report_created — created