记录一下那天晚上的排查过程。CentOS 7 的邮件归档盘上,一个季度目录里五万多个 eml 文件,ls 要等七八秒,find 更是跑十分钟,同一批盘上新建的空目录放同样数量文件却很快。

刚开始盯着「目录项分散在大量块里,元数据读取变成随机 IO,机械盘上放大明显」,折腾了半个多小时,排掉了。

这类报错背后常见的原因有几处,逐个排除就行。目录创建时没开 dir_index,查找退化成线性扫描整张目录表。少数情况下是文件系统是早期用 -O ^dir_index 建的,后续新增目录全部继承这个设置。

少数情况下是文件名长度不一且前缀高度相似,哈希冲突低但线性比较次数被拉长。

上来先确认文件系统是否支持目录索引

dumpe2fs -h /dev/vdb1 2>/dev/null | grep -i dir_index

接着统计目录项数量,确认规模

ls -U /data/archive/2026q3 | wc -l

再往下对已有目录重建索引

e2fsck -fD /dev/vdb1

新目录改用带索引的文件系统并验证

tune2fs -O dir_index /dev/vdb1 && ls -f /data/archive/2026q4 | wc -l

改完先别撤,确认这几项。同一个目录 ls 的耗时从七八秒降到一秒内,find 遍历时间缩短一个数量级,e2fsck -D 完成后目录的块数明显减少。

e2fsck -fD 要卸载分区才能跑,几十万目录的盘上耗时以小时计;根本办法是按时间或哈希拆子目录,别把文件全堆在一层。改动前把原配置备份一份,出问题能马上回滚,这比任何技巧都实用。

作者 9823189