网友在上文热议的btrfs的种种不良印象,跟我之前使用中似乎不一样,我觉得btrfs有很多亮点、很强大,它是近些年推出的优秀的文件系统。SUSE 的开发者曾为 Linux 6.0 内核更新了 Btrfs 文件系统,使得工作负载的吞吐量提高了 3 倍。而 Linux 6.3 内核中包含了Btrfs的大量更新和性能优化 ,据说最高可以提升 10 倍。
本文和大家一起探索下btrfs的部分功能。
Btrfs(B-tree File System)是一种开源的文件系统,最初由 Oracle 开发,并于 2009 年首次发布。它是一种支持写入时复制(COW,copy on write)的文件系统,被广泛运用于各种 Linux 操作系统之中,目标是取代 ext3 文件系统,改善 ext3 的限制。
虽然 Btrfs 已经得到了广泛的应用和支持,但目前并没有任何主流的 Linux 发行版将其作为默认文件系统。一些 Linux 发行版已经将 Btrfs 作为可选的文件系统提供给用户,例如 Fedora、Ubuntu、openSUSE、Debian 等。这些发行版通常会在安装过程中提供选择 Btrfs 作为文件系统的选项,或者在系统安装后通过命令行或图形界面工具进行转换。
需要注意的是,虽然 Btrfs 具有一些先进的功能和特性,但它仍然是一种相对较新的文件系统,可能存在一些稳定性和兼容性问题。因此,在选择使用 Btrfs 作为文件系统时,建议您仔细评估其优缺点,并根据自己的需求和风险承受能力做出选择。以下为演练操作,建议在虚拟机环境下演练。
环境说明
由于btrfs的一些功能在不同版本推出,所以这里有必要先声明所用的btrfs环境信息。
- 系统为Ubuntu 22.04 64位(Btrfs在Centos7、Deepin等发行版也支持)。
- btrfs版本 btrfs-progs v5.16.2。
- 现有存储设备情况
# ls /dev/sd*
sda sda1 sdb sdc
#
其中 /dev/sdb 和 /dev/sdc 是2块均为2T的物理硬盘,未格式化。将用于创建btrfs文件系统。
以下是基于 /dev/sdb和/dev/sdc 硬盘创建支持快照、数据压缩、只读文件系统等特性的 Btrfs 文件系统的步骤:
(1) 确保系统中安装了 Btrfs 工具:
# sudo apt update
# sudo apt install btrfs-progs
# sudo btrfs --version
btrfs-progs v5.16.2
(2) 查询当前有哪些btrfs分区:
# sudo btrfs filesystem show
由于未建立任何btrfs分区,所以显示为空。
(3) 创建 Btrfs 文件系统:
# sudo mkfs.btrfs -m raid1 /dev/sdb /dev/sdc
上述命令将使用 RAID1 模式创建一个 Btrfs 文件系统,其中 /dev/sdb 和 /dev/sdc 是使用的两块物理硬盘。
查看创建的btrfs:
# sudo btrfs filesystem show
Label: none uuid: 3b9d76ac-c675-404e-8f99-e13d5420eb0c
Total devices 2 FS bytes used 256.00KiB
devid 1 size 2.00TiB used 1.02GiB path /dev/sdb
devid 2 size 2.00TiB used 1.01GiB path /dev/sdc
(4) 挂载 Btrfs 文件系统:
# sudo mount /dev/sdb /mnt/
上述命令将 Btrfs 文件系统(设备路径 /dev/sdb)挂载到 /mnt 目录。以上改成使用
# sudo mount /dev/sdc /mnt/
的结果一样的,在btrfs的体系下,btrfs的成员存储设备每个都可以作为同等地位的挂载来源。所以用两块硬盘中的任意一块的地址都可以。
使用 df 查看最新的文件系统情况:
# df -lh
可看到/mnt对应的空间容量有4TB:
# mount /dev/sdb /mnt
# df -lh
Filesystem Size Used Avail Use% Mounted on
tmpfs 546M 1.3M 545M 1% /run
/dev/sda1 2.0T 9.7G 1.9T 1% /
tmpfs 2.7G 4.0K 2.7G 1% /dev/shm
tmpfs 5.0M 4.0K 5.0M 1% /run/lock
tmpfs 546M 76K 546M 1% /run/user/1000
/dev/sdb 4.0T 4.0M 4.0T 1% /mnt
配置 Btrfs 文件系统的子卷:
# sudo btrfs subvolume create /mnt/@home
# sudo btrfs subvolume create /mnt/@snapshots
# sudo btrfs subvolume create /mnt/@backup
上述命令创建了三个子卷:@home、@snapshots 和 @backup。您可以根据需要创建更多的子卷。@
符号后的是子卷名称。三个子卷在文件系统目录下。
(6) 配置子卷的属性:
# sudo btrfs property set /mnt/@home compression lzo
# sudo btrfs property set /mnt/@snapshots ro true
上述命令将 @home 子卷的压缩算法设置为 lzo,并将 @snapshots 子卷设置为只读,由于作为快照用途,为了保护快照不被篡改可以设置快照子卷为只读(这个功能在防止勒索病毒破坏的情况下非常有用)。
目前不建议马上执行上面第2句命令。如果你已执行,可继续执行下面命令将其设置为可读写:
# sudo btrfs property set /mnt/@snapshots ro false
既然有set,就有get,我们要查看btrfs的子卷的属性,则只需将set改为get,
# sudo btrfs property get /mnt/@snapshots
输出显式了该子卷当前的属性:
ro=false
就获取到了子卷 @snapshots 的状态,目前为可读写权限。
关于btrfs的peroperty支持哪些参数,可在闲时进一步阅读btrfs子卷的 property 支持的参数列表,官网文档链接[1]我们继续测试btrfs的 快照功能。
(7) 启用 Btrfs 文件系统的快照功能:
快照简单的来说就是一个子卷,它使用 Btrfs 的 COW 功能与其他子卷共享其数据和元数据。
快照占用的空间将随着原始子卷或快照本身(如果它是可写的)的数据变化而增加。子卷中已添加/修改的文件和已删除的文件仍然存在于快照中。这是一种方便的增量备份方式,快照 home-2023-12-04-1 生成后发生的任何文件变化,就被作为下一次快照home-2023-12-04-2需要保存的增量数据,如此不断增量备份。下面对此加以演示说明:
# sudo btrfs subvolumn snapshot /mnt/@home /mnt/@snapshots/home-2023-12-04-1
上述命令创建了 @home 子卷的快照,位置在日期名称的路径下。此时/mnt/@home 目录内没有任何文件,所以快照 /mnt/@snapshots/home-2023-12-04-1 里也没有任何文件。
然后复制 /etc/fstab文件到 子卷 @home 里:
# cp /etc/fstab /mnt/@home
再快照为 /mnt/@snapshots/home-2023-12-04-2:
# sudo btrfs subvolumn snapshot /mnt/@home /mnt/@snapshots/home-2023-12-04-2
此时查看新快照内的文件情况:
# ls /mnt/@snapshots/home-2023-12-04-2
结果显示有个 fstab 文件。而老快照仍没有文件。
# ls /mnt/@snapshots/home-2023-12-04-1
说明 两个快照确实是不同时刻的文件系统快照,效果符合预期。
现在,您已经成功创建了一个支持快照、数据压缩和只读等特性的 Btrfs 文件系统。您可以根据需要在子卷中存储不同类型的数据,并使用 Btrfs 的管理命令进行管理和操作。
(8) 卸载 Btrfs 文件系统:
# sudo umount /dev/sdb
或:
# sudo umount /dev/sdc
上述命令将 Btrfs 文件系统从挂载的 /mnt 目录卸载。之所以能用 sdb和sdc 都能卸载,道理跟第4. 挂载 Btrfs 文件系统挂载时用这两个一样。以上改成使用:
# sudo umount /mnt
也是同样效果。这与linux系统格式的文件系统的卸载是同样道理。
一个心照不宣的秘密,其实你可以更自由地给 子卷名起名:
最后不得不提到一个你可能一直觉得不爽的点:为什么btrfs子卷名称前面要以@开始?如果访问btrfs的子卷的时候每次都得用反斜杠转义后才能访问路径(shell里不写转义@的形式还会报错提示说路径不存在),觉得很麻烦吧?但似乎网上很多教程都会以@作为快照名称开头?
其实你在第5. 配置 Btrfs 文件系统的子卷时,也可以省略@,那么子卷的名称就是home,snapshot 等,后续的命令中也就不带@范围子卷。
之所以 btrfs 的很多教程里都会用@ 作为子卷名称开头,是约定俗成,为了表示与普通目录名称产生视觉区别,仅此而已( 假设 /mnt/目录下 既有子卷名、又有普通目录名的时候,就难以区分哪个是子卷)。
本文就最近热议的分区话题,评论区提到的btrfs的一些实例演示。希望对未接触过btrfs使用的小伙伴有所帮助。
参考资料:[1]btrfs子卷的 property 支持的参数列表,官网文档链接: https://btrfs.readthedocs.io/en/latest/btrfs-property.html
转载自微信公众号【深入理解Linux】,二维码如下