如何创建和挂载 Btrfs 快照

Btrfs 是一个用于 Linux 的开源通用文件系统。
该名称源自使用 B 树来存储内部文件系统结构。
文件系统使用了不同的名称,包括“Butter F S”和“B-tree F S”。
Btrfs 的开发始于 2007 年的 Oracle,现在许多(包括 Red Hat、Fujitsu、Intel、SUSE 和许多其他)都在为开发工作做出贡献。
Btrfs 包含在主线 Linux 内核中。

Btrfs 快照

Btrfs 子卷可以进行快照和克隆,从而创建另外的 B 树。
快照作为在某个时间点拍摄的子卷的副本开始。
我们可以使快照可写,并将其用作原始子卷的演进克隆。
或者,我们可以将快照用作子卷的稳定镜像,用于备份目的或者迁移到其他系统。
快照可以快速创建,并且它们最初占用很少的磁盘空间。

使用 btrfs subvolume snapshot 命令创建子卷的可写/可读快照。
以下示例创建 SV1 子卷的快照:

# btrfs subvolume snapshot /btrfs/SV1 /btrfs/SV1/SV1-snap
Create a snapshot of '/btrfs/SV1' in '/btrfs/SV1/SV1-snap'

使用 btrfs subvolume snapshot -r 选项创建只读快照:

# btrfs subvolume snapshot -r /btrfs/SV1 /btrfs/SV1-rosnap
Create a readonly snapshot of '/btrfs/SV1' in '/btrfs/SV1-rosnap'

使用 ls 命令时,快照显示为常规目录。
快照也会出现在 btrfs subvolume list 命令的输出中。

# btrfs subvolume list /btrfs
ID 257 gen 10 top level 5 path SV1
ID 258 gen 9 top level 257 path SV1/SV1-snap
ID 259 gen 10 top level 5 path SV1-rosnap

挂载子卷或者快照

默认情况下,Linux 挂载 ID 为 0 的父 Btrfs 卷。
在此示例中,在创建任何子卷和快照之前发出以下挂载命令:

# mount /dev/sdb /btrfs

子卷 SV1 是在 /btrfs 中创建的。
ls 命令显示子卷:

# ls -l /btrfs
total 0
drwxr-xr-x. 1 root root 84 Mar 29 11:01 SV1

以下示例将文件复制到 SV1,创建 SV1 的快照,并验证子卷和快照是否包含相同的文件:

# cp -p /boot/vmlinuz-3.10.0-693.17.1.el7.x86_64 /btrfs/SV1
# btrfs sub snapshot /btrfs/SV1 /btrfs/SV1-snap
Create a snapshot of '/btrfs/SV1' in '/btrfs/SV1-snap'
# ls /btrfs/SV1*
/btrfs/SV1:
vmlinuz-3.10.0-693.17.1.el7.x86_64
/btrfs/SV1-snap:
vmlinuz-3.10.0-693.17.1.el7.x86_64

如果卸载 /btrfs 并重新挂载,默认情况下会挂载父 Btrfs 卷:

# ls /btrfs/
SV1  SV1-snap
# umount /btrfs
# mount /dev/sda /btrfs/
# ls /btrfs/
SV1  SV1-snap

但是,我们可以将 btrfs 子卷或者快照挂载为磁盘设备。
如果我们挂载快照而不是其父子卷,则可以有效地将文件系统的状态回滚到拍摄快照时的状态。
以下示例将文件复制到 SV1,以便内容与 SV1-snap 不同:

# cp testfile /btrfs/SV1
# ls -l /btrfs/SV1*
/btrfs/SV1:
total 5760
-rw-r--r--. 1 root root      19 Mar 29 11:44 testfile
-rwxr-xr-x. 1 root root 5890720 Jan 25 20:26 vmlinuz-3.10.0-693.17.1.el7.x86_64
/btrfs/SV1-snap:
total 5756
-rwxr-xr-x. 1 root root 5890720 Jan 25 20:26 vmlinuz-3.10.0-693.17.1.el7.x86_64

要挂载子卷或者快照,我们必须首先确定要挂载的子卷的 ID 号。
使用 btrfs subvolume list 命令显示 ID 号。
在以下示例中,根子卷的 ID 为 257:

# btrfs sub list /btrfs
ID 257 gen 12 top level 5 path SV1
ID 258 gen 9 top level 5 path SV1-snap

使用 btrfs "subvolume set-default" 命令设置文件系统的默认子卷。
例如,要挂载 ID 为 257 的 SV1 Btrfs 子卷:

# btrfs subvolume set-default 257 /btrfs

然后我们需要卸载并重新挂载 Btrfs 文件系统。
然后根级别包含 SV1 子卷的内容,并且根子卷不再可见:

# ls -l /btrfs
total 5760
-rw-r--r--. 1 root root      19 Mar 29 11:44 testfile
-rwxr-xr-x. 1 root root 5890720 Jan 25 20:26 vmlinuz-3.10.0-693.17.1.el7.x86_64

我们还可以使用 mount 命令的“-o subvolid”选项来挂载根子卷或者子卷或者快照。
例如,要挂载根子卷:

# umount /btrfs
# mount -o subvolid=5 /dev/sda /btrfs
# ls -l /btrfs
total 0
drwxr-xr-x. 1 root root 84 Mar 29 11:44 SV1
drwxr-xr-x. 1 root root 68 Mar 29 11:17 SV1-snap
https://onitroad.com 更多教程

创建文件快照

我们可以使用“cp -reflink”命令来拍摄文件的快照。
使用此选项,文件系统不会创建指向现有 inode 的新链接,而是创建一个与原始副本共享相同磁盘块的新 inode。
新文件看起来是原始文件的副本,但数据块没有重复。
这使得复制几乎是即时的,并且还节省了磁盘空间。
随着文件内容随着时间的推移而发生变化,其所需的存储量会增加。
一个限制是此操作只能在同一文件系统的边界内和同一子卷内工作。

以下示例使用 cp -reflink 命令复制文件。
使用的空间在复制操作之前和之后给出。
请注意,使用的空间不会增加。

# df -hP /btrfs
Filesystem       Size  Used   Avail  Use%   Mounted on
/dev/sda         10G   23M    8.0G    1%    /btrfs
# cp --reflink /btrfs/SV1/vmlinuz-3.10.0-693.17.1.el7.x86_64 /btrfs/SV1/copy_of_vmlinuz
# df -h /btrfs
Filesystem      Size  Used Avail Use% Mounted on
/dev/sda         10G   23M  8.0G   1% /btrfs
日期:2020-09-17 00:14:17 来源:oir作者:oir