了解 ZFS 的错误报告(在 Linux 上)

了解 ZFS 的错误报告(在 Linux 上)

我已在 ZFS 上成功设置 Debian Stretch,包括根文件系统。事情按预期进行,我以为我已经理解了基本概念 - 直到我重新阅读 Sun 的 ZFS 文档。

我的场景是:

  • 我想防止(更准确地说:检测)无声位腐烂

  • 目前,我已经设置了一个带有一个 vdev 的根池,它是两个相同磁盘的镜像

  • 当然,我确实打开了(即没有关闭)校验和

现在我遇到了这个文件。在页面末尾,他们显示了zpool status示例配置的命令输出,

[...]
NAME        STATE     READ WRITE CKSUM
tank        DEGRADED     0     0     0
  mirror-0  DEGRADED     0     0     0
    c1t0d0  ONLINE       0     0     0
    c1t1d0  OFFLINE      0     0     0  48K resilvered
[...]

接下来是声明:

READ 和 WRITE 列提供设备上发生的 I/O 错误的计数,而 CKSUM 列提供设备上发生的不可纠正的校验和错误的计数。

首先,“设备”在这种情况下意味着什么?他们谈论的是物理设备、vdev 还是其他东西?我的假设是他们正在谈论层次结构中的每个“设备”。那么,vdev 错误计数器可能是其物理设备的错误计数器的总和,而池错误计数器可能是其 vdev 的错误计数器的总和。它是否正确?

其次,不可纠正的校验和错误是什么意思?我认为这个术语通常在谈论物理磁盘时使用,要么涉及从盘片到磁盘电子设备的数据传输,要么涉及磁盘上物理扇区的校验和,要么涉及从磁盘端口(SATA、SAS、 ...)到主板(或控制器)。

但什么我真正感兴趣的是 ZFS 级别(而不是硬件级别)是否存在校验和错误。我目前确信 CKSUM 正在显示后者(否则,它就没有多大意义),但我想确定。

第三,假设他们所说的校验和错误确实是ZFS级别(而不是硬件级别)的校验和错误,为什么他们只显示无法纠正的错误?这没有任何意义。我们希望看到每一个校验和错误,无论是否可纠正,不是吗?毕竟,校验和错误意味着磁盘上存在某种未被硬件检测到的数据损坏,因此我们可能希望在出现这种情况时立即更改该磁盘任何错误(即使镜像磁盘仍然可以充当“备份”)。所以我可能还不明白“不可纠正的错误”到底是什么意思。

然后我遇到了这个文件这更难理解。在页面末尾附近,它指出

[...]ZFS 维护与池关联的所有数据错误的持久日志。 [...]

然后指出

数据损坏错误总是致命的。它们的存在表明至少有一个应用程序由于池中的数据损坏而遇到了 I/O 错误。冗余池中的设备错误不会导致数据损坏,并且不会记录为此日志的一部分。 [...]

我对第三句话非常担心。根据该段落,可能存在两种错误:数据损坏错误和设备错误。两个磁盘的镜像配置无疑是多余的,所以(根据那段)这不是数据损坏错误如果 ZFS 遇到校验和错误其中一张磁盘(在 ZFS 校验和级别,而不是硬件级别)。这意味着(再次根据该段落)该错误不会被记录为持久错误日志的一部分。

这没有任何意义,所以我一定是弄错了。对我来说,切换到 ZFS 的主要原因是它能够自行检测静默位衰减,即检测并报告设备上的错误,即使这些错误不会导致硬件/驱动程序级别的 I/O 故障。但不将此类错误包含在持久日志中将意味着在重新启动时丢失它们,这将是致命的(恕我直言)。

所以最终Sun在这里选择了令人担忧的措辞,或者我误解了一些概念(不是以英语为母语的人)。

答案1

有关一般概述,请参阅解决 ZFS 问题,最有趣的部分:

配置输出的第二部分显示错误统计信息。这些错误分为三类:

  • READ – 发出读请求时发生的 I/O 错误
  • WRITE – 发出写请求时发生的 I/O 错误
  • CKSUM – 校验和错误,意味着设备由于读取请求而返回损坏的数据

这些错误可用于确定损坏是否是永久性的。少量 I/O 错误可能表示暂时中断,而大量错误可能表示设备存在永久性问题。这些错误不一定对应于应用程序解释的数据损坏。如果设备处于冗余配置中,设备可能会显示无法纠正的错误,而镜像或 RAID-Z 设备级别不会出现错误。在这种情况下,ZFS 成功检索了良好的数据并尝试从现有副本修复损坏的数据。


现在,针对您的问题:

首先,“设备”在这种情况下意味着什么?他们谈论的是物理设备、vdev 还是其他东西?我的假设是他们正在谈论层次结构中的每个“设备”。那么,vdev 错误计数可能是其物理设备的错误计数之和,而池错误计数可能是其 vdev 的错误计数之和。它是否正确?

