【时间】2026 年 9 月 25 号下午,QQ 启动后卡死不动
~/.config/QQ 通过 bind 挂载指向 NFS(/tank/shared/QQ)。QQ 启动后界面转圈,日志里能看到主进程打开了一堆数据库文件,但就是不出聊天记录。
第一反应是:SQLite 在跑 vacuum 或者 integrity check,等一等就过去了。
坑
vmstat 1 显示 wa(IO 等待)在 20–26%,有进程阻塞。直接读 31G 的 nt_msg.db:
本机 direct read:20.6 MB/s(2G 用了 104s)
宿主侧 direct read 同文件:24.8 MB/s两个数字几乎一样,说明瓶颈不在 NFS 网络层,而在宿主那两块 ST16000NM000J 16T 机械盘的顺序读上限。SQLite 加载聊天记录是大量随机读,在这两块盘上就是分钟级。
再看 nt_db 目录,实际 du 出来是 202G——其中 nt_data(媒体库)158G,nt_db(全部数据库)44G。媒体库留在 NFS 没问题(顺序读单文件,25MB/s 够用),卡的是 SQLite 的随机读。
修复
宿主是 PVE,tank 是 ZFS。查 ARC:
zfs_arc_max = 4294967296 # /etc/modprobe.d/zfs.conf 里人为钳到 4G
ARC 命中率:85.6%(30.6M hits / 5.2M misses)4G ARC 装 44G 数据库的热工作集,只能覆盖一小部分。冷加载时大量块要穿透到机械盘。
改动(免重启):
# 持久化
echo "options zfs zfs_arc_max=17179869184" >> /etc/modprobe.d/zfs.conf
# 即时生效
echo 17179869184 | sudo tee /sys/module/zfs/parameters/zfs_arc_max改完验证 ARC 开始增长:4G → 6.9G,上限 16G,会随 IO 逐步填满。
经验
vmstat wa高不代表数据库在整理,先测 direct read 速度区分“网络瓶颈”还是“磁盘瓶颈”。- PVE 宿主上的 ZFS ARC 默认会被钳到 RAM 的 25% 甚至更低,查
/etc/modprobe.d/zfs.conf里有没有zfs_arc_max。 - 媒体库(顺序读)和数据库(随机读)的 IO 模式完全不同,不能混在一起评估。媒体库放 NFS 没问题,数据库放 NFS 就卡。
🎵 Listening companion