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

起因

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

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

一切配置好后本以为万事大吉了,谁成想到时间后硬盘就是不能休眠,观察后发现硬盘一直在工作,即使我啥也没干。用sar -d -n 1发现硬盘移植有少量数据不断写入,使用sudo lsof又抓不到任何进程在操作硬盘,这就有点奇怪了。最后只好祭出神器iotop了,iotop抓取结果如下(我的硬盘是sda1-8):
记录一次jbd2不停写磁盘原因追查_第1张图片
好家伙,这会终于看到元凶了。是这个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不停写磁盘原因追查_第2张图片
这下终于一目了然了,可以看到引起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 这个就是我们需要格式化的磁盘分区

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

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

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 这个就是我们需要格式化的磁盘分区

除了-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

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

Linux各种类型分区的选择

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

参考:
Linux之文件系统选型

你可能感兴趣的:(linux,服务器,运维,jbd2,ubuntu,ext4)