0
集群里机器hang住 备忘1
今天和刘毅同学一起研究了一下集群里机器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 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驱动有很大的嫌疑。
原文链接: http://blog.donghao.org/2013/08/01/cluster_hang_note1/