Arch Linux 下 Btrfs 使用小记
BTRFS 介绍
B-TRee File System 是一个支持子卷快照、数据校验、透明压缩等多种高级功能的现代写时复制(Copy on Write)文件系统。
- 写时复制
- 修改不是原地覆盖,而是先写入到空白区域,再修改指针,可保证数据一致性。1
- 支持快速复制(reflink),简单来说就是副本之间尽量共用数据块,通过 CoW 机制只需额外存储改动部分。
- 可以通过
chattr +C命令对特定文件禁用。
- 快照和子卷地位相当,也可以修改和创建快照。有人认为将其称作“分支(fork)”更加贴切。
- CRC 数据校验可以发现数据损坏,但修复依靠外部备份或 RAID。
- 透明压缩:
- 通过牺牲一定的 CPU 时间,减少实际写入硬盘的数据,提高存储容量与 IO 速度。
- 文件系统内部行为,用户无感。
- 其实当写入稀疏时是负优化,可以通过
chattr +m命令对特定文件禁用。
- 顾名思义,该文件系统使用数据结构 B 树维护元数据。
- 为了支持其先进的快照功能,实际使用的是一种能够高效复制的改进版。2
- 原理可以理解为一种懒惰思想,即尽可能共用各副本的相同部分。
- 这就是有垃圾回收的可持久化多叉平衡树,太裤辣!
BTRFS 数据损坏测试3
安装软件包 btrfs-progs。
用文件虚拟出一块硬盘。之后你可以手动编辑该文件模拟数据损坏,看看会发生什么。
1 | |
安装 BTRFS
参考资料:
笔者的分区方案(终端推荐 cfdisk 工具):
/dev/nvme0n1p1分配 260MB,挂载于/efi。(引导模式为x64 UEFI)/dev/nvme0n1p2分配剩余空间,格式化为 btrfs 文件系统。- 无交换分区。
- 此方案也适用于双系统,注意设备标签可能不同。
设计子卷布局
- 前置知识:btrfs 的子卷是按照目录结构组织的,可以用
mv命令移动。 - 个人认为,尽量不要在需要拍摄快照的子卷里面放子卷,用挂载或软链接代替。
- 快照是不会递归拍摄的,嵌套子卷拍摄后显示为空目录,恢复时需要进一步处理。
- 文件系统的根子卷比较特殊,无法从快照恢复(和不能把目录移动/复制到祖先同理),因此选择创建
@子卷表示根目录。
| 子卷 | 挂载点 |
|---|---|
| @ | / |
| @snapshots | /.snapshots |
| @swap | /swap |
| @home | /home |
| @root | /root |
| @var_log | /var/log |
| @var_cache | /var/cache |
| @var_tmp | /var/tmp |
| @docker | /var/lib/docker |
| @opt | /opt |
@子卷存放操作系统与安装的软件,@snapshots存放系统快照(snapper 会自己生成一个子卷)。@swap存放交换文件。包含交换文件的子卷无法快照,故单独分卷。/home/用户名和/root是普通用户和 root 用户的主目录,分卷可在快照回滚时保留其中的用户数据。/var/log存放日志,不应该快照。/var/cache和/var/tmp存储缓存和临时文件,不需要快照。@docker存放容器,@opt存放自包含软件,我理解这些东西独立于系统存在,不需要一起快照。
分卷并挂载
格式化并分卷:
1 | |
挂载:
1 | |
关于挂载选项的说明:
-o选项表示指定挂载选项,后面紧跟的参数是个字符串,所以注意不要输入空格(或者用双引号括起来)subvol指定挂载的子卷。(或subvolid通过 ID 指定,但是 ID 快照后会改变,不推荐)noatime禁用文件访问时间更新,可以减少写入量,对 SSD 友好。- 在一个有快照的子卷内访问文件会更糟,会导致相应的 B 树复制(这原本是懒惰的)。
chattr +A可以对特定的文件和目录单独禁用访问时间更新。没试过。
nodiratime被noatime蕴含,没必要。compress=zstd:3指定压缩算法为zstd,并指定压缩级别为 3。- zstd 压缩又快又好。
- 默认级别是 3,没测试过哪个级别最快。
ssd会自动检测并优化,不需要加该选项。discard=async自 kernel 6.2 起已经是默认选项。
安装必要软件包
需要安装 btrfs-progs 包,不然装 linux
内核时会报错。
1 | |
Snapper 快照管理
1 | |
snap-pac 是一个 pacman
hook,用来在每次更改软件包前后自动创建快照。
然后创建快照配置。
1 | |
修改
/lib/systemd/system/snapper-timeline.timer,设置创建快照频率
修改配置文件
/etc/snapper/configs/root,设置保留的快照数量
开启 Snapper 自动快照和自动清理的后台服务:
1 | |
从快照恢复
推荐安装 grub-btrfs 包,这个包可以在 grub
界面里列出快照并启动。
如果系统崩了启动不了,就用启动盘;如果没崩,重启后生效。
1 | |
交换文件与休眠4
创建并启用交换文件: 1
2btrfs filesystem mkswapfile --size 8G /swap/swapfile
swapon /swap/swapfile
据说推荐的交换空间大小大概是
编辑 fstab,追加:
1 | |
以在开机时自动启用交换文件。
配置休眠
运行 1
btrfs inspect-internal map-swapfile -r /swap/swapfile
然后创建
/etc/tmpfiles.d/hibernation.conf,写入如下内容,其中:
${offset}为上述命令的输出${swap_file_partition}为交换文件所在分区,在我们的例子中是/dev/nvme0n1p2${image_size}指定生成的镜像大小,0 表示尽可能压缩
1 | |
编辑 /etc/mkinitcpio.conf,修改 HOOKS=()
一行,添加 resume(必须在 udev
后面),示例:
55 | |
然后
1 | |
其他
GUI 快照管理软件: 1
sudo pacman -S btrfs-assistant