每个设备都经过独立检查,并总结其自身的所有错误。如果两个镜像上都存在此类错误,或者 vdev 本身不是冗余的,则它会向上传播。所以,换句话来说,就是影响vdev本身的错误量(这也符合每行单独显示的逻辑)。

但我真正感兴趣的是 ZFS 级别(而不是硬件级别)是否存在校验和错误。我目前确信 CKSUM 正在显示后者(否则,它就没有多大意义),但我想确定。

是的,这是硬件方面(非永久性的东西,比如有故障的电缆、突然移除的磁盘、断电等)。我认为这也是一个观点:“软件方面”的故障意味着 ZFS 本身存在错误,因此未检查的不良行为(假设所有正常的用户交互都被认为是正确的)并且 ZFS 本身无法识别。幸运的是,如今它们已经很少见了。不幸的是,它们在大多数时候也相当严重。

第三,假设他们谈论的校验和错误确实是 ZFS 级别(而不是硬件级别)的校验和错误,那么它们到底为什么只显示不可纠正错误的计数?这没有任何意义。我们希望看到每个校验和错误,无论是否可纠正,不是吗?毕竟,校验和错误意味着磁盘上存在某种尚未被硬件检测到的数据损坏,因此我们可能希望在出现任何错误之前立即更改该磁盘(即使镜像磁盘可以)仍充当“备份”)。所以我可能还不明白“不可纠正”到底是什么意思。

有故障的磁盘已通过读/写错误指示(例如,来自磁盘的 URE)。校验和错误是您所描述的内容:读取了一个块,树中其上方块的校验和认为其返回值不正确,因此它没有返回,而是被丢弃并标记为错误。 “不可纠正”或多或少是定义,因为如果你得到垃圾并且知道它是垃圾,你无法纠正它,但你可以忽略并且不使用它(或重试)。不过,措辞可能会造成不必要的混乱。

根据该段落,可能存在两种错误:数据损坏错误和设备错误。两个磁盘的镜像配置无疑是冗余的,因此(根据该段落)如果 ZFS 在其中一个磁盘上遇到校验和错误(在 ZFS 校验和级别,而不是硬件级别),则不是数据损坏错误。这意味着(再次根据该段落)该错误不会被记录为持久错误日志的一部分。

数据损坏本段中的内容意味着您的某些文件已部分或完全损坏、无法读取,您需要尽快获取最后的备份并替换它们。当 ZFS 的所有预防措施都已经失败并且它无法再为您提供帮助时(但至少它现在会通知您这一点,而不是在下一次服务器启动检查磁盘运行时)。

对我来说,切换到 ZFS 的主要原因是它能够自行检测静默位衰减,即检测并报告设备上的错误,即使这些错误不会导致硬件/驱动程序级别的 I/O 故障。但不将此类错误包含在持久日志中将意味着在重新启动时丢失它们,这将是致命的(恕我直言)。

ZFS 系统背后的想法是,不需要将它们关闭即可发现此类错误,因为可以在线检查文件系统。请记住,10 年前,这是当时大多数小型系统所不具备的功能。因此,我们的想法是(当然是在冗余配置上)您可以检查硬件的读写错误,并通过使用众所周知的副本来纠正它们。此外,您可以每月擦洗以读取所有数据(因为无法知道未读取的数据是否良好)并更正您发现的任何错误。

它就像一个大型旧书档案馆/图书馆:你有有价值的书,也有不太有价值的书,有些可能会随着时间的推移而腐烂,所以你需要一个人每周或每月检查所有书籍的所有页面是否发霉,错误等,如果他发现任何东西他会告诉你。如果你有两个相同的图书馆,他可以去另一栋大楼,在同一页上查看同一本书,然后用副本替换第一个图书馆中被损坏的页面。如果他从不查书,20 年后他可能会遭遇可怕的意外。

答案2

在对这个主题进行了更多思考并多次阅读了 user121391 的回答之后,我想回答我自己的问题,从而尝试进一步澄清 user121391 的陈述。如果有什么不对的地方,请指正。

第一个问题:“设备”是什么意思?

这已经被用户121391澄清了;我无法添加任何有意义的内容。

第二和第三个问题:什么是不可纠正的错误/为什么只是无法纠正的错误计数器中显示的错误?

Sun/Oracle 选择的措辞非常不明确且具有误导性。通常,当磁盘(或层次结构中的任何硬件组件)遇到数据完整性错误时,可能会发生两种情况:

  • 错误可以被纠正(通过 ECC 等机制),并且相应的组件在纠正后传递数据(从而可能增加一些错误计数器,管理员可以通过适当的工具读出这些错误计数器)。

  • 错误可以不是予以纠正。在这种情况下,通常会发生 I/O 错误,以通知硬件/驱动程序/应用程序出现问题。

