• 创建过多子目录报错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

  • 相关阅读:
    jQuery简单入门
    JSON
    AJAX入门2
    一些专业网站(目前包括:粒子滤波,随机集) Hanson
    命名空间 访问权限 通讯录及工资结算系统实例
    js去空格与计算字符串长度
    关于session配置的问题Warning: session_start() [function.sessionstart]:
    淘宝跳失率
    连接mysql数据库之后的“分页”问题
    数据库 基础知识(3
  • 原文地址:https://www.cnblogs.com/azureology/p/16423197.html
Copyright © 2020-2023  润新知