如何确保 BTRFS 中的只读快照未损坏?

如何确保 BTRFS 中的只读快照未损坏?

我们如何确保只读快照不会由于磁盘故障而损坏?

唯一的方法是逐个计算校验和并将其存储以供进一步检查,还是 BTRFS 自行处理?

基本原理

我会定期备份快照,以防可能发生的磁盘故障。几天前,我无法制作btrfs send | btrfs receive特定快照。当我删除它时,其余操作正常进行。此外,btrfs scrub据说有几个无法纠正的错误。这让我想到,在将快照备份到外部磁盘之前,主磁盘上的快照可能已损坏,如果我没有意识到这一点,我最终会在外部磁盘上得到已损坏的备份。

这正是我想要防止发生的事情。我想确保如果我(可以)备份快照,那么它就不会被损坏。

答案1

根据您所说的‘由于磁盘故障而损坏’的含义,可能有两种答案。

如果你指的是简单的静态数据损坏

BTRFS 自行处理此问题,对用户透明。它会在内部对所有内容(包括快照中的数据)进行校验,然后在读取每个块时验证校验和。不过,有几个例外:

  • 如果卷使用nodatasumnodatacow选项挂载,则不会对数据块进行校验。在大多数情况下,您不应该使用这些选项进行挂载,因此这应该不是问题。
  • 任何NOCOW设置了该属性的文件(C在命令的输出中lsattr)也不会被检查。您不太可能拥有任何设置了此属性的真正重要的文件(systemd 日志文件已设置该属性,但除非您手动设置,否则仅此而已)。

如果你指的是由于丢失太多设备而导致卷上的数据遭到严重破坏

除非在某处有另一份数据副本,否则您无法防止这种情况发生。基本上,如果您丢失的设备数量超过卷的存储配置文件可以容忍的数量,您的数据就会丢失,并且除了从备份中恢复之外,没有其他方法可以帮您恢复数据。


关于你的具体情况

您所说的发送/接收问题可能是 Scrub 报告的那些无法纠正的错误的副作用。当 BTRFS 无法透明地修复错误时(通常是因为块是使用无法执行恢复的配置文件存储的,例如 single 或 raid0),它会返回 I/O 错误,这将导致发送操作失败。因此,如果您使用发送/接收,您最终不会得到已经损坏的备份(实际上,使用大多数其他工具也不会,任何好的备份软件如果无法读取文件都会抛出错误)。

在这种情况下,似乎无法纠正的错误完全存在于快照独有的数据或未快照的数据中。您可以相当容易地(尽管不是很快)找出哪些文件有问题,方法是将源卷单独挂载到某处并从挂载位置运行以下命令:

find . -exec cat '{}' \; > /dev/null

这将尝试读取卷上的每个文件,您将在控制台上看到任何读取错误,并在错误消息中显示文件的名称。这可能会非常慢,因此如果您的卷很大,您可能需要将其并行化。

找到并处理这些文件后,就不会再出现问题了。如果修复这些问题后不久又出现,则应检查硬件,因为某物正在悄悄破坏数据。

相关内容