linux内核raid5坏块读之谜


从原理上讲,raid5出现坏块之后读操作肯定是会绕道读取的。我用设置/sys/block/md1/md/dev-sdb/bad_blocks的方法来模块磁盘坏块,用dd从md读数据,从iostat查看的数据流。 创建一个三个盘的raid5:
    Number   Major   Minor   RaidDevice State
       0       8       80        0      active sync   /dev/sdf
       1       8       32        1      active sync   /dev/sdc
       2       8       48        2      active sync   /dev/sdd

设置坏块:
cd /sys/block/md1/md/dev-sdf
echo 262144 2048 > bad_blocks
cat bad_blocks 
263680 512
263168 512
262656 512
262144 512

对raid进行读操作:
dd if=/dev/md1 of=/dev/null bs=64K count=1 

iostat查看流量:
avg-cpu:  %user   %nice %system %iowait  %steal   %idle
           0.17    0.00    0.00    0.00    0.00   99.83

Device:         rrqm/s   wrqm/s     r/s     w/s    rkB/s    wkB/s avgrq-sz avgqu-sz   await r_await w_await  svctm  %util
sda               0.00     0.00    0.00    0.00     0.00     0.00     0.00     0.00    0.00    0.00    0.00   0.00   0.00
sdg               0.00     0.00    0.00    0.00     0.00     0.00     0.00     0.00    0.00    0.00    0.00   0.00   0.00
sdh               0.00     0.00    0.00    0.00     0.00     0.00     0.00     0.00    0.00    0.00    0.00   0.00   0.00
sdi               0.00     0.00    0.00    0.00     0.00     0.00     0.00     0.00    0.00    0.00    0.00   0.00   0.00
sdj               0.00     0.00    0.00    0.00     0.00     0.00     0.00     0.00    0.00    0.00    0.00   0.00   0.00
sdb               0.00     0.00    0.00    0.00     0.00     0.00     0.00     0.00    0.00    0.00    0.00   0.00   0.00
sde               0.00     0.00    0.00    0.00     0.00     0.00     0.00     0.00    0.00    0.00    0.00   0.00   0.00
sdf               5.00     0.00    0.33    0.00    21.33     0.00   128.00     0.00    0.00    0.00    0.00   0.00   0.00
sdc               5.00     0.00    0.33    0.00    21.33     0.00   128.00     0.00    0.00    0.00    0.00   0.00   0.00
sdd               0.00     0.00    0.00    0.00     0.00     0.00     0.00     0.00    0.00    0.00    0.00   0.00   0.00
md1               0.00     0.00   10.67    0.00    42.67     0.00     8.00     0.00    0.00    0.00    0.00   0.00   0.00

从上面的数据流看出几个问题: 1、sdf相应位置已经设置为坏块了,为什么还有读流量呢? 2、只读64K的数据,只为一个chunk数据,为什么两个盘都有流量? 3、读64K的数据,但是实际有128K数据?
想了半天增加了一些打印信息没有答案。最后只有发大招了,在md_make_request打印bio流量,在is_badblock添加打印。 查看结果发现下发的bio比实际流量大,是dd的预读起作用了。 而坏盘仍然有读是因为设置坏块echo 262144 2048 > bad_blocks之后坏块没有排序,导致raid没有识别出坏块,这应该算是内核的一个BUG吧。所以设置坏块需要设置坏块长度不超过512。

相关内容