← 中文资源

简体中文版本

备份前后校验 SQLite 数据库完整性

先对源库跑 integrity_check,再用 backup API 在线备份而非直接拷文件,最后逐行核对副本。

阅读英文原文

目标

用 cp 直接拷贝正在写入的 SQLite 文件,会把写到一半的页和一个可能与副本不匹配的 journal 一起拷走,恢复时直接报 database disk image is malformed。在线 backup API 会在反复的事务中按页拷贝,产出一致快照。本食谱在备份前后分别做结构校验与逻辑哈希对比,把“应该没问题”变成可出示的证据。

步骤要点

  1. 先对源库跑 PRAGMA integrity_check,健康应输出 ok;若有页链错误,先修源库再谈备份。
  2. 继续跑 foreign_key_check 与 quick_check,空输出代表外键一致,quick_check 以更低成本覆盖行级损坏。
  3. 用 sqlite3 的 .backup 命令(backup API 封装)在线备份,期间允许写入,副本应通过 integrity_check。
  4. 分别对源库与副本执行 .dump 并比对 SHA-256,哈希一致即所有表、行与 schema 对象逻辑相同。
  5. 现场复现反模式:写入进行中用 cp 拷贝再校验,直观展示为什么在线拷贝必须用 backup API 或先做 checkpoint。

排错提示

源库 integrity_check 报错就停止备份先做恢复,用 .recover 把可读行抽到新库再从逻辑 dump 重建,别把损坏拷得更快;两次 dump 哈希不一致多半是备份后仍有写入,让写入静止或在同一读事务里做两次 dump;备份报 database is locked 是长读阻塞了 backup,重试 .backup 或改在写入空闲的时段调度。

适用边界

integrity_check 只验结构不验业务正确性,需配合外键检查与应用级不变量;dump 哈希是时点性证明,持续写入下要么在同一事务内对比要么接受最终一致。

代码示例

# 1) structural health of the source
sqlite3 app.db "PRAGMA integrity_check;"     # -> ok
sqlite3 app.db "PRAGMA foreign_key_check;"   # -> (empty = consistent)

# 2) online backup, safe under writes
sqlite3 app.db ".backup backup.db"

# 3) logical equality, not just file equality
sqlite3 app.db    ".dump" | sha256sum   # a1b2...
sqlite3 backup.db ".dump" | sha256sum   # a1b2...  identical

# 4) the anti-pattern, for the record
# cp app.db copy.db   # pages mid-write -> malformed copy