这个坑值得记一笔。镜像仓库跑在 btrfs 上,写入时报 No space left on device,df 显示还有二十 G 空闲,文件系统自己却报告分配失败。
把日志和配置对完,能解释这个现象的基本就这几处。元数据空间先耗尽了,数据空间还有余量;大量快照占着没有回收的 extent;小块分配导致碎片化,剩余空间不连续。
动手时先分别看数据与元数据的余量
btrfs filesystem usage /
然后列出不再需要的快照
btrfs subvolume list /
做一次平衡回收空间
btrfs balance start -dusage=50 /
再确认两类空间余量
btrfs filesystem df /
中间停过一次,把已经改的东西回滚干净,再重新来一遍。
同样的操作我在测试机上先走了一遍,线上只做验证过的部分。
别只看报错消失,验证要多做一步。两边的余量都恢复,写入正常,df 与 usage 输出的数字也能对上。
这里还有个坑。平衡操作会长时间占用 IO,业务高峰执行等于自杀;btrfs 适合快照多的场景,不适合高并发小文件写入。报错文案容易误导,真正的原因往往在相邻那一层的日志里。