我正在备份存储在由单个 raidz vdev 和 2 个硬盘组成的 zpool 中的数据。在此操作期间,我收到校验和错误,现在状态如下:
pool: tmp_zpool
state: ONLINE
status: One or more devices has experienced an error resulting in data
corruption. Applications may be affected.
action: Restore the file in question if possible. Otherwise restore the
entire pool from backup.
see: http://zfsonlinux.org/msg/ZFS-8000-8A
scan: none requested
config:
NAME STATE READ WRITE CKSUM
tmp_zpool ONLINE 0 0 2
raidz1-0 ONLINE 0 0 4
tmp_cont_0 ONLINE 0 0 0
tmp_cont_1 ONLINE 0 0 0
errors: Permanent errors have been detected in the following files:
/some/file
让我感到困惑的是,校验和错误出现在 vdev 级别,而不是磁盘级别。也许我应该注意,其中一个硬盘是内置的,另一个是外置的(这是暂时的情况)。这可能是硬盘控制器的问题吗?
我可以尝试做些什麽来恢复受影响的文件?比如清除错误并仅使用其中一个磁盘导入 vdev 降级?我甚至没有尝试再次读取文件来查看会发生什么。(不确定是否会影响任何事情。)
更新:我放弃了等待清除错误并重试可能出错的解释,所以我继续尝试。我首先这样做了zpool clear
,然后zpool status
没有显示任何错误。然后,我尝试读取有错误的文件(最后有 2 个),但相应的块仍被报告为坏的/不可读的。这一次,zpool status
不再显示增加的校验和错误。接下来,我尝试使 raidz1 vdev 中的一个磁盘脱机并重复该过程,但结果没有改变。总共,我丢失了 1.6T 中的 2 个 128K 块。
答案状态:目前,我发现这个问题没有全面的答案。如果有人想写一个或编辑现有的答案,请解决以下问题:
- 什么原因可能导致这种情况?
- 该怎么办呢?
- 如何才能预防呢?
对于 1,理论及其问题似乎是:
选择
raidz1
而不是raidz2
。问题: 至少需要 4 个磁盘raidz2
。虽然冗余的必要性很明显,但反复建议解决冗余失败的方法是增加冗余是没有用的。了解如何最好地利用您拥有的冗余会更有用。选择 而
raidz1
不是mirror
。问题:乍一看,它们之间的区别似乎在于效率,而不是冗余。但这可能是错的。原因:zfs 为每个磁盘上的每个块保存一个校验和,但两个磁盘都没有报告单独的校验和错误。这似乎表明,对于每个坏块,2 个磁盘包含不同的块有效负载,每个块都有匹配的校验和,而 zfs 无法判断哪个是正确的。这表明有 2 个不同的校验和计算,并且有效负载在它们之间发生了变化。这可以用 RAM 损坏来解释,也许(需要确认)选择 而不是mirror
,raidz1
只需要一个校验和。RAM 损坏发生在写入期间,而不是读取期间。如上所述,这似乎是合理的。问题:为什么在写入时没有将其检测为错误?是不是 zfs 没有检查它写入的内容?或者,写入不同磁盘的块有效负载是相同的?
对于 2:
- 由于磁盘没有单独的校验和错误,zfs 中是否存在某种低级方式来访问此类坏块的 2 个不同副本?
对于 3:
显然,这样
mirror
做raidz1
就能避免这种情况发生吗?我假设对该 zpool 的清理已检测到问题。就我而言,我正在移动一些数据,并在实际读取该 zpool 之前销毁了源数据,以为我有 2 个磁盘冗余。这里的道德观念是在信任其内容之前清理 zpool 吗?清理当然是有用的,但有必要吗?例如,是否有必要使用 而
mirror
不是 进行清理raidz1
?
答案1
这是 raidz1(以及 RAID5)的问题。如果磁盘上的数据发生变化,但没有发生驱动器故障,无法让 ZFS 或 RAID 控制器知道哪个驱动器导致了错误,那么它就无法知道哪个驱动器是正确的。使用 raidz2(及更高版本)或 RAID6,您可以获得一组驱动器,这些驱动器可以决定忽略哪个驱动器进行重建。
您唯一的解决方案是覆盖该文件,方法是恢复备份副本或写入/dev/null
该文件。
答案2
我遇到了类似的问题。我不确定这是否有帮助,但我找到了 FreeBSD 开发人员发布的有关 vdev 级校验和错误的相关文章。
https://lists.freebsd.org/pipermail/freebsd-hackers/2014-October/046330.html
如果 vdev_raidz.c 无法确定哪个叶子 vdev 负责,则校验和错误将出现在 raidz vdev 上,而不是叶子上。如果两个或多个叶子 vdev 对同一块返回坏数据,则可能会发生这种情况,这也会导致无法恢复的数据错误。我看到您遇到了一些无法恢复的数据错误,所以也许这就是您遇到的情况。
ZFS 中的细微设计错误也可能导致 vdev_raidz.c 无法确定哪个子设备导致了校验和错误。但是,我只见过当 raidz vdev 有镜像子设备时发生这种情况。只有当子设备是备用或替换 vdev 时才会发生这种情况。您是否激活了任何备用设备,或者您是否手动替换了 vdev?
我自己正在考虑删除我的zpool.cache
文件并导入我的池来重新生成该zpool.cache
文件。