SQLite 报 database disk image is malformed:排查与预防全记录

丁丁智造 · 2026-08-17
SQLite 报 database disk image is malformed:排查与预防全记录
导读:数据库损坏导致后台列表空白是很棘手的问题。本文复盘 malformed 的常见成因、排查步骤、恢复手段,以及如何从流程上彻底避免。

错误现象

后台访问列表时顶部报红字 database disk image is malformed,列表显示 0 条。这句话的意思是数据库磁盘映像损坏,SQLite 无法正常解析文件。

常见成因(按概率排序)

  1. 程序运行时覆盖数据库文件:服务还在写库,就用 SFTP 直接覆盖 .db,文件写到一半被读,结构损坏
  2. WAL/SHM 残留不一致:WAL 模式下只传了主库,没处理 -wal/-shm,新旧文件不匹配
  3. 传输不完整:网络中断导致上传文件缺字节
  4. 磁盘写满或异常断电:写入中途失败
  5. SQLite 版本/位数不兼容(较少见)

排查步骤

# 1. 先停掉正在访问数据库的服务
pm2 stop gongkong-server
# 2. 查看数据目录,确认有没有 -wal/-shm 残留
ls -la data/
# 3. 完整性检查
sqlite3 data/gongkong.db "PRAGMA integrity_check;"

返回 ok 才是健康;返回错误列表就是已损坏。

正确的替换流程(关键)

  1. 先停服务,确保没有进程在写库
  2. 删除旧的 .db 以及残留的 .db-wal、.db-shm
  3. 用 SFTP 完整上传本地库(二进制方式)
  4. 核对文件字节数与本地完全一致
  5. 再做一次 integrity_check
  6. 修正文件权限后启动服务

尝试恢复损坏库

如果没有干净备份,可尝试导出再导入:

sqlite3 bad.db ".recover" | sqlite3 recovered.db

.recover 能尽量导出可读数据,但不保证 100%,所以预防远胜于恢复

从流程上彻底预防

  • 永远先停服务再动数据库文件
  • 每次部署前后各做一次完整性检查
  • 建立定时备份(VACUUM INTO 或 .backup),保留最近若干份
  • 监控服务器磁盘剩余空间
  • 本地库和服务器库的更新走固定操作手册,不靠记忆

这次问题的根因就是运行中覆盖文件,严格执行“先停、再传、校验、后启”,malformed 完全可以避免。