现在,在极少数情况下,I/O 错误会发生不是即使存在也会发生曾是尚未纠正的数据完整性错误。这可能是由于软件有缺陷、硬件故障等造成的。这就是我个人所说的“无声位腐烂”的意思,也正是我切换到 ZFS 的原因:此类错误是由 ZFS 自己的“端到端”校验和检测到的。

所以,一个ZFS 校验和错误正是数据(完整性)错误在硬件级别,不会导致 I/O 错误(本应如此),因此除了 ZFS 自己的校验和之外,任何机制都无法检测到,反之亦然。从这个意义上说,命令的 CKSUM 列中的错误数量zpool status -v就是 ZFS 校验和错误的数量以及未检测到的硬件错误的数量,因为这两个数字完全相同。

换句话说,如果设备自行更正了完整性错误,或者(如果错误无法更正)设置了 I/O 错误,ZFS 将不是增加了其 CKSUM 错误计数器。

我一直对 Sun 文档的这一部分感到非常担心,因为术语“不可纠正的错误”从未得到解释,因此非常具有误导性。如果他们写的是“无法纠正的硬件错误,不会导致 I/O 错误正如他们通常应该的那样“,我对文档的这一部分不会有任何问题。

因此,总而言之,再次强调:在这种情况下,“不可纠正”意味着“在硬件级别不可纠正且未检测到”(未检测到,尽管存在数据(完整性)错误,但没有发生 I/O 错误),而不是“不可纠正”在ZFS级别”(实际上,据我所知,ZFS不会尝试通过某种纠错校验和机制来纠正单个磁盘上的坏数据,但它会借助校验和来识别错误数据,然后在以下情况下尝试纠正数据:上有正确的数据副本其他磁盘(镜像)或者数据是否可以从上的数据重建其他磁盘 (RAIDZ))。

最后一个问题(关于持久化日志)

再一次,Sun 的文档在这里是错误的(或者至少具有误导性,以至于没有人会通过阅读它来理解到底发生了什么):

显然至少有持久日志。

文档中讨论的其中之一是日志,其中详细包含由于应用程序 I/O 错误而无法读取哪个文件,即即使通过冗余机制也无法纠正的 I/O 错误或 ZFS 校验和错误ZFS 的。换句话说,如果 I/O 错误发生在磁盘级别,但 ZFS 可以通过其冗余机制(RAIDZ、镜像)修复该错误,则错误为不是记录在该持久日志中。

恕我直言,这是有道理的。借助该日志,管理员一目了然地了解应从备份中恢复哪些文件。

但是文档中没有提及第二个持久“日志”:错误计数器的“日志”。当然,无论是在清理期间还是在正常操作期间检测到错误,错误计数器都会在重新启动之间保留。否则,ZFS 将没有任何意义:

想象一下,您有一个脚本,zpool status -v每天晚上 11 点运行一次,并将输出邮寄给您,您每天早上都会检查这些电子邮件,看看一切是否正常。有一天,正午时分,ZFS 检测到其中一个磁盘上存在错误,增加相应设备的 I/O 或 CKSUM 错误计数器,纠正错误(例如,因为镜像磁盘具有正确的数据)并传递数据。在这种情况下,没有应用输入/输出错误;因此,错误将不是写入文档中提到的持久错误日志。

那时,I/O 或 CKSUM 错误计数器是唯一的提示相应的磁盘有问题。然后,两个小时后,由于某种原因,您必须重新启动服务器。时间压力很大,生产必须继续,当然zpool status -v在这种情况下你不会在重新启动之前手动运行(你可能无论如何都无法登录)。现在,如果 ZFS 没有将错误计数器写入单独的“日志”,您将丢失其中一个磁盘出现错误的信息。检查 ZFS 状态的脚本将在晚上 11 点运行,第二天早上,在研究相应的电子邮件时,您会很高兴看到没有问题......

因此,错误计数器永久存储在某个地方(我们可以讨论是否应该将其称为“日志”,但关键点是它们被永久存储,以便zpool status -v在重新启动后显示与立即显示的结果相同的结果)重新启动之前)。实际上,据我所知,zpool clear这是重置错误计数器的唯一方法。

我认为 Sun / Oracle 在编写如此不清楚的文档时并没有给自己带来好处。我是一位经验丰富的用户(实际上是开发人员),我习惯于阅读糟糕的文档。但Sun的文档确实是灾难性的。他们期望什么?我真的应该欺骗我的一个磁盘产生 I/O 错误,然后重新启动我的服务器以查看错误计数器是否被保留吗?或者我应该阅读源代码来回答这样基本而重要的问题吗?

如果我必须做出支持或反对 ZFS / Solaris 的决定,我会阅读文档,然后做出决定。在这种情况下,我显然会决定反对,因为从文档中我得到的印象是重新启动时不会保留错误计数器,这当然是完全不可接受的。

幸运的是,在阅读了其他一些有关 ZFS 的文章后,我尝试了 ZFS,并且阅读 Sun 的文档。文档有多糟糕,产品就有多好(恕我直言)。

相关内容