分类: LINUX
2015-07-19 22:32:14
这里如果配合remap机制,将坏块重映射到新的位置,坏块就能够得到恢复了。目前软raid中并没有实现remap功能。
以下调研工作基于centos6.3的内核linux-2.6.32-279。
调研badblock机制有如下问题需要解决:
1. 如何保存badblock信息?
2. 什么时候会记录badblock信息?
3. 什么时候会清除badblock信息?
4. Badblock机制是否支持数据重映射功能?
5. 在有Badblock机制保证下何时会踢盘?
6. 发生badblock后,除了记录badblock信息,raid还会做什么处理?
Raid中,每个磁盘中都记录有raid的元数据信息,在centos6.3中,为了支持badblock机制,结构上做了如下调整:
1.修改描述磁盘元数据结构sb_page,增加与badblock机制有关的信息:
__u8 bblog_shift:决定raid是否支持badblock机制的开关;
__le16 bblog_size:记录badblock信息占用的数据大小(以512B为单位);
__le32 bblog_offset:记录badblock元数据的信息在磁盘上的起始位置。
2. 新加描述badblock的元数据结构bb_page;
3. 在描述磁盘信息的结构中增加结构badblock,其包含信息如下:
int count:坏块个数;
int unacked_exist:描述是否有未被处理的坏块;
int shift:用来表示坏块数据的单位。如果为0则为1个sector(512B);如果为1则为1K;如果为2则为2K,以此类推;为-1,表示关闭badblock的支持;
u64 *page:记录坏块位置以及长度等信息,为4K大小,每个坏块信息长度占8B,所以最大能够记录512个坏块信息;
sector_t sector:记录sb_page中的bblog_offset信息;
sector_t size:记录sb_page中的bblog_size信息。
除了元数据读写发生错误依然会踢盘外,在badblock机制保障下,正常IO路径一旦发生了读写错误,会调用函数md_set_badblocks,将当前数据位置offset(单位sector)以及数据长度size(单位sector)标记在badblock list中。
Badblock list的特性与实现方式如下:
1. Badblock机制中申请了一个page(4K)的空间来存储badblocks,每64位存储一个badblock信息,共可以存储512个badblock信息,超过512个badblocks,将没有空间存储而导致踢盘操作<踢盘触发点>;
2. 每64位存储的badblock信息内容为:
低9位表示该badblock的区域长度,所以最长可表示512<最大的坏块区域长度>
高1位暂未使用
中间的54位长度表示badblock的起始扇区
3. 一个page可以保存512个badblock,这些badblock按照起始扇区从小到大排序
4. Badblock区域如果相邻可以合并,但是合并后的区域长度最大为512sectors
5. 为了保证badblock的顺序,增加/清除一条badblock信息时,先按照二分查找法,找到插入位置,然后直接使用内存拷贝函数memmove进行位置的调整;
6. 判断某个数据块是否有错误,也是通过以上的二分查找法,如果确认数据块在badblock list中有记录,则认为此数据块已经为bad。
7. Raid的主控线程在检查到某个数据块为bad时,会触发局部rebuild操作,直到该块被修复。当一个bad的块能够被再次写入数据时,则认为该块修复完成可以清除其在badblock list中的记录,清除时会涉及到一条badblock信息是否进行拆分的处理。
当正常读写发生错误时,会首先尝试设置该块为bad:
1. 如果发现badblock机制没有开启或者当前磁盘已经有512个badblocks,则设置该块为bad失败,触发踢盘操作;
2. 如果badblock机制开启且当前磁盘badblocks个数没有达到512个,则设置bad成功,然后尝试局部数据rebuild操作,直到所有的badblock块都被修复为止<此部分会影响正常IO性能>
以raid5为例,当同一个条带中有两个磁盘及以上发生了读写错误,此时数据校验失败,就会给上层应用返回错误,导致上层应用终止;但是如果一个条带只有一个磁盘上发生了错误,会通过校验可以获取到正确的数据,此时上层应用正常运行。
经过调研发现,centos6.3平台自带的mdadm-3.2.3-9工具默认并不支持badblock机制的raid创建。调研了高版本mdadm-3.2.5,默认也不支持badblock机制的raid创建。通过给mdadm工具打patch可以支持创建带有badblock机制的raid。
测试平台:centos6.3
测试工具:dd(测试读/写,粒度4K)
Raid5参数:chunk=64k,bitmap-chunk=2048k,metadata=1.2
测试方法:cbd设备模拟同一位置坏块,在cbd和lvm设备上创建raid5
测试用例:
1. 三块磁盘,不开启badblock机制
测试结果:raid5在检测到磁盘有错误IO返回时,直接踢盘
2. 三块磁盘,开启badblock机制
测试结果:raid5在检测到磁盘有错误IO返回时,不踢盘,但是当同一条带错误次数>1次,上层IO会终止;
当同一条带只有1个错误时,应用会继续进行,可以看到每个盘上都有数据读写,尝试对坏块做局部修复操作,如果修复不了,就会将该sector标记为bad
测试总结
1. 不开启badblock机制时,如果发生IO错误,立刻踢盘;
1. 当某个区域发生读写错误时,只是标识为坏块,并没有实现remap机制,不能将坏块区域的数据remap到磁盘其他位置保存起来。并且主控线程检查到有坏块时,会触发坏块的rebuild操作,进行坏块修复,如果一直修复不成功,此部分会影响IO性能。
2. 只申请了一个page大小的区域保存坏块信息,每块磁盘最多只支持512个坏块,且代码设定的比较死,不能动态改变。
3. Mdadm工具未能支持使用badblock机制的raid设备创建。
1. 修改mdadm工具,使可支持badblock机制的raid设备创建
2. 当前badblock机制只支持最大512个坏块,且代码设计比较死,此部分可以重新设计,不过牵扯到磁盘layout结构、元数据信息等变化,改动比较大
3. 设计数据重映射机制,和badblock机制结合起来,可以增加raid设备的稳定性。
针对前面文档中提到的问题,这里总结如下:
1. 如何保存badblock信息
metadata1.2版本,每个磁盘开头部分有一片4K大小的区域,badblock信息保存在此。
2. 什么时候会记录badblock信息?
正常IO错误发生时,会记录badblock信息。
3. 什么时候会清除badblock信息?
当标记为badblock的区域可被写成功时,会清除badblock信息。
4. Badblock机制是否支持remap功能?
不支持。
5. 在有Badblock机制保证下何时会踢盘?
当错误块超过512时,依然会触发踢盘操作。
6. 发生badblock后,除了记录badblock信息,raid还会做什么处理?
触发坏块rebuild操作,此操作会影响io性能。