答案1
TL;DR 元数据(如果 btrfs 没有遭受一般的低空间情况)将自动地增加。如果不存在未分配的可用空间,则自动增加会受到阻碍。然而,如果btrfs
分配给数据部分的空间多于其需要的空间,则可以重新分配它。这balance
在 btrfs 中称为-ing。
假设 的支持块设备上有足够的未分配内存btrfs
,则文件系统的元数据部分会分配(正如 OP 所假设的那样)自动内存以增加/扩展元数据。
因此,答案是:是的(前提是不存在内存/可用空间不足的情况btrfs
),那么元数据将自动增加,如下所示:
(1) 我们看一下 btrfs 的一些初始分配设置(在设备上40GB
)
$> btrfs filesystem df /
Data, single: total=25.00GiB, used=24.49GiB
System, single: total=32.00MiB, used=16.00KiB
Metadata, single: total=1.55GiB, used=1.33GiB
GlobalReserve, single: total=85.41MiB, used=0.00B
(2) 可以看出,文件系统中用于存储元数据的分配空间为1.55GiB,其中1.33GiB,因此几乎全部被使用(这可能是OP案例中发生的情况)
(3) 我们现在增加要添加的元数据。为此,我们使用--reflink=always
命令选项复制 /home 文件夹cp
。
$> cp -r --reflink=always /home /home.copy
(4) 因为(我们假设 /home 中有很多文件),文件系统中添加了很多新数据,因为我们使用的--reflink
实际数据几乎没有使用任何额外空间,所以它使用写入时复制机制。简而言之,大部分元数据都被添加到文件系统中。我们可以再看一下
$> btrfs filesystem df /
Data, single: total=25.00GiB, used=24.65GiB
System, single: total=32.00MiB, used=16.00KiB
Metadata, single: total=2.78GiB, used=2.45GiB
GlobalReserve, single: total=85.41MiB, used=0.00B
可以看出,这里为元数据分配的空间btrfs
有自动地增加扩大。
由于这是自动进行的,因此通常不会被用户检测到。然而,在某些情况下,大多数情况下整个文件系统已经被填满了。在这些情况下,btrfs
可能会开始“卡顿”并且无法自动增加元数据的分配空间。例如,原因可能是所有空间已分配给各个部分(数据、系统、元数据、GlobalReserve)。令人困惑的是,可能仍然存在明显的空间。一个例子是这样的输出:
$> btrfs filesystem df /
Data, single: total=38.12GiB, used=25.01GiB
System, single: total=32.00MiB, used=16.00KiB
Metadata, single: total=1.55GiB, used=1.45GiB
GlobalReserve, single: total=85.41MiB, used=0.00B
可以看出,系统一切正常40GiB
,但分配有些关闭balance
,因为虽然仍有空间用于新文件的数据,但元数据(如 OP 情况)较低。btrfs
不再可能为支持文件系统的设备自动分配内存(只需将分配总数相加,38.12G+1.55G+..~= 40GiB)。
然而,由于分配给文件系统部分的剩余空间过多data
,因此现在它对于平衡 btrfs 很有用,甚至是必要的。平衡意味着重新分配已经分配的空间。
在 OP 的情况下,可以假设由于某种原因,分配的不同部分之间btrfs
发生了不平衡。
不幸的是,原则上应该搜索空块(分配给数据)并将它们交给更好的用户(这将是几乎耗尽的元数据空间)的简单命令sudo btrfs balance -dusage=0
可能会失败,因为找不到完全空的数据块。
因此,开发人员btrfs
建议逐步提高“何时应重新排列数据块以回收空间”的使用限制。
因此,如果结果为
$> sudo btrfs balance -dusage=0
Done, had to relocate 0 out of 170 chunks
显示没有搬迁,应该做一些
$> sudo btrfs balance -dusage=5
Done, had to relocate 0 out of 170 chunks <--(again fail)
$> sudo btrfs balance -dusage=10
Done, had to relocate 0 out of 170 chunks <--(again fail)
$> sudo btrfs balance -dusage=15
Done, had to relocate 2 out of 170 chunks <--(success)
另一个答案暗示了btrfs
节点大小的影响,这在一定程度上影响了元数据增加的速度。节点大小(如另一个答案中提到的)仅在mkfs.btrfs
文件系统创建时设置一次。理论上,如果可以将节点大小更改为较低的值(如果可能的话),则可以减小元数据的大小(但事实并非如此!)。
然而,节点大小将无法以任何方式帮助扩展或增加分配的元数据空间。相反,它一开始可能只会有助于节省空间。但是,较小的节点大小并不能保证减少元数据大小。事实上,某些情况可能表明较大的节点大小会减少 btrfs 的树遍历长度,因为节点可以包含更多“链接”。
答案2
根据btrfs wiki 上的常见问题解答,这是不可能的,也不太可能实现。
我可以在不重新创建文件系统的情况下更改元数据块大小吗?
不可以,一旦创建文件系统,传递给 mkfs.btrfs -n SIZE 的值就无法更改。需要备份/恢复。请注意,这可能永远不会实现,因为它需要对核心功能进行重大更新。
您可以将现有的 btrfs 文件系统迁移到具有更大-n SIZE
.您甚至可以使用 btrfs RAID 和平衡将其添加到现有文件系统,然后删除旧文件系统。
也可以看看关于几乎已满的驱动器的部分。
答案3
昨天df -h
显示磁盘已满,但还有4G可用空间
Filesystem Size Used Available Use% Mounted on
/dev/sdb3 29.3G 25.9G 0 100% /mnt/sdb3
所以我尝试btrfs fi df /mnt/sdb3
查看元数据已满,因此我尝试扩展元数据并且它再次工作
在其他磁盘上制作5G文件并losetup
作为驱动器
dd if=/dev/zero of=/mnt/sda1/tmpBtrfs.img bs=1G count=5
losetup -v -f /mnt/sda1/tmpBtrfs.img
添加到磁盘,然后df -h
看到9G可用
btrfs device add /dev/loop1 /mnt/sdb3
平衡以释放空间
btrfs bal start /mnt/sdb3
并删除刚刚添加的5g盘
btrfs device delete /dev/loop1 /mnt/sdb3
losetup -d /mnt/sda1/tmpBtrfs.img
rm /mnt/sda1/tmpBtrfs.img
然后,元数据将自动扩展(大约是使用的两倍)