错误现象
后台访问列表时顶部报红字 database disk image is malformed,列表显示 0 条。这句话的意思是数据库磁盘映像损坏,SQLite 无法正常解析文件。
常见成因(按概率排序)
- 程序运行时覆盖数据库文件:服务还在写库,就用 SFTP 直接覆盖 .db,文件写到一半被读,结构损坏
- WAL/SHM 残留不一致:WAL 模式下只传了主库,没处理 -wal/-shm,新旧文件不匹配
- 传输不完整:网络中断导致上传文件缺字节
- 磁盘写满或异常断电:写入中途失败
- SQLite 版本/位数不兼容(较少见)
排查步骤
# 1. 先停掉正在访问数据库的服务
pm2 stop gongkong-server
# 2. 查看数据目录,确认有没有 -wal/-shm 残留
ls -la data/
# 3. 完整性检查
sqlite3 data/gongkong.db "PRAGMA integrity_check;"
返回 ok 才是健康;返回错误列表就是已损坏。
正确的替换流程(关键)
- 先停服务,确保没有进程在写库
- 删除旧的 .db 以及残留的 .db-wal、.db-shm
- 用 SFTP 完整上传本地库(二进制方式)
- 核对文件字节数与本地完全一致
- 再做一次 integrity_check
- 修正文件权限后启动服务
尝试恢复损坏库
如果没有干净备份,可尝试导出再导入:
sqlite3 bad.db ".recover" | sqlite3 recovered.db
.recover 能尽量导出可读数据,但不保证 100%,所以预防远胜于恢复。
从流程上彻底预防
- 永远先停服务再动数据库文件
- 每次部署前后各做一次完整性检查
- 建立定时备份(VACUUM INTO 或 .backup),保留最近若干份
- 监控服务器磁盘剩余空间
- 本地库和服务器库的更新走固定操作手册,不靠记忆
这次问题的根因就是运行中覆盖文件,严格执行“先停、再传、校验、后启”,malformed 完全可以避免。