当 SQLite 数据库文件体积明显大于实际数据量且业务允许短暂锁表时,使用 VACUUM 命令是清理碎片、释放磁盘空间的标准做法。
先说结论:VACUUM 能重建数据库文件以回收空间,但执行期间会锁表且需要额外磁盘空间,建议在低峰期操作。
- 先定位:确认文件虚大程度,检查 freelist_count pragma。
- 先做:操作前务必备份文件,确保磁盘剩余空间充足。
- 再验证:对比操作前后文件大小及 freelist_count 数值。
命令速用版
VACUUM;为什么会这样
SQLite 删除数据时,默认不会立即将空间归还给操作系统,而是标记为空闲页留给后续写入使用。随着频繁增删,空闲页积累导致文件体积膨胀,实际有效数据占比下降。
分步处理
1. 检查当前状态:使用 PRAGMA freelist_count; 查看空闲页数量,若数值较大则值得清理。
2. 备份数据库:直接复制 .db 文件到安全位置,防止执行中断导致文件损坏。
3. 确认磁盘空间:VACUUM 需要临时文件,确保剩余空间至少等于当前数据库文件大小。
4. 执行清理:在数据库连接中运行 VACUUM; 命令,期间避免其他写入操作。
怎么验证是否生效
操作完成后,再次查看数据库文件大小,通常会有明显减小。同时运行 PRAGMA freelist_count; 返回值应接近 0。
常见坑
1. 磁盘空间不足:若空间不够,VACUUM 会失败,极端情况下可能损坏数据库。
2. 长时间锁表:重建过程持有 exclusive 锁,业务写入会阻塞,大库耗时可能较长。
3. 与 auto_vacuum 混淆:pragma auto_vacuum 是自动维护机制,与手动 VACUUM 命令效果不同,前者可能无法彻底碎片整理。
参考来源
- SQLite Documentation - VACUUM, https://www.sqlite.org/lang_vacuum.html
- SQLite Documentation - PRAGMA auto_vacuum, https://www.sqlite.org/pragma.html#pragma_auto_vacuum
原文链接:https://www.zjcp.cc/ask/10819.html
