Btrfs
来自 Btrfs 文档
- Btrfs 是 Linux 的现代写入时复制 (COW) 文件系统,旨在实现高级功能,同时专注于容错、修复和易于管理。
准备工作
对于用户空间实用程序,安装 btrfs-progs 软件包,这是基本操作所必需的。
如果您需要从 Btrfs 文件系统启动(即,您的内核和 initramfs 位于 Btrfs 分区上),请检查您的引导加载程序是否支持 Btrfs。
文件系统创建
以下说明如何创建新的 Btrfs 文件系统。要将 Ext3/4 分区转换为 Btrfs,请参阅 #Ext3/4 到 Btrfs 转换。要使用无分区设置,请参阅 #无分区 Btrfs 磁盘。
有关更多信息,请参阅 mkfs.btrfs(8)。
单设备文件系统
要在分区 /dev/partition
上创建 Btrfs 文件系统
# mkfs.btrfs -L mylabel /dev/partition
Btrfs 元数据的默认节点大小为 16 KiB,而数据的默认扇区大小等于页面大小并自动检测。要为元数据使用更大的节点大小(必须是扇区大小的倍数,最大允许 64 KiB),请通过 -n
开关指定 nodesize
的值,如本示例所示,使用 32 KiB 块
# mkfs.btrfs -L mylabel -n 32k /dev/partition
多设备文件系统
- Btrfs 的 RAID 5 和 RAID 6 模式存在致命缺陷,不应用于“除测试以外的任何用途(使用可丢弃数据)。” 已知问题和部分解决方法列表。有关状态更新,请参阅 btrfs(5) § RAID56 STATUS AND RECOMMENDED PRACTICES。
- 默认情况下,systemd 禁用
/var/log/journal
的 CoW,这可能会导致 RAID 1 上的数据损坏(请参阅 #禁用 CoW)。为防止这种情况,请创建一个空文件/etc/tmpfiles.d/journal-nocow.conf
以覆盖/usr/lib/tmpfiles.d/journal-nocow.conf
(请参阅 tmpfiles.d(5) § CONFIGURATION DIRECTORIES AND PRECEDENCE)。
可以使用多个设备创建 RAID。支持的 RAID 级别包括 RAID 0、RAID 1、RAID 10、RAID 5 和 RAID 6。从内核 5.5 开始,RAID1c3 和 RAID1c4 用于 RAID 1 级别的 3 份和 4 份副本。可以使用 -d
和 -m
选项分别配置数据和元数据的 RAID 级别。默认情况下,数据有一份副本 (single
),元数据是镜像的 (raid1
)。这类似于创建 JBOD 配置,其中磁盘被视为一个文件系统,但文件不会重复。有关如何创建 Btrfs RAID 卷的更多信息,请参阅 Using Btrfs with Multiple Devices。
# mkfs.btrfs -d single -m raid1 /dev/part1 /dev/part2 ...
您必须在 /etc/mkinitcpio.conf
中包含 udev
钩子、systemd
钩子或 btrfs
钩子,才能在池中使用多个 Btrfs 设备。有关更多信息,请参阅 Mkinitcpio#常用钩子 文章。
文件系统创建后,建议运行以下命令扫描多设备 Btrfs 文件系统并注册它们,从而允许通过仅指定一个成员来挂载多设备文件系统
# btrfs device scan
- 稍后可以向多设备文件系统添加设备。有关更多信息,请参阅 Btrfs wiki 文章。
- 设备的大小可以不同。但是,如果 RAID 配置中的一个驱动器比其他驱动器大,则不会使用此额外空间。
- 某些引导加载程序(如 Syslinux)不支持多设备文件系统。
- Btrfs 不会自动从最快的设备读取数据,因此混合使用不同类型的磁盘会导致性能不一致。有关详细信息,请参阅 [1]。
有关特定于多设备 Btrfs 文件系统的维护建议,请参阅 #RAID。
配置文件
Btrfs 使用配置文件的概念来配置镜像、奇偶校验和条带化。在标准 RAID 术语中,这称为RAID 级别。同一 Btrfs 文件系统的元数据(mkfs.btrfs(8) 的 -m
选项)和数据(mkfs.btrfs(8) 的 -d
选项)的配置文件可能不同。
一些值得注意的配置文件
- single
- 无镜像、无条带化、无奇偶校验,允许将多个设备映射到单个文件系统,在 mdadm 术语中称为
LINEAR
。 - raid0
- 无镜像、条带化、无奇偶校验,允许设备之间的并行访问,但不限于像传统 mdadm RAID 那样的同等大小的设备。
- raid1
- 镜像、无条带化、无奇偶校验,允许从一个驱动器故障中恢复。
配置文件系统
写入时复制 (CoW)
默认情况下,Btrfs 始终对所有文件使用 写入时复制。写入不会覆盖原始位置的数据;相反,块的修改副本会被写入新位置,并且元数据会更新以指向新位置。有关实现细节以及优缺点,请参阅 Btrfs Sysadmin Guide 部分。
禁用 CoW
nodatacow
文件。当与 RAID 1 结合使用时,电源中断或其他损坏源可能会导致数据不同步。要在已挂载的子卷中禁用新创建文件的写入时复制,请使用 nodatacow
挂载选项。这只会影响新创建的文件。写入时复制仍然会发生在现有文件上。nodatacow
选项还会禁用压缩。有关详细信息,请参阅 btrfs(5)。
nodatacow
,而将另一些子卷挂载为 datacow
。第一个挂载的子卷的挂载选项适用于任何其他子卷。”要禁用单个文件/目录的写入时复制,请执行
$ chattr +C /dir/file
$ mv /path/to/dir /path/to/dir_old $ mkdir /path/to/dir $ chattr +C /path/to/dir $ cp -a --reflink=never /path/to/dir_old/. /path/to/dir $ rm -rf /path/to/dir_old确保在此过程中未使用数据。另请注意,如下所述,不带
--reflink=never
的 mv
或 cp
将不起作用。对快照的影响
如果文件禁用了写入时复制 (NOCOW) 并且已创建快照,则快照后对文件块的第一次写入将是 COW 操作,因为快照会锁定旧的文件块。但是,该文件将保留 NOCOW 属性,并且对同一文件块的任何后续写入都将是就地写入,直到下一个快照。
频繁快照可能会降低 NOCOW 的有效性,因为第一次写入仍然需要 COW。为了完全避免此类文件的写入时复制,请将它们放在单独的子卷中,并且不要对该子卷进行快照。
压缩
Btrfs 支持透明和自动压缩。这可以减小文件大小,并通过减少写入放大来显着延长基于闪存的介质的寿命。请参阅 Fedora:Changes/BtrfsByDefault#Compression、[2] 和 [3]。在某些情况下(例如,单线程和大量文件 I/O),它还可以提高性能,而在其他情况下(例如,多线程和/或 CPU 密集型任务以及大量文件 I/O),显然会损害性能。通常,使用最快的压缩算法 zstd 和 lzo 可以获得更好的性能,并且一些 基准测试 提供了详细的比较。
LZO 具有固定的压缩级别,而 zlib 和 zstd 具有从 1(低压缩)到 9 (zlib) 或 15 (zstd) 的级别范围;请参阅 btrfs(5) § COMPRESSION。更改级别会以不同的方式影响 CPU 和 I/O 吞吐量,因此应在更改前后进行检查/基准测试。
compress=alg[:level]
挂载选项允许自动考虑每个文件是否进行压缩,其中 alg
可以是 zlib
、lzo
、zstd
或 no
(不压缩)。使用此选项,Btrfs 将检查压缩数据的第一部分是否会缩小它。如果会缩小,则对该文件的整个写入将被压缩。如果不会缩小,则不会压缩任何内容。使用此选项,如果写入的第一部分没有缩小,则即使数据的其余部分会大幅缩小,也不会对写入应用压缩。[4] 这样做是为了防止磁盘等待开始写入,直到要写入的所有数据都完全提供给 Btrfs 并压缩。
可以改用 compress-force=alg[:level]
挂载选项,这使得 Btrfs 跳过检查压缩是否会缩小第一部分,并为每个文件启用自动压缩尝试。在最坏的情况下,这可能会导致(稍微)更多的 CPU 使用率,但没有任何目的。但是,对多个混合使用系统的经验测试表明,使用 compress-force=zstd
比仅使用 compress=zstd
(也具有 10% 的磁盘压缩率)可以显着提高约 10% 的磁盘压缩率。但是,请记住,强制压缩违反了 官方 Btrfs 指南。
只有在添加挂载选项后创建或修改的文件才会被压缩。
要将压缩应用于现有文件,请使用 btrfs filesystem defragment -calg
命令,其中 alg
可以是 zlib
、lzo
或 zstd
。例如,为了使用 zstd 重新压缩整个文件系统,请运行以下命令
# btrfs filesystem defragment -r -v -czstd /
cp
或 bcp 创建的副本)的文件进行碎片整理,再加上使用带有压缩算法的 -c
开关,可能会导致两个不相关的文件,从而有效地增加磁盘使用率。要在将 Arch 安装到空的 Btrfs 分区时启用压缩,请在挂载文件系统时使用 compress
选项:mount -o compress=zstd /dev/sdxY /mnt/
。在配置期间,将 compress=zstd
添加到 fstab 中根文件系统的挂载选项。
compress
挂载选项的情况下为每个文件启用压缩;为此,请对文件应用 chattr +c
或 btrfs property set file compression alg
。第一个命令使用从 ext2 文件系统继承的文件属性的旧接口,并且不够灵活,因此默认情况下设置 zlib
压缩。另一个命令使用给定的算法在文件上设置属性。(注意:尚未实现以这种方式设置级别。)当应用于目录时,它将导致新文件在创建时自动压缩。- 如果您使用此选项,则使用旧内核或没有
zstd
支持的 btrfs-progs 的系统可能无法读取或修复您的文件系统。 - GRUB 在 2.04 中引入了 zstd 支持。通过使用适用于您的 BIOS/UEFI 设置的适当选项运行
grub-install
,确保您实际上已升级自那时起安装在 MBR/ESP 中的引导加载程序,因为这不是自动完成的。请参阅 FS#63235。
查看压缩类型和比率
compsize 接受文件列表(或整个 Btrfs 文件系统),并测量使用的压缩类型和有效的压缩率。未压缩的大小可能与 du(1) 等其他程序给出的数字不匹配,因为每个区段都只计数一次,即使它被多次重新链接,并且即使它的一部分不再在任何地方使用但尚未进行垃圾回收。-x
选项使其保持在单个文件系统上,这在 compsize -x /
等情况下很有用,以避免它尝试查找非 Btrfs 子目录并导致整个运行失败。
子卷
“Btrfs 子卷不是块设备(也不能被视为块设备),相反,Btrfs 子卷可以被认为是 POSIX 文件命名空间。可以通过文件系统的顶层子卷访问此命名空间,也可以将其自身挂载。” [5]
每个 Btrfs 文件系统都有一个 ID 为 5 的顶层子卷。此子卷无法删除或替换为另一个子卷。顶层子卷在文件系统上的路径为 /
,其他子卷嵌套在顶层子卷下方。但是,子卷可以在文件系统中移动,它们的路径可能会更改,而它们的 ID 不会更改。
默认情况下,挂载文件系统时会挂载顶层子卷。选项允许改为挂载特定的子卷。
子卷的主要用例是 快照。
有关更多详细信息,请参阅以下链接
创建子卷
要创建子卷,必须挂载 Btrfs 文件系统。子卷的名称使用最后一个参数设置。
# btrfs subvolume create /path/to/subvolume
--parents
自动创建父目录(如果它们不存在)。列出子卷
要查看路径所属文件系统的所有子卷的列表
# btrfs subvolume list -t path
-t
触发更易读的表格视图。
删除子卷
要删除子卷
# btrfs subvolume delete /path/to/subvolume
如果子卷包含应删除的其他子卷,请添加 -R
/--recursive
选项。或者,可以像常规目录一样删除子卷 (rm -r
, rmdir
)。
挂载子卷
可以使用 subvol=/path/to/subvolume
或 subvolid=objectid
挂载标志像文件系统分区一样挂载子卷。例如,您可以创建一个名为 subvol_root
的子卷并将其挂载为 /
。可以通过在文件系统的顶层下创建各种子卷,然后将它们挂载到适当的挂载点来模拟传统的文件系统分区。最好使用 subvol=/path/to/subvolume
而不是 subvolid 进行挂载,因为 subvolid 在还原 #快照 时可能会更改,从而需要更改挂载配置。
/
(默认情况下是这样做的),可以更轻松地更改子卷布局。相反,请考虑创建一个子卷来存放您的实际数据并将其挂载为 /
。有关每个子卷可以使用哪些挂载选项,请参阅 Btrfs Wiki FAQ。
有关使用子卷的文件系统布局示例,请参阅 Snapper#建议的文件系统布局、Btrfs SysadminGuide#管理快照 和 SysadminGuide#Layout。
有关 Btrfs 特定的挂载选项的完整列表,请参阅 btrfs(5)。
将子卷挂载为根目录
要将子卷用作根挂载点,请将其设置为默认子卷,或使用内核参数 rootflags=subvol=/path/to/subvolume
指定子卷。在 /etc/fstab
中编辑根挂载点,并指定挂载选项 subvol=
。或者,可以使用其 id 指定子卷,rootflags=subvolid=objectid
作为内核参数,subvolid=objectid
作为 /etc/fstab
中的挂载选项。最好使用 subvol=/path/to/subvolume
而不是 subvolid 进行挂载,因为 subvolid 在还原 #快照 时可能会更改,从而需要更改挂载配置,否则系统将无法启动。
更改默认子卷
如果未提供 subvol=
挂载选项,则会挂载默认子卷。要更改默认子卷,请执行
# btrfs subvolume set-default subvolume-id /
其中 subvolume-id 可以通过列出找到。
使用 btrfs subvolume set-default
更改默认子卷将使文件系统的顶层不可访问,除非使用 subvol=/
或 subvolid=5
挂载选项 [6]。
配额
Btrfs 中的配额支持在子卷级别通过使用配额组或 qgroup 实现:默认情况下,每个子卷都分配了一个配额组,形式为 0/subvolume_id
。但是,如果需要,可以使用任何数字创建配额组。
要使用 qgroups,您需要首先使用以下命令启用配额
# btrfs quota enable path
从此刻开始,新创建的子卷将受这些组控制。为了追溯性地为已存在的子卷启用它们,请正常启用配额,然后使用每个子卷的 subvolume_id 为每个子卷创建一个 qgroup(配额组)并重新扫描它们
# btrfs subvolume list path | cut -d' ' -f2 | xargs -I{} -n1 btrfs qgroup create 0/{} path # btrfs quota rescan path
Btrfs 中的配额组形成树层次结构,其中 qgroup 附加到子卷。大小限制是按 qgroup 设置的,并且当树中包含给定子卷的任何限制达到时,该限制会生效。
配额组的限制可以应用于总数据使用量、未共享数据使用量、压缩数据使用量或两者。文件复制和文件删除都可能影响限制,因为如果原始卷的文件被删除并且仅剩一份副本,则另一个 qgroup 的未共享限制可能会更改。例如,新的快照与原始子卷共享几乎所有块,对任一子卷的新写入将朝着独占限制增加,删除一个卷中的公共数据会朝着另一个卷中的独占限制增加。
要对 qgroup 应用限制,请使用命令 btrfs qgroup limit
。根据您的使用情况,可以使用总限制、未共享限制 (-e
) 或压缩限制 (-c
)。要显示文件系统中给定路径的使用情况和限制,请使用
# btrfs qgroup show -reF path
提交间隔
数据写入文件系统的分辨率由 Btrfs 本身和系统范围的设置决定。Btrfs 默认为 30 秒的检查点间隔,新数据在该间隔内提交到文件系统。可以通过在 /etc/fstab
中为 Btrfs 分区附加 commit
挂载选项来更改此设置。
LABEL=arch64 / btrfs defaults,compress=zstd,commit=120 0 0
系统范围的设置也会影响提交间隔。它们包括 /proc/sys/vm/*
下的文件,并且超出了本文的范围。有关它们的内核文档,请访问 https://docs.linuxkernel.org.cn/admin-guide/sysctl/vm.html。
SSD TRIM
Btrfs 文件系统能够从支持 TRIM 命令的 SSD 驱动器中释放未使用的块。异步丢弃支持可通过挂载选项 discard=async
获得,并且自 linux 6.2 起默认启用。释放的区段不会立即丢弃,而是分组在一起,稍后由单独的工作线程进行 TRIM,从而改善提交延迟。
异步丢弃可以安全地与定期 TRIM [7] 一起使用。
关于启用和使用 TRIM 的更多信息,请参阅 固态硬盘#TRIM。
用法
交换文件
要正确初始化交换文件,首先创建一个非快照子卷来托管该文件,例如:
# btrfs subvolume create /swap
创建交换文件
# btrfs filesystem mkswapfile --size 4g --uuid clear /swap/swapfile
如果省略 --size
,则默认使用 2GiB。
激活交换文件
# swapon /swap/swapfile
最后,编辑 fstab 配置文件以添加交换文件的条目
/etc/fstab
/swap/swapfile none swap defaults 0 0
有关更多信息,请参阅 fstab#用法。
No_COW
属性(使用 chattr
),然后按照 Swap#交换文件创建 中的步骤操作。有关替代方法,请参阅 btrfs(5) § SWAPFILE 支持。要将交换文件用于休眠,您可能还需要按照 休眠 中描述的步骤进行操作。
显示已用/可用空间
通用的 Linux 用户空间工具,如 df(1),将不准确地报告 Btrfs 分区上的可用空间。建议使用 btrfs filesystem usage
查询 Btrfs 分区。例如,要获得设备分配和使用统计的完整细分:
# btrfs filesystem usage /
btrfs filesystem usage
命令目前无法在 RAID5/RAID6
RAID 级别下正常工作。或者,btrfs filesystem df
允许快速检查已分配空间的使用情况,而无需以 root 身份运行
$ btrfs filesystem df /
有关更多信息,请参阅 [8]。
相同的限制适用于分析文件系统某些子集空间使用情况的工具,例如 du(1) 或 ncdu(1),因为它们没有考虑 reflinks、快照和压缩。相反,请参阅 btduAUR 和 compsize 以获取 Btrfs 感知的替代方案。
碎片整理
Btrfs 支持通过挂载选项 autodefrag
进行在线碎片整理;请参阅 btrfs(5) § 挂载选项。要手动整理您的根目录,请使用:
# btrfs filesystem defragment -r /
在没有 -r
开关的情况下使用上述命令将仅导致包含目录的子卷所持有的元数据被碎片整理。这允许通过简单地指定路径来进行单个文件碎片整理。
cp
或 bcp 创建的副本)的文件进行碎片整理,再加上使用带有压缩算法的 -c
开关,可能会导致两个不相关的文件,从而有效地增加磁盘使用率。RAID
Btrfs 为 #多设备文件系统 提供原生 “RAID”。使 Btrfs RAID 与 mdadm 区分开来的显著功能是自愈冗余阵列和在线平衡。有关更多信息,请参阅 Btrfs wiki 页面。Btrfs 系统管理员页面也有一个部分提供了更多技术背景。
Scrub
Btrfs Wiki 术语表指出,Btrfs scrub 是“[一种]在线文件系统检查工具。读取文件系统上的所有数据和元数据,并使用校验和和来自 RAID 存储的重复副本,以识别和修复任何损坏的数据。”
手动启动
要在包含 /
的文件系统上启动(后台)scrub:
# btrfs scrub start /
要检查正在运行的 scrub 的状态:
# btrfs scrub status /
使用服务或定时器启动
btrfs-progs 软件包带来了 btrfs-scrub@.timer
单元,用于每月 scrub 指定的挂载点。启用带有转义路径的定时器,例如 btrfs-scrub@-.timer
用于 /
,btrfs-scrub@home.timer
用于 /home
。您可以使用 systemd-escape -p /path/to/mountpoint
来转义路径;有关详细信息,请参阅 systemd-escape(1)。
您也可以通过启动 btrfs-scrub@.service
(使用相同的编码路径)来运行 scrub。与 btrfs scrub
(以 root 用户身份)相比,其优势在于 scrub 的结果将记录在 systemd 日志中。
在散热不足的大型 NVMe 驱动器上(例如在笔记本电脑中),scrub 可能会以足够快且足够长的时间读取驱动器,使其变得非常热。如果您正在使用 systemd 运行 scrub,则可以使用 drop-in 文件轻松地使用 systemd.resource-control(5) 中描述的 IOReadBandwidthMax
选项来限制 scrub 的速率。
Balance
“balance 再次通过分配器传递文件系统中的所有数据。它主要用于在添加或删除设备时重新平衡文件系统中跨设备的数据。如果设备发生故障,balance 将为冗余 RAID 级别重新生成丢失的副本。” [9] 请参阅 上游 FAQ 页面。
在单设备文件系统上,balance 也可能有助于(临时)减少已分配但未使用的(元)数据块的数量。有时,这对于修复 “文件系统已满”问题是必需的。
# btrfs balance start --bg / # btrfs balance status /
快照
“快照只是一个子卷,它使用 Btrfs 的 COW 功能与其他一些子卷共享其数据(和元数据)。” 有关详细信息,请参阅 Btrfs Wiki SysadminGuide#快照。
要创建快照:
# btrfs subvolume snapshot source [dest/]name
要创建只读快照,请添加 -r
标志。要创建只读快照的可写版本,只需创建其快照即可。
- 可以使用
btrfs property set -f -ts '/path/to/snapshot' ro false
将快照就地从只读转换为可写。但是,不建议这样做,因为它会导致问题,影响未来的任何增量发送/接收。制作新的可写快照可以防止此类问题。 - 快照不是递归的。每个嵌套的子卷都将是快照中的一个空目录。
发送/接收
可以使用 send
命令将子卷发送到 stdout 或文件。当管道传输到 Btrfs receive
命令时,这通常最有用。例如,要将名为 /root_backup
的快照(可能是您之前为 /
制作的快照)发送到 /backup
,您可以执行以下操作:
# btrfs send /root_backup | btrfs receive /backup
发送的快照必须是只读的。上述命令对于将子卷复制到外部设备(例如,上面挂载在 /backup
的 USB 磁盘)很有用。
将在接收端创建子卷。无需手动创建。
另一个示例,它创建:/mnt/arch-v2/subvolumes/@var
# btrfs send --proto 2 --compressed-data '/mnt/arch/snapshots/@var' | btrfs receive '/mnt/arch-v2/subvolumes/'
示例中使用的参数 --proto 2
和 --compressed-data
可能有助于更高效地发送(假设压缩数据)。
您也可以仅发送两个快照之间的差异。例如,如果您已经发送了上述 root_backup
的副本,并且在系统上制作了一个名为 root_backup_new
的新只读快照,那么要仅将增量差异发送到 /backup
,请执行:
# btrfs send -p /root_backup /root_backup_new | btrfs receive /backup
现在,/backup
中将存在一个名为 root_backup_new
的新子卷。
有关如何将此用于增量备份以及用于自动化该过程的工具,请参阅 Btrfs Wiki 的增量备份页面 和 #增量备份到外部驱动器。
去重
通过写时复制,Btrfs 能够复制文件或整个子卷,而无需实际复制数据。但是,每当文件被更改时,都会创建一个新的实际副本。去重更进一步,通过主动识别共享公共序列的数据块,并将它们组合成具有相同写时复制语义的区段。
专用于去重 Btrfs 格式化分区的工具包括 duperemove 和 bees。人们可能还希望仅在文件级别上去重数据,而不是使用例如 rmlint-gitAUR、rdfind、jdupesAUR 或 dduper-gitAUR。有关这些程序可用功能和附加信息的概述,请查看 上游 Wiki 条目。
调整大小
您可以将文件系统扩展到设备上可用的最大空间,或指定确切的大小。在尝试增加文件系统的大小之前,请确保增加设备或逻辑卷的大小。当为设备上的文件系统指定确切大小时(无论是增加还是减小),请确保新大小满足以下条件:
- 新大小必须大于现有数据的大小;否则,会发生数据丢失。
- 新大小必须等于或小于当前设备大小,因为文件系统大小不能超出可用空间。
要将文件系统大小扩展到设备的最大可用大小:
# btrfs filesystem resize max /
要将文件系统扩展到特定大小:
# btrfs filesystem resize size /
将 size
替换为所需的字节大小。您也可以在值上指定单位,例如 K(千字节)、M(兆字节)或 G(吉字节)。或者,您可以通过在值前加上加号 (+) 或减号 (-) 来指定相对于当前大小的增加或减少:
# btrfs filesystem resize +size / # btrfs filesystem resize -size /
已知问题
在尝试之前,应了解一些限制。
加密
Btrfs 没有内置的加密支持,但这可能会在未来实现。用户可以在运行 mkfs.btrfs
之前加密分区,请参阅 dm-crypt/加密整个系统。另一种方法是 堆叠文件系统加密。
btrfs check 问题
工具 btrfs check
存在已知问题,不应在未进一步阅读的情况下运行;请参阅 #btrfs check 部分。
技巧和窍门
无分区 Btrfs 磁盘
Btrfs 可以占用整个数据存储设备,取代 MBR 或 GPT 分区方案,使用 子卷来模拟分区。但是,并非必须使用无分区设置才能简单地在现有分区上创建 Btrfs 文件系统,该分区是使用另一种方法创建的。无分区单磁盘设置有一些限制:
要使用 Btrfs 覆盖现有的分区表,请运行以下命令:
# mkfs.btrfs /dev/sdX
例如,使用 /dev/sda
而不是 /dev/sda1
。后者将格式化现有分区,而不是替换整个分区方案。由于根分区是 Btrfs,请确保 btrfs
已编译到内核中,或者将 btrfs
放入 mkinitcpio.conf#MODULES 并重新生成 initramfs。
像对待带有 主引导记录的数据存储设备一样安装启动引导器。请参阅 Syslinux#手动 或 GRUB/技巧和窍门#安装到分区或无分区磁盘。如果您的内核由于 Failed to mount /sysroot.
而无法启动,请在 /etc/default/grub
中添加 GRUB_PRELOAD_MODULES="btrfs"
并生成 grub 配置文件。
Ext3/4 到 Btrfs 转换
从安装 CD 启动,然后通过执行以下操作进行转换:
# btrfs-convert /dev/partition
挂载分区并通过检查文件来测试转换。请务必更改 /etc/fstab
以反映更改(将类型更改为 btrfs
,并将fs_passno [最后一个字段] 更改为 0
,因为 Btrfs 在启动时不做文件系统检查)。另请注意,分区的 UUID 将已更改,因此在使用 UUID 时相应地更新 fstab。chroot
进入系统并重建启动引导器的菜单列表(请参阅 从现有 Linux 安装)。如果转换根文件系统,在仍然 chroot 的情况下,运行 mkinitcpio -p linux
以重新生成 initramfs,否则系统将无法成功启动。
/ext2_saved
仍然存在,始终可以选择回滚。使用 btrfs-convert -r /dev/partition
命令进行回滚;这将丢弃对新转换的 Btrfs 文件系统的任何修改。在确认没有问题后,通过删除备份 ext2_saved
子卷来完成转换。请注意,如果没有它,您将无法恢复到 ext3/4。
# btrfs subvolume delete /ext2_saved
最后,平衡文件系统以回收空间。
请记住,一些先前安装的应用程序必须适应 Btrfs。
损坏恢复
btrfs check
存在已知问题,请参阅 #btrfs check 部分btrfs-check 不能在已挂载的文件系统上使用。为了能够在不从 Live USB 启动的情况下使用 btrfs-check,请将其添加到初始 ramdisk:
/etc/mkinitcpio.conf
BINARIES=(btrfs)
然后,如果启动出现问题,该实用程序可用于修复。
有关更多信息,请参阅 btrfs-check(8)。
启动到快照
为了启动到快照,与将子卷挂载为根分区相同的过程适用,如 将子卷挂载为根分区 部分所述,因为快照可以像子卷一样挂载。
- 如果使用 GRUB,则在重新生成配置文件时,可以在 grub-btrfs 或 grub-btrfs-gitAUR 的帮助下自动填充 Btrfs 快照的启动菜单。
- 如果使用 rEFInd,则在启用
refind-btrfs.service
后,可以在 refind-btrfsAUR 的帮助下自动填充 Btrfs 快照的启动菜单。 - 如果使用 Limine,您可以安装 limine-snapper-syncAUR,它会在启用
limine-snapper-watcher.service
后,每当 Snapper 列表更改时,自动在启动菜单中生成快照条目。有关更多信息,请参阅 Limine#Snapper 快照与 Btrfs 的集成。
将 Btrfs 子卷与 systemd-nspawn 一起使用
请参阅 Systemd-nspawn#将 Btrfs 子卷用作容器根目录 和 Systemd-nspawn#使用容器的临时 Btrfs 快照 文章。
减少访问时间元数据更新
由于 Btrfs 的写时复制特性,仅仅访问文件就会触发元数据复制和写入。减少访问时间更新的频率可以消除这种意外的磁盘使用并提高性能。有关可用选项,请参阅 fstab#atime 选项。
增量备份到外部驱动器
以下软件包使用 btrfs send
和 btrfs receive
将备份增量发送到外部驱动器。请参阅它们的文档以了解实现、功能和要求的差异。
- btrbk — 用于创建 Btrfs 子卷的快照和远程备份的工具。
- snap-sync — 使用 Snapper 快照备份到外部驱动器或远程计算机。
- snapsync — Snapper 的同步工具。
以下软件包允许将 snapper 快照备份到非 Btrfs 文件系统。
- snapborg — 类似于 borgmatic 的工具,它将 snapper 快照与 borg 备份集成。
自动快照
对于 Btrfs 快照的管理和自动创建,可以使用快照管理器,例如 Snapper、Timeshift 或 Yabsnap。
自动通知
桌面通知可帮助您立即注意到严重的 Btrfs 问题,与根本没有通知相比,可提供更好的感知。
btrfs-desktop-notificationAUR 为以下事件提供桌面通知:
- 启动到任何只读快照或系统。
- dmesg 日志中出现的 Btrfs 警告、错误或致命消息。
有关更多信息和配置,请参阅 https://gitlab.com/Zesko/btrfs-desktop-notification。
故障排除
有关常规故障排除,请参阅 Btrfs 故障排除页面 和 Btrfs 问题 FAQ。
GRUB
分区偏移
当您尝试将 core.img
嵌入到已分区磁盘中时,可能会发生偏移问题。这意味着将 GRUB 的 core.img
直接嵌入到无分区磁盘(例如 /dev/sdX
)上的 Btrfs 池中是没问题的。
GRUB 可以启动 Btrfs 分区,但是该模块可能比其他文件系统更大。并且由 grub-install
创建的 core.img
文件可能不适合驱动器 MBR 和第一个分区之间的前 63 个扇区(31.5KiB)。最新的分区工具(如 fdisk
和 gdisk
)通过将第一个分区偏移大约 1MiB 或 2MiB 来避免此问题。
缺少 root
遇到以下情况的用户:从 RAID 样式设置启动时出现 error no such device: root
,然后编辑 /usr/share/grub/grub-mkconfig_lib 并删除行 echo " search --no-floppy --fs-uuid --set=root ${hints} ${fs_uuid}"
中的两个引号。为 grub 重新生成配置,系统应该可以无错误启动。
挂载超时
有时,特别是在大型 RAID1 阵列中,挂载可能会在启动期间超时,并显示如下日志消息:
Jan 25 18:05:12 host systemd[1]: storage.mount: Mounting timed out. Terminating. Jan 25 18:05:46 host systemd[1]: storage.mount: Mount process exited, code=killed, status=15/TERM Jan 25 18:05:46 host systemd[1]: storage.mount: Failed with result 'timeout'. Jan 25 18:05:46 host systemd[1]: Failed to mount /storage. Jan 25 18:05:46 host systemd[1]: Startup finished in 32.943s (firmware) + 3.097s (loader) + 7.247s (kernel)> Jan 25 18:05:46 host kernel: BTRFS error (device sda): open_ctree failed
这可以通过在 fstab 中通过 systemd 特定的挂载选项 x-systemd.mount-timeout
提供更长的超时时间来轻松解决。例如:
/dev/sda /storage btrfs rw,relatime,x-systemd.mount-timeout=5min 0 0
BTRFS: open_ctree failed
截至 2014 年 11 月,systemd 或 mkinitcpio 中似乎存在一个错误,导致在 mkinitcpio.conf
中使用 btrfs
hook 的多设备 Btrfs 文件系统的系统上出现以下错误:
BTRFS: open_ctree failed mount: wrong fs type, bad option, bad superblock on /dev/sdb2, missing codepage or helper program, or other error In some cases, useful info is found in syslog - try dmesg|tail or so. You are now being dropped into an emergency shell.
一种解决方法是从 /etc/mkinitcpio.conf
中的 HOOKS
数组中删除 btrfs
,而是将 btrfs
添加到 MODULES
数组中。然后重新生成 initramfs 并重新启动。
如果您尝试挂载缺少其中一个设备的 raid 阵列,您将得到相同的错误。在这种情况下,您必须将 degraded
挂载选项添加到 /etc/fstab
。如果您的根目录位于阵列上,您还必须将 rootflags=degraded
添加到您的 内核参数。
截至 2016 年 8 月,此 bug 的一个潜在解决方法是在 /etc/fstab
中仅挂载阵列中的一个驱动器,并允许 Btrfs 自动发现和附加其他驱动器。基于组的标识符(例如 UUID 和 LABEL)似乎会导致失败。例如,一个由 'disk1' 和 'disk2' 组成的双设备 RAID1 阵列将分配一个 UUID,但不要使用 UUID,而是在 /etc/fstab
中仅使用 /dev/mapper/disk1
。有关更详细的说明,请参阅以下博客文章。
另一个可能的解决方法是在 mkinitcpio.conf 中删除 udev
hook,并将其替换为 systemd
hook。在这种情况下,btrfs
不应 位于 HOOKS
或 MODULES
数组中。
请参阅原始论坛帖子和 FS#42884 以获取更多信息和讨论。
btrfs check
btrfs check
命令,因此强烈建议创建备份并在执行带有 --repair
开关的 btrfs check
之前查阅 btrfs-check(8)。btrfs-check(8) 命令可用于检查或修复未挂载的 Btrfs 文件系统。但是,此修复工具仍不成熟,即使对于那些不会导致文件系统无法挂载的错误,也无法修复某些文件系统错误。
持续的驱动器活动
自 内核 版本 6.2 起,默认设置 discard=async
mount(8) 选项。据报告,这会导致某些驱动器即使在空闲时也会持续活动,因为丢弃队列的填充速度快于处理速度。这可能会导致功耗增加,尤其是在基于 NVMe 的驱动器上。
从内核版本 6.3 开始,默认丢弃 iops_limit
已从 100 更改为 1000,以解决此问题。您可以在旧内核版本上手动将其设置为所需的值,例如
# echo 1000 > /sys/fs/btrfs/uuid/discard/iops_limit
其中 uuid
是 Btrfs 文件系统的 UUID。 1000
的限制将需要通过实验进行调整。
要在启动时设置参数,可以使用 systemd-tmpfiles,例如,通过创建以下文件
/etc/tmpfiles.d/btrfs-discard.conf
w /sys/fs/btrfs/uuid/discard/iops_limit - - - - 1000
或者,可以完全禁用异步丢弃,方法是在 fstab 中使用 nodiscard
挂载选项进行挂载,并改用 定期 TRIM。
设备 total_bytes 应最多为 X,但找到 Y
如果驱动器已从另一台计算机移动或设备顺序已更改,并且报告的大小差异很小(最多几兆字节),则可能是 HPA(主机保护区域) 生效。
要验证是否启用了 HPA,请使用 hdparm
# hdparm -N DEVICE
输出提供两个数字:可见扇区数和实际扇区数。如果它们不同,则启用了 HPA。
如果主板强制设置此项,并且固件不提供关闭该选项的选项,则唯一的选择是缩小受影响的文件系统。这在原始计算机上或在任何不应用 HPA 的机器上最容易完成。
设备上没有剩余空间
博客文章 Fixing Btrfs Filesystem Full Problems 建议并解释了以下检查/步骤
- 立即清理空间(删除历史快照)
- 你的文件系统真的满了么?元数据和/或数据块不平衡(运行
btrfs balance
) - 你的文件系统真的满了么?数据块不平衡
- 你的文件系统真的满了么?元数据不平衡
- 由于文件系统已满,无法运行 Balance(在运行
btrfs balance
之前,临时添加设备(例如 USB 密钥或循环设备)到 btrfs 文件系统,使用btrfs device add
)
另请参阅
- 官方网站
- 性能相关
- 其他