![ZFS 能应对突然断电吗?(如果磁盘本身没有发生故障或变得不可靠,哪些事件会导致池无法恢复)](https://linux22.com/image/1509870/ZFS%20%E8%83%BD%E5%BA%94%E5%AF%B9%E7%AA%81%E7%84%B6%E6%96%AD%E7%94%B5%E5%90%97%EF%BC%9F%EF%BC%88%E5%A6%82%E6%9E%9C%E7%A3%81%E7%9B%98%E6%9C%AC%E8%BA%AB%E6%B2%A1%E6%9C%89%E5%8F%91%E7%94%9F%E6%95%85%E9%9A%9C%E6%88%96%E5%8F%98%E5%BE%97%E4%B8%8D%E5%8F%AF%E9%9D%A0%EF%BC%8C%E5%93%AA%E4%BA%9B%E4%BA%8B%E4%BB%B6%E4%BC%9A%E5%AF%BC%E8%87%B4%E6%B1%A0%E6%97%A0%E6%B3%95%E6%81%A2%E5%A4%8D%EF%BC%89.png)
所有资源都说 ZFS 没有 fsck 或恢复工具,使用电池支持的 SSD 为 ZIL 等。
如果突然以某种方式拔掉插头(尽管有UPS等,但仍然完全断电,但假设没有物理损坏,没有磁头崩溃等),SSD会将缓存写入nvram,然后变得安静......
当 ZFS 重新启动时,它有多大可能保持一致状态(即使丢失了一些数据)并且池可用/可读?
更新
我意识到我其实是想问一个更接近的问题,什么事件会导致 ZFS 放弃读取池,尽管数据基本完好无损?目前还不清楚 ZFS 可以恢复什么(或者在有合适的硬件的情况下可以恢复)以及它不能恢复什么(或者在没有合适的硬件的情况下不能恢复),因为它在内部做了很多自我检查和修复工作。显然,冗余不足+磁盘故障(或其他主要硬件问题)是一种情况,而由于固件/软件错误导致的完全擦除/覆盖是另一种情况。但是假设存储介质、硬件和软件仍然可靠/正常工作,还有哪些问题会导致游泳池丢失?修复游泳池的极限在哪里?哪些情况会出现,才能阻止修复?又需要发生什么情况才能引发这些情况?
答案1
当 ZFS 重新启动时,它有多大可能保持一致状态(即使丢失了一些数据)并且池可用/可读?
ZFS 的运行方式类似于事务数据库管理系统与传统文件系统不同,在更新时旧数据不会被原地覆盖。相反,新数据会写入磁盘的其他位置,然后文件系统元数据结构会更新为指向新数据,只有这样旧数据的块才会被释放以供文件系统重用。这样,如果新数据更新没有 100% 提交到持久存储中,突然断电将使旧数据副本保留在原处。您不会替换一半的块或类似情况,从而导致数据损坏。
最重要的是,ZFS 使用复杂的校验方案这使得文件系统能够检测错误写入或损坏的数据。
如果您使用具有冗余存储的 ZFS,则同样的方案允许文件系统在修复文件系统时在两个或多个冗余数据副本之间进行选择。也就是说,如果您拥有给定块的两个副本,并且其中只有一个与存储的校验和匹配,则文件系统知道应该使用干净的副本修复坏副本。
这些修复可能会在运行时发生,当你尝试读取或修改数据时——此时文件系统可能会意识到所请求的块并不完全正确——或者在zfs scrub
操作。在包含很少访问的文件的 ZFS 池上定期安排清理是很常见的,因为否则文件系统在正常操作过程中不会发现硬件数据丢失。在不可靠的硬件上运行的 ZFS 池在每次清理后显示一定数量的固定块是很常见的。
清理与其他 Unix 类型的文件系统类似fsck
,只不过清理是在线进行的,当文件系统已安装且可用时;清理是在后台进行的,并且仅在池处于空闲状态时进行。此外,fsck
实现通常只检查元数据,而不检查数据,但 ZFS 会检查两者的校验和,因此可以检测两者中的错误。如果这些完整性机制决定需要替换其中一个块,它可以使用校验和来决定用哪个副本替换损坏的副本。
假设存储介质、硬件和软件仍然可靠/正常工作,那么还有哪些其他问题导致了池丢失?
据我所知,没有这种情况。您提到的三件事之一失败了,或者 ZFS 将挂载池并从中读取。
显然冗余度不足+磁盘故障(或其他主要硬件问题)就是一个例子
是的,尽管这可能发生在比你考虑的更微妙的情况下。
以一个简单的双向镜像为例。我想你正在考虑其中一个磁盘从计算机中物理移除,或者至少由于某种原因无法访问。但是,想象一下两个磁盘上的扇区 12345 都损坏了。那么 ZFS 中所有巧妙的校验和和冗余都无法帮助你:两个副本都已损坏,因此无法读取包含该扇区的整个块。
但这里有一个巧妙之处:因为 ZFS 既是一个文件系统,又是一个卷管理器——而不是像硬件 RAID + 那样的临时组合ext4或者左心室血管造影+ ext4 —zpool status
命令会告诉您哪个文件已不可恢复地损坏。如果您删除该文件,池会立即恢复到未损坏状态;问题已解决。将文件系统与 RAID 和 LVM 部分分开的临时措施无法做到这一点。
哪些情况必须出现才会使它不复存在,以及需要发生什么事情才会引发这些情况?
我知道的唯一情况是类似上述示例的情况,其中数据损坏已经破坏了足够多的关键文件系统元数据的冗余副本,以至于 ZFS 无法读取它。
因此,对于当今的超大磁盘(100 万亿位!),我建议您至少为 ZFS(或任何其他 RAID 或 LVM 系统)配置双冗余。在 ZFS 术语中,这意味着raidz2、三向镜子或更高级别。
话虽如此,ZFS 通常会存储所有文件系统元数据的额外副本,超出常规文件数据使用的正常冗余级别。例如,双向镜像将存储 2 个常规用户数据副本,但存储 4 个所有元数据副本。您可以调低此设置以提高性能,但不能完全关闭它。
ZFS 手册中有一章关于ZFS 故障模式你可能会觉得很有启发。
答案2
由于我的评论太长,这个答案似乎很有用。Warren Young 已经在他的答案中正确概述了所有基本考虑因素,所以我只关注“镜像还是不镜像 SLOG 设备?”部分。
情况如下:
我漫步到我的 ZFS 系统,在非常繁忙的传入数据会话中途,我毫无预警地绊倒并意外拔出 P3500 ZIL,系统立即冻结。由于电源和 MB 质量良好,其他 HDD/SSD 不受电气瞬变的影响。除 ZIL 外,其他所有磁盘/卷都是冗余的。我是否刚刚丢失了一些最近的数据、整个池,或者“这取决于”,如果这取决于什么?)
如果您仔细想想,ZIL 通常存储在所有池磁盘上,因此享有与池相同的冗余。如果您出于速度目的将其移到单独的设备上,则需要自己建立另一个镜像(如果您想要冗余)。但即使您没有它,您也只会丢失 ZIL 中的少量数据(仅在需要同步写入并且应用程序数据已损坏时才需要从备份中恢复),而不会使整个池不一致(在所有情况下都将从备份中恢复)。
现在,对于选择什么的问题:
当我将钱花在硬件规格上时,某个时候我必须选择设计的目标。
这取决于你的情况(一如既往):
- 如果您只有普通数据存储(经典文件服务器),那么将 ZIL 移动到 SLOG 设备不会带来太多好处(甚至什么好处都没有),因为 SMB 是异步的,可以处理突然断电。我相信对于 NFS 来说,这取决于您的选择/软件,但如今大多数人都在所有三个主要系统上使用 SMB。
- 如果您需要速度和完整性(主要用于数据库和 VM 存储),您将(应该)使用,
sync=always
并且您将需要用于 ZIL 的 SLOG 设备,否则它会非常非常慢。在这些情况下,您可以镜像 SLOG 设备,或者决定“突然发生 SSD/控制器硬件故障或移除和突然断电”事件足够罕见,无需运行它。然后您可以决定成本是否合理(在大多数情况下是合理的,因为其余硬件相当昂贵,但仍然比商业产品便宜得多)。 - 如果您想要安心,但预算有限,我推荐英特尔 SSD 730。它作为“游戏玩家”或“发烧友”产品出售,但如果您比较数据表,内部与较小的 3700 系列非常相似。它还具有超级电容器,正如网络上的多个来源所述。当然,英特尔官方不会承认这一点,因为那样的话就没有人会购买昂贵的产品了。
编辑:关于您的评论:
NFS/ESXi/sync 将是一个主要用例。由于成本和风险都落在我的肩上,我试图了解风险,而不是寻求推荐的方法 - 如果单独的 ZIL 因断电而发生故障(无论它是否打算冗余、丢失保护等),但没有其他任何影响,可能的丢失/损坏是否仅限于 ZIL 收到的尚未写入池的数据(最坏情况下是最后几秒钟的数据),并且可以恢复,或者是否有突然的 ZIL+电源故障(假设没有其他类型的故障同时发生)会导致池无法恢复?
所有观点仅在您的示例假设下有效,并且以下任何一项都不成立:(a)ZFS 中的错误,(b)所有池磁盘的完全硬件故障,(c)人为错误/恶意。
- 您的池数据将保持安全,并且静态数据的完整性将得到保护,这意味着您可以导入池,并且从 ZFS 的角度来看它不会受到损坏。这是 ZFS 断电的正常行为,也是其设计的一部分。
- 恢复供电后,通常会读取 ZIL 来重做丢失的事务(类似于 RDBMS)。现在可以进行以下操作:
- 您的 SLOG 设备未损坏,或者损坏的部分可以从 SLOG 镜像中恢复:一切照常运行(最终重新镀银后),因此您的最后 5 秒被写回池中。
- 您的 SLOG 设备已损坏:ZIL 无法正确回滚。我不知道是否尝试过部分回滚,但从您的角度来看,这无关紧要(因为您需要所有事务),因此我假设您最后 5 秒的数据已被丢弃。
从池的角度来看,即使是这种最坏的情况也相当不错 - 损失了 5 秒,但池是可以导入的(如果它的版本至少 19 岁)。但从应用程序的角度来看,这可能是一个严重错误——应用程序刚刚写入了 5 秒的同步数据,确认已成功写入,重启后数据丢失,但应用程序不知道这一点。确切的错误取决于应用程序。DBMS 可能变得不一致并需要修复,大型数据文件可能无法读取,系统文件可能导致难以找到的崩溃,加密存储分区可能完全无法恢复——所有这些都是因为其中的一部分丢失/错误。
另一点很少被提及:SSD 可能会意外损坏,因此镜像比 HDD 更重要,但如果您将两个相同的全新 SSD 放入系统,则故障可能会同时发生。
您可以阅读Solaris ZFS、同步写入和 ZIL 说明以及有关数据丢失情况的部分详细信息据我所知,丢失 ZFS ZIL SLOG 设备的影响。Oracle 文档有点短,但也提到在正常运行下,当 SLOG 发生故障时,ZIL 会自动从 SLOG 移动到池设备(当然,那里有 5 秒的漏洞)。
手册页还提供了有关在没有 ZIL 的情况下导入池的信息:
zpool import -a [-DfmN] [-F [-n]] [-c cachefile|-d dir] [-o mntopts] [-o
property=value]... [-R root]
-m Allows a pool to import when there is a missing log
device. Recent transactions can be lost because the log
device will be discarded.
答案3
我在 4 台服务器和我的笔记本电脑上使用 ZFS 已有 5 年多了。在写入密集型服务器上,我很少遇到电源故障(损坏的 UPS 固件报告错误数据),但我没有注意到任何*数据错误/池挂载问题(这并不意味着没有数据丢失,因为最新的事务尚未完成写入,如前所述/CoW)
* 除了一次我偏离 ZFS 手册的情况:我在 KVM Guest 中的单个磁盘(iSCIS SAN LUN 映射到主机上)上安装了 ZFS,在初始数据复制后,我忘记将缓存模式从 WriteBack 更改为 WriteThrough。池(5TB)可读,但报告了 20k+ 个错误。我不得不使用备份服务器中的数据重新创建池 - 感谢 zfs 快照和 zfs 发送/接收,我只丢失了(这意味着情况可能会更糟)2 分钟的数据。 使用 ECC 内存,禁用所有写缓冲(至少没有 BBU/FBU——这是另一个故事的主题),RTFM 和 ZFS 非常稳定。