Loading

创建过多子目录报错Too many links排查

描述

使用Python处理数据集,大约需要生成20万个子目录。
生成到65000左右时候开始报错mkdir Failed: Too many links
类似cp mv等命令也无法正常执行。

排查

首先怀疑文件inode用尽,检查磁盘inode余量

$ df -i /data1
Filesystem        Inodes   IUsed     IFree IUse% Mounted on
/dev/sdb       234389504 7908490 226481014    4% /data1

余量充足,排除该原因。进而怀疑文件系统限制,
查询资料得知ext3文件系统限制最大子目录数32000个,
但ext4无此限制,查看磁盘文件系统类型:

$ df -T /data1
Filesystem     Type  1K-blocks       Used Available Use% Mounted on
/dev/sdb       ext4 3691353224 3100686016 403157244  89% /data1

已经是ext4再次排除可能性。考虑到在Docker使用Python环境,怀疑OverlayFS存在限制。
诚然overlay存在一些限制,可通过升级overlay2解决。文中出现报错的类型如下:

failed to register layer: link /data/sys/var/docker/overlay/xxxxx: too many links

和我的错误有明显区别,anyway抱着试验心态将overlay升级为overlay2故障依旧没有解决。

定位

痛定思痛,排查了三个可能的原因都不对,怕是有遗漏。
作为对照,物理机直接新建70000个文件夹也复现了Too many links
此举排除OverlayFS嫌疑,有必要深究ext4的细节。
果然,在man ext4发现一个名为dir_nlink的选项:

Normally, ext4 allows an inode to have no more than 65,000 hard links. This applies to regular files as well as
directories, which means that there can be no more than 64,998 subdirectories in a directory (because each of the
'.' and '..' entries, as well as the directory entry for the directory in its parent directory counts as a hard
link). This feature lifts this limit by causing ext4 to use a link count of 1 to indicate that the number of hard
links to a directory is not known when the link count might exceed the maximum count limit.

实锤ext4对于子目录也存在65000默认数量限制,需手动解除。

解决

明确方向后很快在so找到了解除方法:

sudo umount /dev/sdb
sudo tune2fs -O dir_index,dir_nlink /dev/sdb

再次挂载后可以正常建立超过70000个子目录,限制解除。

$ mkdir {1..70000}
$ ll | wc -l
70003

该方法仅对新建目录生效,修改老目录限制则需要用到原文中的更新命令重建indices注意做好容灾。

参考

聊聊Linux上“too many links”报错出现的原因和处理方法_圣骑士控魔之手的技术博客_51CTO博客
ext4(5) - Linux manual page
filesystems - Ubuntu server ext4 hitting 65000 subdirectory limit - Server Fault

posted @ 2022-06-29 14:14  azureology  阅读(1513)  评论(0)    收藏  举报