何时对 BTRFS 分区进行重新平衡

运行 Cumulus Linux 3.y.z 的客户(使用 BTRFS(b 树文件系统))可能会遇到磁盘空间管理问题。这是 BTRFS 的一个已知问题,因为它不执行定期垃圾回收或重新平衡。如果无人看管,这些错误可能会导致无法重新平衡磁盘上的分区。为避免此问题,NVIDIA 建议以抢占方式重新平衡 BTRFS 分区,但仅在绝对必要时才进行,以避免缩短磁盘的使用寿命。通过跟踪磁盘空间使用情况的状态,您可以确定何时执行重新平衡。

本文介绍了一种确定执行 BTRFS 重新平衡的适当时间的方法。

问题呈现

当 BTRFS 正在运行并且存在正确的磁盘 I/O 模式和文件大小时,问题就会出现。这会导致磁盘空间使用效率低下,并最终阻止新的写入磁盘。您可以判断此问题正在发生,因为出现了“设备上没有剩余空间”错误。

何时重新平衡

在确定何时应执行重新平衡时,请考虑以下几个因素

  • 应多久运行一次检查?
  • 分区是否具有大量已分配空间?
  • 重新平衡是否会释放任何空间?

检查间隔

此问题逐渐发生,在很长一段时间内,磁盘 I/O 正确。预期从“一切正常”到“没有剩余空间”(即使设备上没有太多数据)的时间段至少为一周。此时间段越小,您必须运行检查的频率就越高。虽然检查不会产生显着的磁盘 I/O,但它确实会消耗一些,以及 CPU 周期。因此,您应尽可能不频繁地运行检查。

已分配空间检查

如果 BTRFS 没有分配分区的很大一部分,则无需执行重新平衡。一个 15 GB 的分区,其中 BTRFS 仅分配了 4 GB,则有足够的未分配空间,不需要重新平衡。对此卷进行重新平衡几乎不会释放任何已分配空间。因此,第一个检查是确定 BTRFS 是否已分配分区的很大一部分,其中“很大一部分”是以下两者中较大者

  • 分区大小的 80%,或
  • 除了 2 GB 分区大小之外的所有空间。

根据此定义,如果 (14.66 x 0.80) 或 (14.66 - 2) 的最大值成立,则 14.66 GB 分区符合具有大量已分配磁盘空间的分区。计算结果为最大值 11.728 GB 或 12.66 GB。由于 12.66 GB 大于 11.728 GB,因此 12.66 GB 是确定磁盘大量分配的因素。

选择这些参数是因为 BTRFS 似乎分配的块最大为分区大小的 1/10,最大为 1 GB。希望至少有一个块未分配,以便在重新平衡操作期间使用。当分区的未分配部分超过 2 GB 或 20% 阈值时运行重新平衡可保证至少有一个块可用于重新平衡操作。

如果分区从没有分配很大一部分空间的情况变为少于一个块未分配,则重新平衡操作可能无法运行。在这种情况下,您可能必须缩短检查间隔。已分配空间量不足以确定是否应执行重新平衡操作。例如,如果分区确实已完全填充 97% 的数据,则已分配空间检查将显示已分配了分区的很大一部分。在这种情况下,重新平衡不会释放已用空间,因为磁盘实际上几乎已满。因此,您必须考虑更多标准来确定是否需要重新平衡。

数据存储效率检查

要确定重新平衡是否会释放空间,BTRFS 会比较为数据分配的空间量与数据使用的空间量。如果两者之间的差异大于块的最大大小,则重新平衡可能会释放一些空间。块的最大大小是 1 GB 或分区大小的 10% 中的最小值。

根据此定义,对于一个 14.66 GB 的分区,其中为数据分配了 13.94 GB 的空间,而该数据仅使用了 2.30 GB 的空间,则已分配但未使用的空间量为 13.94 GB - 2.30 GB,即 11.64 GB。最大块大小是 (14.66 GB * 0.10) 或 1 GB 中的较小者。由于 1 GB 小于 1.466 GB,因此最大块大小为 1 GB。要比较这两个值,11.64 GB 大于 1 GB,表明您必须执行重新平衡。

数据存储效率检查本身也不够充分;您必须将其与已分配空间检查结合使用。考虑一个 14.66 GB 的分区,其中为数据分配了 4 GB,而该数据仅使用了 1 GB。虽然重新平衡可能会释放一些空间,但您无需重新平衡,因为设备上还有足够的空间来存储其他数据。此时运行重新平衡将对磁盘造成额外的、不必要的磨损。

元数据和系统块中存储的 BTRFS 信息不在此检查中考虑。它们仅占分区用量的一小部分。

总而言之,如果已分配空间检查和数据存储效率检查均返回肯定结果,则 NVIDIA 建议进行重新平衡。如果只有一个检查返回 true,则您尚无需重新平衡。

执行检查:示例

BTRFS 文件系统使用情况命令输出包含执行上述检查所需的所有信息。以下是输出示例

$ sudo btrfs fi usage -b /
Overall:
     Device size:                    7474450432
     Device allocated:               2028994560
     Device unallocated:             5445455872
     Device missing:                          0
     Used:                            904900608
     Free (estimated):               6199468032   (min: 3476740096)
     Data ratio:                           1.00
     Metadata ratio:                       2.00
     Global reserve:                   16777216   (used: 0)

Data,single: Size:1568669696, Used:814657536
   /dev/sda4 1568669696

Metadata,DUP: Size:196608000, Used:45105152
   /dev/sda4 393216000

System,DUP: Size:33554432, Used:16384
   /dev/sda4  67108864

Unallocated:
   /dev/sda4 5445455872

检查使用红色显示的数字。

首先,执行已分配空间检查。已分配空间是否大于 a) 分区大小的 80% 或 b) 除 2 GB 分区之外的所有空间中的较大者?

  1. 计算条件 A:7474450432 * 0.80 = 5,979,560,345
  2. 计算条件 B:7474450432 - 2147483648 = 5,326,966,784
  3. 取条件 A 和 B 中较大者,并与磁盘分配进行比较:2,028,994,560 < 5,979,560,345

由于磁盘分配小于条件,因此检查为 False,无需在此分区上运行 BTRFS 重新平衡。

在此示例中,由于已分配空间检查通过,因此您无需执行数据存储效率检查。但是,如果它失败了,您将必须执行第二次测试以确保您不需要重新平衡。如果您假设第一次测试失败,并且对于同一分区,您将检查为数据信息分配的空间量减去用于数据信息的空间量是否大于块大小

  1. 计算已分配空间和已用空间之间的差值:1568669696 - 814657536 = 754,012,160
  2. 计算块大小:(7474450432 * 0.10) 或 1073741824 中的较小者 = 747,445,043
  3. 比较这两个值:754,012,160 > 747,445,043

由于差值大于块大小,因此检查为 True,您可以通过运行重新平衡来释放空间。如果两个检查都失败,则需要重新平衡。如果只有此检查失败,则无需重新平衡。

结论

尽管 BTRFS 文件系统没有内置的垃圾回收机制,但您可以通过定期检查 BTRFS 统计信息来创建此功能的合理模拟。当 BTRFS 分配的空间量变得很大并且重新平衡很可能释放一些空间(两个检查都为 true)时,您应运行重新平衡。这可以防止系统陷入 BTRFS 分配了整个分区,但只有一小部分磁盘正在使用的情况。

参考资料