snapraid的功能试验&验证--于OMV5--udpated/2024.1.5
一、相关科普
a.静默数据错误(silent data corruption):或称静默错误,bitrot,位翻转。由于不可抗力导致的磁盘上某个二进制数据位由0变1(或相反),导致数据错误。
二、对比几种有冗余功能的存储方案
Raid:这里主要讲基于硬件实现的raid阵列。这是一种条带式阵列,每个文件被拆分成多份分别存储在阵列的每个硬盘上,由此可见,当失去冗余能力时,所有数据都将不可恢复。
ZFS:ZFS阵列本身结构类似raid都是条带式(形似raid5,raid6),但zfs通过软件实现,相比raid提供更高的冗余级别和静默错误的应对方式。扩容主要有2种方式,新建相同的阵列合并;或是逐次用更大的硬盘替换已有硬盘,每次替换都要重建一次 。
Unraid:和snapraid相似,基于目录的阵列,每个数据盘都是单独分区,单盘使用,扩容方便直接加硬盘即可。Unraid是实时的冗余模式,当发生任何写入时会对各硬盘相同区块计算校验码,然后存入校验盘,这就可能导致写入速度较慢,而校验盘的压力比较大,当然,可以通过添加SSD作为缓存提高速度。Unraid本身不支持静默错误检查和修复。在unraid系统上,插件,docker等支持齐全,适合ALL in ONE。
Snapraid:和unraid系统不同只是一个软件工具,同时也提供了Windows版本(没有webUI)。Snapraid的校验并不是实时进行的,需要配置计划任务进行同步校验,而针对静默数据的问题,snapraid可以周期性地擦洗(scrub)一定量的数据,并对比校验数据发现问题提供修复方法。
附图简单对比各种阵列。(仅供参考,技术细节的描述可能有所出入)
三、Snapraid功能试验
实验环境:
VMware虚拟机,OpenMediaVault 5系统安装snapraid插件;snapraid配置如图:
(一)、误删除恢复
1. 更新校验
snapraid sync # 更新校验会将所有的文件同步到当前状态,包括被修改或删除的(即,删除或修改后立即校验的话,将无法恢复校验前的状态)
等同以下操作;
snapraid -h sync # -h,--pre-hash 预哈希的更新校验方式
写入前,首先计算一次hash,确保在写入过程不会因额外硬件错误发生静默错误(通常是在系统负载较高的情况下),但是会消耗几乎两倍的时间。
2. 记录MD5,删除文件
被删除的3个文件的MD5,文件存储在data_a02上:
3. 修复
a. 全盘修复,此操作会将过往被删除的或被修改的文件,恢复到更新校验时的状态(新加文件不会作改动)
snapraid fix
b. 恢复特定文件或目录
snapraid fix -f [FileName] #文件名不需路径,不检查其他仅恢复文件名所指文件。注意文件名带空格的文件 snapraid fix -f [DIR/] #目录不需路径,恢复目录,加上 -m 仅恢复该目录内丢失的文件而不影响其他文件
此操作仅恢复指定名称的文件或文件夹
4. 被删除的文件全部恢复,检查MD5与前面一致
(二)模拟磁盘损坏并恢复数据
1. 更新校验 snapraid sync
略
2. 卸载数据盘模拟磁盘损坏丢失
3. 装载备用盘
新盘创建分区并挂载
把新硬盘添加到snapraid阵列
4.修复
a.点击修复 snapraid fix
b.运行修复命令,并将日志存储在外部文件中
snapraid -d NAME -l fix.log fix # 实际使用时建议使用该命令,因为snapraid fix会将已有文件全部恢复到更新校验时的状态
其中NAME是磁盘的名称。如果要恢复的磁盘是奇偶校验盘,请使用"parity","2-parity"等名称。如果您有更多损坏的磁盘,请使用多个-d选项来指定所有这些选项。
引用:https://www.zhihu.com/column/p/32040033
5. 结果
对比容量及随机检查几个文件的MD5,恢复成功
注:截图中的snapraid.content是snapraid的索引文件在多个磁盘中存有备份,snapraid更新校验时会排除该文件,因此修复后该文件不会恢复。
(三)、模拟静默错误并修复文件
说明:测试文件为数据盘上的名为rawfile的文件,该数据盘容量1GB,磁盘设备为/dev/sdb1。卸载/挂载操作在OMV5 web界面上进行。
1. 创建测试文件记录MD5以及rawfile和/dev/sdb1在50M偏移量处的字符
a. 创建一个900M的空文件
# dd if=/dev/zero of=rawfile bs=1M count=900 # MYLOOP=$(losetup -f --show rawfile) # echo $MYLOOP /dev/loop0 # mkfs.ext4 $MYLOOP # mount $MYLOOP /mnt
b. 以字符y填充文件
# yes >/mnt/infile yes: standard output: No space left on device # umount /mnt # losetup -d $MYLOOP # dd if=rawfile bs=1 count=10 skip=$((50*1024*1024)) 2>/dev/null|hexdump -vC 00000000 79 0a 79 0a 79 0a 79 0a 79 0a |y.y.y.y.y.| 0000000a # dd if=/dev/sdb1 bs=1 count=10 skip=$((50*1024*1024)) 2>/dev/null|hexdump -vC 00000000 79 0a 79 0a 79 0a 79 0a 79 0a |y.y.y.y.y.| 0000000a # md5sum rawfile 5e0fe3395be4be49ea3628b1c88e5eaa rawfile
2. 更新校验并卸载数据盘
若不卸载磁盘设备直接操作rawfile文件,文件属性会被改变,包括修改时间(详见 stat rawfile 命令),则snapraid scrub不会认为产生了error,而是文件被update。
*2021.02.26 update.(不明原因[某种系统缓存机制??],echo ‘x’ | dd 更改之后md5sum结果可能不变,需要umount后,再mount才正常)
可不卸载数据盘,后续操作没有直接更改rawfile,对/dev/sdb1的操作不会影响rawfile文件属性(能被snapraid识别的)。
3. 使用dd命令操作/dev/sdb1,把50M偏移量处的字符y改成字符x
(y十六进制0x79,x十六进制0x78,在二进制表示中只有一位发生变化)
# dd if=/dev/sdb1 bs=1 count=10 skip=$((50*1024*1024)) 2>/dev/null|hexdump -vC 00000000 79 0a 79 0a 79 0a 79 0a 79 0a |y.y.y.y.y.| 0000000a # echo 'x' | dd of=/dev/sdb1 bs=1 count=1 seek=$((50*1024*1024)) conv=notrunc # dd if=/dev/sdb1 bs=1 count=10 skip=$((50*1024*1024)) 2>/dev/null|hexdump -vC 00000000 78 0a 79 0a 79 0a 79 0a 79 0a |x.y.y.y.y.| 0000000a
4. 挂载数据盘,检查当前MD5,记录rawfile和/dev/sdb1在50M偏移量处的字符
# dd if=rawfile bs=1 count=10 skip=$((50*1024*1024)) 2>/dev/null|hexdump -vC 00000000 79 0a 79 0a 79 0a 79 0a 79 0a |y.y.y.y.y.| 0000000a # dd if=/dev/sdb1 bs=1 count=10 skip=$((50*1024*1024)) 2>/dev/null|hexdump -vC 00000000 78 0a 79 0a 79 0a 79 0a 79 0a |x.y.y.y.y.| 0000000a # md5sum rawfile 5a6a74908aa41084817daa14a1c344fa rawfile
可见rawfile的MD5已经发生改变。另外,观察到rawfile在50M偏移量的字符未改变,说明rawfile和/dev/sdb1的数据位并不一一对应(一个是文件,一个是块设备,无视无视)
5. 数据盘添加到snapraid阵列,scrub检查数据(OMV上翻译为侦测)
snapraid -p 100 -o 0 scrub # 指定立即擦洗100%的数据(无参情况下,只会擦洗‘8%且超过10天未被擦洗’的数据)
如图,检查到数据错误,按照提示可以列出错误的块位置或直接进行错误修复
snapraid diff
没有检测到文件更新或是修改
snapraid sync
在存在静默错误的情况下,更新校验不会把错误数据校验保存到校验盘,因此仍可以使用已有校验数据修复静默错误
6. 修复及结果,对比rawfile的MD5与原来一致
# snapraid -e fix
# md5sum rawfile
5e0fe3395be4be49ea3628b1c88e5eaa rawfile
在修复时,由于操作了rawfile,snapraid diff 认为文件更新了
7. 静默错误模拟方法参考:https://www.redhat.com/en/blog/what-bit-rot-and-how-can-i-detect-it-rhel
(四)、进阶——双校验盘环境下的试验-udpated/2024.1.5
说明:试验环境为3个数据盘,2个校验盘,模拟测试同时损坏1个数据盘和1个校验盘的情况下snapraid的恢复能力
1. 目录结构和硬盘挂载情况如图:
2. 删除数据盘d1和校验盘p1的所有内容
3. 用snapraid fix修复,可以看到数据盘d1和校验盘p1的文件都被恢复(除了snapraid.conf 配置当中排除的文件)
4. 进一步测试 同时损坏数据盘d1和校验盘p1,并且在数据盘d2有文件(例子中是 music-3.mp3)被删除或者修改的情况下,能否正常修复
5. 执行snapraid fix 后,发现有文件无法恢复
四、Snapraid实际应用总结
通过上面的试验,可以总结出以下几个重要的snapraid工作机制
1.没有版本控制功能,更新校验之后就无法把数据/文件恢复到以前的状态,考虑到snapraid本质是提供数据冗余功能而不是数据备份,因此这个结果也很正常。所以我们需要注意更新校验的时机。
2.更新校验(sync)和数据擦洗(scrub)不会冲突,校验不会对产生静默错误的数据进行更新。另外,校验是增量形式,不会每次更新都全数据盘进行校验。
3.无参数的修复功能会把所有数据恢复到前次校验的状态。因为该特性,我们需要特别注意,如果数据盘是经常改动的则不建议使用"修复"(ovm5上),不过通常情况下也不需要使用无参的fix。
4. 重要 根据 udpated/2024.1.5 的试验结果,在一次sync之后,如果对任意数据盘上的文件有“删除”“修改”,应尽快执行下一次的sync,以免有硬盘损坏后无法把坏盘上的数据都恢复过来。