SQLite 备份与恢复指南

详解 SQLite 备份与恢复的四类方法:.backup 在线物理备份、.dump/.restore 逻辑备份与恢复、VACUUM INTO 生成紧凑完整副本、冷备份(cp/sqlite3 拷贝)及其 WAL 注意事项;包含完整性校验、自动备份与实战排障。命令与输出基于 SQLite 3.53.4 实测。

SQLiteSQLite备份恢复运维嵌入式数据库关系型数据库OLTP2026/10/02

SQLite 备份与恢复指南

目标:掌握 SQLite 的全部备份与恢复手段。SQLite 是嵌入式单文件数据库,备份既简单又要求正确——在线运行时不能只 cp 主文件(WAL 模式下会漏掉日志)。本文涵盖四类备份的实测命令、恢复流程与完整性校验,全部基于 SQLite 3.53.4 环境实测。

环境信息

信息项值
SQLite 版本3.53.4(源码编译)
操作系统Ubuntu 22.04.5 LTS
数据文件/tmp/src.db、/tmp/dm.db

一、备份方式总览

方式类型适用命令
.backup / .save在线物理库较小、需带事务一致sqlite3 a.db ".backup b.db"
.dump / .restore逻辑跨版本迁移、只需数据sqlite3 a.db ".dump"
VACUUM INTO紧凑副本生成干净独立副本sqlite3 a.db "VACUUM INTO b.db"
cp/sqlite3 冷拷贝物理冷备库未打开(无写者)时cp a.db a.db.bak

二、.backup 在线物理备份(推荐)

.backup 使用在线备份 API,无需停服,可得到一致快照,兼容旧版 SQLite:

sqlite3 /tmp/n.db ".backup /tmp/bk.db"

实测:备份文件与源库大小一致,备份完整。

$ ls -la /tmp/n.db /tmp/bk.db
-rw-r--r-- 1 root root 8192 Oct  2 14:23 /tmp/bk.db
-rw-r--r-- 1 root root 8192 Oct  2 14:23 /tmp/n.db

$ sqlite3 /tmp/bk.db "PRAGMA integrity_check;"
ok

.save FILE 是 .backup 的别名。默认备份主库 main,可通过参数指定其它库(如 ATTACH 的库)。

三、.dump 逻辑备份 + .restore 恢复

3.1 .dump 导出为 SQL 文本

.dump 把库内容转成一组 SQL 语句,适合跨版本迁移、只看数据、或同步到其它库:

sqlite3 /tmp/dm.db ".dump"

实测输出(含建表与数据 INSERT):

PRAGMA foreign_keys=OFF;
BEGIN TRANSACTION;
CREATE TABLE emp(id INTEGER PRIMARY KEY, name TEXT, dept TEXT);
INSERT INTO emp VALUES(1,'alice','eng');
INSERT INTO emp VALUES(2,'bob','sales');
INSERT INTO emp VALUES(3,'carol','eng');
COMMIT;

导出到文件:

sqlite3 /tmp/dm.db ".dump" > /tmp/dm_dump.sql

3.2 .restore 恢复

用 .dump 生成的 SQL 重建库:

sqlite3 /tmp/restored.db < /tmp/dm_dump.sql
# 或
sqlite3 /tmp/restored.db ".read /tmp/dm_dump.sql"

恢复后校验:

sqlite3 /tmp/restored.db "PRAGMA integrity_check; SELECT count(*) FROM emp;"

用 .restore 命令从备份库直接恢复到目标库:

sqlite3 /tmp/res.db ".restore /tmp/src.db"

3.3 逻辑备份的局限

  • 导出是文本,体积相对大、恢复较慢。
  • 不包含空页与某些存储细节,但数据与 schema 完整,适合迁移。

四、VACUUM INTO 生成紧凑完整副本

VACUUM INTO newfile.db 会生成一个紧凑、完整、已清理零碎空间的独立副本,非常适合打包归档:

sqlite3 /tmp/dm.db "VACUUM INTO '/tmp/clone.db'"
ls -la /tmp/clone.db
sqlite3 /tmp/clone.db "PRAGMA integrity_check; SELECT count(*) FROM emp;"

实测输出:

-rw-r--r-- 1 root root 8192 Oct  2 14:27 clone.db
ok
3

与 VACUUM 的区别:VACUUM INTO 生成新库文件不影响原库,且副本是重排过的紧凑布局。

五、冷备份(物理复制)

当库没有被任何进程打开(或已退出正常连接)时,直接复制文件即可:

cp /tmp/src.db /tmp/src.db.$(date +%Y%m%d).bak

⚠️ 勿在 WAL 模式下直接 cp:WAL 事务的部分数据还在 库名-wal 文件里,只拷 src.db 会丢最近提交。需先:

PRAGMA wal_checkpoint(TRUNCATE);

执行成功后再 cp 主文件与 -wal/-shm(若仍存在)。更稳妥的在线方案始终用 .backup 或 VACUUM INTO。

启用 WAL 的库真实文件形如(三个文件都属于该库):

driver.db
driver.db-wal
driver.db-shm

六、完整性校验

恢复或备份后统一校验:

PRAGMA integrity_check;   -- 无损坏输出 ok;损坏输出错误页列表
PRAGMA quick_check;       -- 速度快但检查较少

两者实测均返回:

ok

七、自动备份(定期执行)

可用 cron 每天执行一次在线备份(配合压缩):

30 2 * * *  sqlite3 /data/app.db ".backup /backup/app-$(date +\%F).db" && gzip -f /backup/app-$(date +\%F).db

保持最近 N 份的清理命令(用 find,非循环脚本):

find /backup -name "app-*.db.gz" -mtime +14 -delete

八、常见问题(FAQ)

1. 恢复后 integrity_check 报损坏?

多为 WAL 模式下直接复制漏拷 -wal。改用 .backup 或先 PRAGMA wal_checkpoint(TRUNCATE); 再冷拷贝。损坏时 integrity_check 会列出损坏页号,可用 PRAGMA table_info(...) 与重建表方式抢救,并配合 dump 只导可读部分。

2. .dump 和 .backup 选择哪个?

  • 日常快速备份、跨库迁移 → .dump(文本、跨版本兼容)。
  • 生产一致快照、原样恢复 → .backup / VACUUM INTO(二进制、快)。
  • 需要干净副本归档 → VACUUM INTO。

3. 数据库文件被 btrfs / ZFS 快照备份还要 WAL 处理吗?

零拷贝要求在被快照前无活跃写。若有 WAL 未合并,快照会含 -wal,恢复时把 -wal 一起放回同目录即可;否则先 checkpoint。

4. 备份文件比源文件大很多?

.dump 文本体积通常大于二进制库文件,属正常。VACUUM INTO 会压缩空闲空间,往往比源库还小。

九、小结

SQLite 备份关键在"在线一致":日常用 .backup 在线物理备份,跨库迁移用 .dump/.restore,归档清理用 VACUUM INTO,停机冷备需处理 WAL。恢复后一律 PRAGMA integrity_check; 校验。配合《SQLite PRAGMA 与配置调优详解》中的 journal_mode/wal_checkpoint,即可搭建可靠备份链路。