• 记录一次jbd2不停写磁盘原因追查


    起因

    最近买了两块16T氦气硬盘挂在小主机上当仓库盘使用,硬盘配置了自动休眠,具体系统配置如下:
    CPU:Intel N5105
    操作系统:ubuntu20.04
    硬盘休眠:hd-idle

    因为是企业盘的原因,并不支持电源管理,要么运行,要么停止,试了一下就只有hd-idle能让他停下,hdparam是基于电源管理的,对这个机械硬盘并不起作用。

    一切配置好后本以为万事大吉了,谁成想到时间后硬盘就是不能休眠,观察后发现硬盘一直在工作,即使我啥也没干。用sar -d -n 1发现硬盘移植有少量数据不断写入,使用sudo lsof又抓不到任何进程在操作硬盘,这就有点奇怪了。最后只好祭出神器iotop了,iotop抓取结果如下(我的硬盘是sda1-8):
    请添加图片描述
    好家伙,这会终于看到元凶了。是这个jbd2干的好事情。网上搜索了一番,大都是说数据库sync导致的ext4日志写入jbd2占比高。可是我根本没装数据库,也没有对硬盘做任何操作,为什么这个奇怪。

    又过了一天一夜,网上搜罗最终无果,后面又发现只要我不挂载这个硬盘就没事,只要一挂载他就一直写。硬盘灯每隔2s闪烁几次,硬盘烫的要命,这还了得,实在不能忍,非得揪出这个元凶。

    追查

    最后无奈还得祭出大杀器kernel debug,首先看一下内核有没有开启jbd2调试ls /sys/kernel/debug/tracing有jbd2文件夹就是开启了,下面直接打开jbd2所有追踪器:echo 1 | sudo tee /sys/kernel/debug/tracing/jbd2/enable等待几秒觉得抓得差不多了咋们就关掉echo 0 | sudo tee /sys/kernel/debug/tracing/jbd2/enable 然后查看结果:sudo cat /sys/kernel/debug/tracing/trace

    请添加图片描述
    这下终于一目了然了,可以看到引起jbd2的并不是什么应用软件,或者ext4日志事物的写入,而是一个叫做ext4lazyinit的东西。下面抄袭一段网上介绍:

    extlazyinit :在创建Ext4文件系统时,必须清理inode表的现有区域(用null覆盖,或“0”)。此过程需要大量时间。但是,一旦我们启用了“lazyinit”特性后,ext4文件系统的创建将显著加快,因为它不会立即初始化所有inode表,而是在后台的初始挂载过程中逐步初始化它们(内核版本2.6.37),这个过程会对文件系统的写入产生影响。

    解决

    简单来说ext4lazyinit其实也相当于快速格式化了吧,如果想在创建的时候就完全初始化inode可以用下面的命令:

     mkfs.ext4 -E lazy_itable_init=0,lazy_journal_init=0 /dev/sda1
    #  /dev/sda1 这个就是我们需要格式化的磁盘分区
    
    • 1
    • 2

    如何查看ext4lazyinit进程:
    可以通过bcc的biosnoop 工具查看对应的磁盘写入可以清晰的看到:

     ./biosnoop |grep 'sdh' |grep 'W'
    
    • 1

    ext4大容量分区问题

    禁用ext4lazyinit的格式化会发现需要非常旧的时间,格式化完毕会会发现硬盘空间被占了相当多,16T应该会占用256G,难怪我的硬盘都好几天了都还在写。这是因为ext4分区inode的设计导致的,ext4分区使用inode组成的bitmap以静态地址映射的方式来管理磁盘。ext4分区中每个inode占用256b大小空间。默认情况下,mkfs2fs会为每16kb的磁盘空间分配一个inode,格式化时系统根据磁盘大小,计算可以保存的文件个数,进而为inode保留空间。
    所以格式化大容量磁盘,系统会分配过多inode,为inode预留过多空间,导致磁盘空间占用特别大。这里可以得出inode占用整个分区的比例大概为256b/64k=1/64。那么16T就会占用16T/64=256G,经过计算下来发现已经是相当大的一个数字了,256G已经是一个不可忽略的数字。
    为此ext4支持设置多大磁盘空间分配一个inode,我们可以在格式化的时候用-i参数,下面格式化一个1M空间分配一个inode的分区:

     mkfs.ext4 -i 1048576 -E lazy_itable_init=0,lazy_journal_init=0 /dev/sda1
    #  /dev/sda1 这个就是我们需要格式化的磁盘分区
    
    • 1
    • 2

    除了-i参数还有-T可以指定

    mkfs.ext4 -T largefile -E lazy_itable_init=0,lazy_journal_init=0 /dev/sda1
    #1M一个inode
    mkfs.ext4 -T largefile4 -E lazy_itable_init=0,lazy_journal_init=0 /dev/sda1
    #4M一个inode
    
    • 1
    • 2
    • 3
    • 4

    另外需要注意inode也不能太少,太少了分区可容纳的文件个数就会变得很少,如果都是小文件就多分点inode,视频类大文件就少分点inode

    Linux各种类型分区的选择

    上面可以发现,ext4 inode并不是很适合超大容量分区使用,inode的分配并不好掌握,一旦格式化了又不能反悔,那一天分区变得不适合你用了岂不是麻烦。这里我还是比较看好xfs文件系统的,动态inode生成,用多少,生成多少,还能后期扩展,成熟稳定。所以以后超大分区我大概都会使用xfs文件系统了,下面借用网上一张图,看看各种文件系统的特点:
    在这里插入图片描述
    从这张图中可以看到btrfs和xfs都很不错,但是btrfs据说很不成熟,出问题了很难搞,所以我还是用xfs吧,打完收工!

    参考:
    Linux之文件系统选型

  • 相关阅读:
    Kubernetes的基础概念和网络通信方式(二)
    STC8H开发(十六): GPIO驱动XL2400无线模块
    vue3+vite项目配置ESlint、pritter插件
    5.Vue-在Vue框架中实现Vue的增删改查
    redis概念及python操作
    基于matomo实现业务数据埋点采集上报
    Less预处理——变量和嵌套
    Netty&NIO
    Linux查看内核和系统版本信息
    LVS-DR模式 +keepalived
  • 原文地址:https://blog.csdn.net/qq_16054639/article/details/126221955