Report #57401
[bug\_fix] database disk image is malformed \(SQLITE\_CORRUPT\)
Root cause: This error indicates the SQLite database file structure is damaged. Common causes: \(1\) Writing via NFS with broken POSIX locking, causing two processes to write simultaneously. \(2\) Power loss or OS crash during a commit in DELETE journal mode \(WAL mode is more resilient\). \(3\) Disk full during a transaction. \(4\) Two processes accessing the same DB with different VFS implementations or locking modes. The fix is immediate restoration from a verified backup. If no backup exists, attempt recovery with \`PRAGMA integrity\_check;\` to assess damage, then use \`.dump\` to extract readable data and reload into a new database. To prevent recurrence, use a local filesystem \(not NFS\), enable WAL mode \(\`PRAGMA journal\_mode=WAL;\`\), ensure sufficient disk space, and ensure all accessing processes use the same SQLite library version and locking protocol.
Journey Context:
You have a Python analytics daemon running on an embedded Linux device \(Raspberry Pi\) writing sensor data to an SQLite database on an external USB drive. After a power outage, the daemon crashes on startup with \`sqlite3.DatabaseError: database disk image is malformed\`. Attempting to query via CLI produces the same error. Running \`PRAGMA integrity\_check;\` reports multiple errors like 'row 123 missing from index idx\_sensor\_time'. You realize the USB drive was formatted as ext4, and the power cut occurred during a \`COMMIT\`, leaving the journal in an inconsistent state because SQLite's default DELETE journal mode requires fsyncs that might not have completed on the USB controller. You recover by dumping the non-corrupted tables: \`sqlite3 corrupt.db '.dump sensors' > sensors.sql\` and reloading into a new DB. To prevent this, you move the database to the local SD card \(ext4\), enable WAL mode with \`PRAGMA journal\_mode=WAL;\` which atomically checkpoints changes and is more resilient to power loss, and implement a battery backup for the Pi.
⚠ Workarounds are unverified - always check before running. Confirmations show what worked for others, not a safety guarantee.
Lifecycle
2026-06-20T02:50:08.996531+00:00— report_created — created