btrfs scrub 到底是做什么的?根据手册页(完全不清楚),它会进行一些错误检查。什么样的错误检查?它有多可靠?它能恢复一些错误吗?它是如何工作的?它在每个 btrfs 磁盘上都有效吗?
答案1
我不知道它是否还能做其他事情,但我知道它至少btrfs scrub
会进行全盘数据清理。基本上,它会读取磁盘上的所有数据*,重新计算其校验和,并将重新计算的校验和与存储的校验和进行比较。当存储和重新计算的校验和不匹配时,系统就知道存在损坏。
一旦检测到损坏,行为取决于您的磁盘设置。例如,如果您使用 btrfs 的 RAID 1(镜像)功能,则btrfs scrub
可以通过从另一个磁盘复制未损坏的版本来修复损坏的数据。如果某些数据的所有副本都已损坏(例如,多磁盘损坏或首先没有冗余副本),那么btrfs scrub
除了警告您之外,没有什么可以做的。
这一点之所以重要,是因为硬盘在读写数据时,可靠性只有 99.999999999999%。因此,每几 TB 的数据 I/O,就可能出现错误。虽然在正常的磁盘访问过程中可以检测到错误(并修复,假设冗余副本仍然有效),但常规的全盘清理能够在错误积累到足以损坏同一数据的所有副本之前发现并修复错误。
* 我使用“数据”而不是“文件”来包含元数据。Btrfs 将文件和相应的元数据(包括校验和)存储在数据块中,所有这些都经过校验和检查btrfs scrub
。
也可以看看:
- Btrfs -> 校验和树和清理维基百科:有关 btrfs 数据清理的技术信息。
- 生日问题 -> 概率表在维基百科中:将“哈希空间”视为“数据块的数量”,将“哈希元素的数量”视为“损坏的数据块的数量”,这给出了在 RAID 1 设置中存在两个副本都损坏的数据块的概率。
答案2
扩展 Mark Haferkamp 的出色回答,btrfs scrub
阅读所有内容数据而不是所有文件是一个关键属性,实际上这也是它如此有用的原因。请记住,btrfs 具有内置 RAID 支持。假设您有一个跨越两个驱动器的 btrfs 文件系统,您已将其配置为使用 RAID1。在这种情况下,当您写入文件时,该写入将复制到两个磁盘。(对于更复杂的例子,情况会变得更加复杂,但对于这个简单的情况,总是会发生这种情况。)但是,当您从该文件读取时,读取将仅到达一个磁盘(因为除非第一个副本由于某种原因无法使用,否则两次读取文件是一种浪费)。
现在假设您的第二个 btrfs 驱动器正在降级并开始损坏文件系统中的数据。当您从此磁盘读取块时,btrfs 会注意到校验和不匹配,并将从已知良好的副本(第一个驱动器上的副本)中恢复带内块。它会将数据返回给调用的应用程序read()
(或其他程序),就像什么都没发生一样。
但是,如果 btrfs 决定不从第二个磁盘读取怎么办?请记住,有两个副本,因此它可以从第一个磁盘读取或者第二个磁盘。如果它从第一个磁盘读取,它不会注意到任何错误。它唯一会注意到任何错误的情况是当第一个磁盘也出现性能下降时。现在您真的陷入困境,因为恢复数据已经太晚了——第二个磁盘的副本已经损坏了一段时间,而第一个副本(您本来会用它来恢复第二个磁盘)现在也损坏了!
这就是btrfs scrub
进来的地方。它读取所有数据,并非所有文件。这包括元数据,也包括通常不在读取路径中的文件的辅助副本。当它读取这些辅助副本时,这为 btrfs 的带内纠错创造了机会,可以从冗余副本中恢复数据。