ILD

database fragmentation and vacuum
作者:Yuan Jianpeng 邮箱:yuanjp89@163.com
发布时间:2026-1-30 站点:Inside Linux Development

最近的项目中,出现数据库搜索很慢,本地确没有问题,上去分析发现,数据库文件碎片化了。由于数据库是放在磁盘上的,碎片化之后,遍历数据库就相当于随机访问磁盘,速度就很慢。


使用filefrag命令查看碎片化:

$ filefrag u3049499598-7cb394645c881238-v0.db

u3049499598-7cb394645c881238-v0.db: 76452 extents found


读取文件:

dd if=u3049499598-7cb394645c881238-v0.db of=/dev/null iflag=direct status=progress

20206080 字节 (20 MB, 19 MiB) 已复制,4 s,5.0 MB/s


发现速度只有5MB/S,这就是碎片化了。执行数据库搜索需要3分钟。


btrfs defragmentation

$ btrfs filesystem defragment u2232476592-f8a433997316e97b-v0.db


sqlite vacuum

$ sqlite3 u2232476592-f8a433997316e97b-v0.db VACUUM


执行这两条命令后,数据库搜索时间从3分钟下降到1.7s。



避免碎片化

mozilla也碰到了同样的问题:

https://sqlite-users.sqlite.narkive.com/IfUGkoqR/coping-with-database-growth-fragmentation


可以通过设置chunk size为1M来减少碎片化。

        int sz = 1024 * 1024;

        sqlite3_file_control(db, "main", SQLITE_FCNTL_CHUNK_SIZE, &sz);


碎片是如何产生的

个人理解。如果同时写多个文件。比如A/B/C

那么A/B/C依次拿到连续的block,但是对于单个文件block就不连续了。

比如有block 1-10,A/B/C同时写,那分配的block可能是:

A 1 4 7

B 2 5 8

C 3 6 9




参考:


https://askubuntu.com/questions/229770/how-do-i-show-the-current-amount-of-fragmentation-on-a-btrfs-filesystem


https://btrfs.readthedocs.io/en/latest/Defragmentation.html


https://stackoverflow.com/questions/13393866/sqlite-wal-performance-improvement


Copyright © linuxdev.cc 2017-2024. Some Rights Reserved.