一些背景知识:
我将 VM 映像、我的主目录、我的邮件、我的媒体集合存储在单主 DRBD 设备上,该设备构建于 LVM 逻辑卷上,而 LVM 逻辑卷构建在两个 RAID0 阵列(每个 DRBD 集群节点上一个)上。 RAID0是为了改善访问时间。 DBRD集群中的两个节点提供冗余。我每小时备份我的家庭和邮件,每周备份虚拟机操作系统和媒体集合,所有这些都在异地进行。偶尔会出现中断,但恢复总是很简单并且不会丢失数据。我不需要第三个节点的复杂性来提供仲裁。这种设置长期以来一直运作良好。
然而,我知道我没有涉及到的一个领域是 bitrot。我怎么知道那部十年没看的电影还能看呢?我如何知道我没有备份损坏的数据?
所以我有一个脚本可以保存所有文件的校验和并将它们与上次运行进行比较,报告任何差异。显然,使用操作系统提供的一些工具来完成同样的事情会更好。我首先想到的是 Btrfs 和 ZFS。从我的谷歌搜索来看,Btrfs 在这方面还不成熟,而 ZFS 很成熟。另外,我对 ZFS 更加熟悉,因此 ZFS 是我的首选解决方案。
接下来是我想回答的主要问题:ZFS 能否检测到其后备存储中的损坏?
由于我周围没有备用物理机,因此我计划尝试使用在其自己的“磁盘”中具有一些未分配空间的虚拟机来创建一个逻辑卷来模拟物理磁盘,将其提供给 ZFS,创建一个 zvol ,将随机数据写入逻辑卷并检查:
- zvol 内容的校验和要么以某种方式失败(也许 ZFS 将使 zvol 脱机),要么校验和发生更改,并且
- ZFS 会标记损坏的后备存储,尽管可能仅在我进行清理时进行。
鉴于此测试不起作用(详细信息如下),也许我的实验或我的期望已经存在缺陷?
无论如何,这就是我所做的:
卷组中有足够的空间,因此我可以创建一个 LV 用作 ZFS 的后备存储:
penne# vgs
VG #PV #LV #SN Attr VSize VFree
vg0 1 3 0 wz--n- <40.46g <6.46g
penne# lvcreate --name=lvtest --size=1g vg0
Logical volume "lvtest" created.
penne#
我将该 LV 分配给一个新的 ZFS 池并从中创建一个 zvol:
penne# zpool create zpooltest /dev/vg0/lvtest
penne# zfs create -V 800M zpooltest/zvoltest
penne#
可以这么说,我将在后备存储“在 ZFS 后面”大约一半处写入 1MB 的损坏内容。后备店有多大?
penne# dd if=/dev/vg0/lvtest of=/dev/null bs=1M
1024+0 records in
1024+0 records out
1073741824 bytes (1.1 GB, 1.0 GiB) copied, 3.24444 s, 331 MB/s
penne#
所以中间大约有 500000000 字节。
zvol 的校验和是我感兴趣的东西。如果我使用 raidz,那么我希望损坏不会影响其校验和,因为 ZFS 可以解决损坏问题,但是当使用单个磁盘后备存储时,我希望要更改的校验和并清理以报告磁盘错误。所以我首先查看 zvol 的校验和:
penne# dd if=/dev/zvol/zpooltest/zvoltest bs=1M 2>/dev/null | md5sum
ebbcd350dfe34f526c0d80b3bf2d07dd -
penne#
现在我损坏了后备存储中间的 1MB:
penne# dd if=/dev/urandom of=/dev/vg0/lvtest seek=500000000 bs=1 count=1000000 conv=notrunc
1000000+0 records in
1000000+0 records out
1000000 bytes (1.0 MB, 977 KiB) copied, 1.27545 s, 784 kB/s
penne#
并重新检查 zvol 的校验和:
penne# dd if=/dev/zvol/zpooltest/zvoltest bs=1M 2>/dev/null | md5sum
ebbcd350dfe34f526c0d80b3bf2d07dd -
penne#
为什么没有改变?
鉴于 zvol 的内容似乎没有改变,那么磨砂什么也不做也就不足为奇了:
penne# zpool scrub zpooltest
penne# zpool status
pool: zpooltest
state: ONLINE
scan: scrub repaired 0B in 00:00:00 with 0 errors on Fri Mar 17 14:08:29 2023
config:
NAME STATE READ WRITE CKSUM
zpooltest ONLINE 0 0 0
lvtest ONLINE 0 0 0
errors: No known data errors
penne#
我意识到块被缓存在各处,所以我重新启动以刷新所有内容,然后重新检查 zvol 的校验和:
penne# reboot
...
penne# dd if=/dev/zvol/zpooltest/zvoltest bs=1M 2>/dev/null | md5sum
ebbcd350dfe34f526c0d80b3bf2d07dd -
penne#
还是一样!为什么?
同样,鉴于 zvol 的内容似乎没有改变,那么另一个擦洗不执行任何操作也就不足为奇了:
penne# zpool scrub zpooltest
penne# zpool status
pool: zpooltest
state: ONLINE
scan: scrub repaired 0B in 00:00:00 with 0 errors on Fri Mar 17 14:09:27 2023
config:
NAME STATE READ WRITE CKSUM
zpooltest ONLINE 0 0 0
lvtest ONLINE 0 0 0
errors: No known data errors
penne#
我见过这发布但未能检测到损坏的原因是损坏非常接近后备存储的开头。但就我而言,我正在后备存储的中间写出 slap-bang 。
最后,我要问你的问题是:到底发生了什么事?
操作系统是Debian 11,ZFS是OpenZFS 2.0.3。
谢谢!
亚历克西斯