今天和刘毅同学一起研究了一下集群里机器hang住的现象。
所谓“hang住”,就是磁盘抽风(当然,也可能是sas/raid卡抽风),对发给它的io都不返回,造成许多访问它的进程都进入“D”状态,应用停止工作,等在read/write等系统调用上,严重的甚至终端命令都无法返回。

几个主要的场景都出现了ext4的报错:

EXT4-fs (sdx): delayed block allocation failed for inode 98838775 at logical offset 2048 with
 max blocks 2048 with error -5

有的还伴随CDB错误:

sd 0:0:8:0: [sdx] CDB: Read(10): 28 00 c0 c0 00 57 00 00 08 00
end_request: I/O error, dev sdi, sector 3233808471

分析了一下,分两种情况。

第一种情况——kernel没报CDB错误,但是ext4的delay alloc报错且应用hang住了。看/var/log/messages,前面有这么几行:

Jul 31 15:24:01 kernel: : [1391835.617793] EXT4-fs error (device sdx): 
ext4_init_block_bitmap: Checksum bad for group 1664
Jul 31 15:24:02 kernel: : [1391835.749685] EXT4-fs error (device sdx): 
ext4_mb_generate_buddy: EXT4-fs: group 1664: 0 blocks in bitmap, 24544 in gd

ext4已经发现checksum不对了,还记得这个“ext4_mb_generate_buddy”在之前的实验中遇到过,block-group一旦数据被破坏,报的就是这个错误。虽然ext4有uninit_bg,但是这依赖于硬盘中那个小小的struct ext4_group_desc中的flag带有EXT4_BG_BLOCK_UNINIT这个bit,如果fio破坏了这个bit,把它给从1变0了,那就相当没有开启uninit_bg,ext4上来就认为这个group已经初始化,一检查检验和就发现不对了。后面一切逻辑也都不对了。看来ext4对裸盘读写不是完全免疫的,只是比ext3抗磨一些。

第二种情况,有CDB错误但是delay alloc还是hang住了。发生读CDB错误,那ext4的代码在分配文件空间的时候(就是delay alloc开始往磁盘上落的时候),读到元数据就是错的,分配空间失败,那就一定报错

fs/ext4/inode.c
mpage_da_map_and_submit()

        blks = ext4_get_blocks(handle, mpd->inode, &map,
                               &new, get_blocks_flags);
        if (blks < 0) {
                ....
                ext4_msg(mpd->inode->i_sb, KERN_CRIT,
                         "delayed block allocation failed for inode %lu at "
                         "logical offset %llu with max blocks %zd with "
                         "error %d", mpd->inode->i_ino,
                         (unsigned long long) next,
                         mpd->b_size >> mpd->inode->i_blkbits, err);
                printk(KERN_CRIT "This should not happen!!  "
                       "Data will be lost\n");
                ....

总的来说,虽然都发生delay alloc的报错,但并不是ext4本身的问题,只因为它是个热路径,所以每次下层的错误都是它先倒霉。所以,首先,要确保mkfs之后不再用fio读写裸盘,再观察一段时间,看是否还有无CDB错误但hang住的情况;其次,如果可能,慢慢分批把机器的mpt2sas驱动升级,因为没有磁盘真正损坏却这么多CDB错误,mpt2sas驱动有很大的嫌疑。