我试图了解 ZFS 在特定条件下的行为,但文档对此并不十分明确,所以我只能猜测。
假设我们有一个具有冗余的 zpool。请考虑以下事件序列:
设备 D 与服务器之间的连接出现问题。这会导致大量故障,因此 ZFS 导致设备故障,使池处于降级状态。
当池处于降级状态时,池会发生变异(写入和/或更改数据)。
连接问题已得到物理修复,因此设备 D再次可靠。
管理员知道 D 上的大部分数据都是有效的,并且不想不必要地用重新同步来给池增加压力,因此运行了
zpool clear pool D
。 Oracle 的文档指出,这是适当的操作,其中故障是由于已更正的暂时性问题引起的。
我读到过,这zpool clear
只会清除错误计数器,并将设备恢复到在线状态。然而,这有点麻烦,因为如果全部如果这样,池就会处于不一致的状态!
这是因为步骤 2 中的突变不会成功写入 D。相反,D 将反映连接故障之前的池状态。这当然不是 zpool 的常态,并且可能导致另一台设备发生故障时硬数据丢失 - 但是,池状态不会反映此问题!
我至少会假设,基于 ZFS 强大的完整性机制,尝试从 D 读取变异数据会发现错误并进行修复。然而,这引发了两个问题:
除非进行清理,否则读取不能保证命中所有突变;
一旦ZFS做触及变异的数据,它(我猜测)可能会再次导致驱动器故障,因为在 ZFS 看来它正在破坏数据,因为它不记得以前的写入失败。
理论上,ZFS 可以通过跟踪降级状态期间发生的变更并在清除 D 时将其写回 D 来规避此问题。但出于某种原因,我怀疑事实并非如此。
我希望对 ZFS 有深入了解的人可以对这方面提供一些指导。
答案1
“从理论上讲,ZFS 可以通过跟踪降级状态下发生的突变并在清除后将其写回 D 来规避此问题。但出于某种原因,我怀疑事实并非如此。”
实际上,这几乎就是它在这种情况下可以做的事情。你看,每次写入 ZFS 池中的磁盘时,当前的全局池事务 ID 都会写入磁盘。因此,假设,例如,您遇到了您解释的情况,并且连接丢失和恢复之间的总时间小于 127 * txg_timeout(并且这对池上的负载和其他一些事情做出了许多粗略的假设,但为了典型的安全性,假设为一半,因此如果 txg_timeout 是 10 秒,那么 600 秒或 10 分钟是合理的时间,可以期望它仍然有效)。
在断开连接之前,池能够成功写入与事务 ID 20192 相关的写入。随着时间流逝,磁盘恢复了。当磁盘再次可用时,池已经经历了许多事务组,并且事务 ID 为 20209。此时,ZFS 仍有可能执行所谓的“快速重新同步”,即重新同步磁盘,但仅限于事务 ID 20193 至 20209,而不是完全重新同步驱动器。这样可以快速高效地使磁盘与池的其余部分一起恢复规格。
但是,启动该活动的方法不是“zpool clear”。如果一切正常,那么在磁盘恢复正常时,重新同步应该会自动启动。事实上,它可能运行得非常快,您从未看到过。在这种情况下,“zpool clear”将是清除设备消失时出现的仍然可见的错误计数的正确活动。根据您使用的 zfs 版本、操作系统、设备当前被 zfs 列出的方式以及设备处于该状态的时间长短,修复此问题的“正确”方法会有所不同。它实际上可能是“zpool clear”(清除错误,并且驱动器的下一次访问应该会注意到不同步的 txg id 并启动重新同步),或者您可能需要使用“zpool online”或“zpool replace”。
当所有这些正常工作时,我习惯看到的是磁盘消失,驱动器进入 OFFLINE 或 DEGRADED 或 FAULTED 或 UNAVAIL 或 REMOVED 状态。然后,当驱动器在 OS 级别再次可访问时,FMA 和其他 OS 机制启动,ZFS 意识到磁盘已返回,并且快速重新同步,设备再次以 ONLINE 状态出现在 zpool 状态中,但可能仍具有与之关联的错误计数。关键是它处于 ONLINE 状态,这表明自动修复(重新同步)成功。您可以通过拔出任何驱动器、等待几秒钟并检查“zpool status”,然后重新插入磁盘并再次检查“zpool status”并查看发生的情况来对其进行测试。ZFS 并不是这里唯一的移动部件 - ZFS 实际上在很大程度上依赖于其他 OS 机制来告知它磁盘的状态,如果这些机制失败,您将获得与成功不同的症状。
在任何一种情况下,快速恢复要么能够运行并成功,要么无法运行或失败。如果是后者,磁盘将有在返回工作之前完成完整的重新同步,因此,除非管理员覆盖允许具有不匹配 txgid 的磁盘重新进入池而不对该差异进行任何形式的更正(通常不可能),否则您帖子底部列出的两个问题通常是不可能的。如果发生这种情况,我怀疑下次访问驱动器要么会导致启动快速重新同步(并成功,或失败并将磁盘推入完全重新同步),要么最终会将磁盘踢出 - 或者可能由于 txgid 差异而导致恐慌。在任何这些事件中,都不会发生数据丢失或向请求返回不正确的数据。
答案2
注意:
- ZFS 上的每个数据块都有公平校验和。因此,当发生故障时,ZFS 知道哪个驱动器在冗余设置中保存了正确的数据。运行
zpool scrub ZFSPOOL
将修复数据或将数据传播到所有正在运行的驱动器以进行 RADZ。 - ZFS 采用Reed-Solomon 错误修正这对于突发错误来说是最好的。丢失驱动器就是这种突发错误,RS 可以纠正。
当数据中心的空调出现问题时,驱动器上会出现许多 DMA 错误,而 ZFS 能够解决这一问题。而且这只是简单的镜像。
我确实记得 SUN 在推出 ZFS 时发布的宣传视频……他们在部署到 8 端口 USB 集线器的 USB 闪存驱动器上制作了 RAIDZ,然后在集线器中随机更改了其中几个的位置,同时在该池上执行 IO,没有观察到中断。