如何创建一个btrfs快照?

我的/home分区由一个完整的物理磁盘组成。它被格式化为btrfs。我想对其进行快照。我对子卷命名感到困惑。
我知道有类似的问题,但每个类似的问题似乎都在问与我所问的不同的事情(而且它们是旧的,这意味着可能已经过时了,考虑到btrfs的快速发展)。例如,这个问题的答案显然不是我问题的答案,因为我的/home分区是一个单独的卷,而btrfs的man页面显示了一个不同的命令来创建快照。 另一个类似的问题,没有确定的解决方案还有其他人对命名问题感到困惑
我的问题是:

简单起步:这是拍摄我家分区快照的正确命令吗?

btrfs subvolume snapshot /home/@home /home/@home_snapshot_20120421

我非常勇敢地进行了测试,但是它并没有起作用。错误信息是error accessing /home/@home。如下所示,@home被列出。

显然我对子卷名称感到困惑。在创建快照时需要使用它们吗?一些示例显示使用/home作为源参数来拍摄home目录的快照,但是根据根卷的示例,似乎我需要使用/home/@home

这个命令可以工作吗?如果不能,原因是什么?

btrfs subvolume snapshot /home /home/@home_snapshot_20120421

“@”符号只是一种命名约定吗?它有任何意义吗?

以下是一些可能相关的输出:

btrfs subvolume list /home
ID 256 top level 5 path @home

我不确定确切的意思是什么。当我尝试执行btrfs device scan时,会出现错误(例如无法扫描设备/dev/sda1)。我的文件系统没有任何错误。一切都很好。
这是我的分区情况。回答某个回复时,不,/home不是我唯一的btrfs分区。
/dev/sda1: (boot partition) TYPE="ext2"  
/dev/sda2: (root partition) TYPE="btrfs"  
/dev/sdb1: (home partition) TYPE="btrfs"  
/dev/sdc1: (shared partition) TYPE="btrfs"  
/dev/sdc2: TYPE="swap"  

社区将决定有关回购的事项... - One Zero
3个回答

在Ubuntu 12.04上,创建我家目录快照的正确命令是什么?

考虑到家目录位于btrfs分区并且挂载为/home,正确的命令是:

sudo btrfs subvolume snapshot /home/ /home/<any_name_you_choose_for_the_snapshot>

这是我的结果:
在今天运行命令之前:
$ btrfs subvolume list /home  
ID 256 top level 5 path @home  
ID 257 top level 5 path @home/@snapshot_20120521_1936

命令:
$ sudo btrfs subvolume snapshot /home/ /home/@snapshot_20120611_1307  
Create a snapshot of '/home/' in '/home/@snapshot_20120611_1307'

运行今天的命令后:

$ btrfs subvolume list /home  
ID 256 top level 5 path @home  
ID 257 top level 5 path @home/@snapshot_20120521_1936  
ID 258 top level 5 path @home/@snapshot_20120611_1307

这种方法的唯一问题是当你在/home目录下使用ls命令时,快照会显示出来。
Ubuntu社区维基已经更新了一个解决方案。以下是解决方案:
如何在Ubuntu布局中处理快照
为了在Ubuntu布局中处理/或/home的快照,最方便的方法是将btrfs文件系统挂载到一个单独的位置,并从btrfs树的顶部进行操作,而不是从挂载的子卷中进行操作。 <-- 这就是解决方案。不幸的是,这并不方便。
sudo mount /dev/sdX# /mnt

要创建快照,请使用我上面使用的相同语法:

sudo btrfs subvolume snapshot /mnt/@ /mnt/@_snapshot

这将创建一个名为 @_snapshot 的子卷快照,该快照位于 btrfs 树的顶部。由于它位于树的顶部,使用挂载卷列出文件时将不会显示。
要回滚到快照,您只需要将其名称更改为 ubuntu 挂载的名称并重新启动即可。以下是更改名称的方法:
sudo mv /mnt/@ /mnt/@_badroot
sudo mv /mnt/@_snapshot /mnt/@

删除快照使用:

sudo btrfs subvolume delete /mnt/@_badroot

btrfs快照本身就是子卷,并且是自包含的。删除旧的@子卷是可以的,前提是我们有替代品。
注意:btrfs-tools命令set-default会破坏Ubuntu的布局。

所以你在那里对吧?现在你应该能够挂载你的快照了。 - turbo
我实际上还没有尝试过安装它们。而且我刚刚看到了psusi关于apt-btrfs-snapshot软件包的回答。那看起来很有趣,对吧? - MountainX
是的,我在第三点也提到了。抱歉,不得不指出一下 ;) - turbo
我建议你将你的解决方案标记为答案。 - turbo
有一个解决方案可以防止快照在ls /home时显示出来。我正在编辑我的答案,马上提供相关信息。 - MountainX

首先,好的,第一件事:
你正在查看的子卷的名称是@home,如btrfs subvolume list /home所示。它被挂载在/home上。@home是子卷的名称,它的ID是256,所以很可能只有你的/home被格式化为btrfs。
现在要创建一个@home的快照,你需要执行以下命令: sudo btrfs subvolume snapshot /home/ /home/@home_snapshot_20120421 子卷可以有任何名称。@是Ubuntu在安装时的约定。(如果你使用apt-btrfs-snapshot,根子卷必须命名为@)。社区维基强烈建议将@作为根目录,将@home作为家目录,因为它是以这种方式挂载的。这在回滚时尤其重要:你不应该使用btrfs subvolume set-default(故意未突出显示语法)。
对于btrfs device scan,你需要使用sudo。
要删除一个子卷,你可以使用sudo btrfs subvolume delete @home_snapshot_20120421
所有btrfs命令都可以缩写,只要它们是明确的。例如,sudo btrfs device scan 可以缩写为 sudo btrfs d ssudo btrfs dev sc 或其他类似的形式。
希望这回答了你的问题。有一些工具可以进行常规备份,btrfs-snapshot-rotation 就是一个例子。使用这些工具时要小心,因为它们都不够成熟或得到足够的关注,也就是说,它们很可能包含错误。

我遇到一个错误:$ sudo btrfs subvolume snapshot @home home/@snapshot_20120611_1257 ERROR: error accessing '@home' - MountainX
另外,我还没有成功地使用btrfs device scan命令。无论是使用sudo还是其他方式,都会出现错误信息"ERROR: unable to scan the device '/dev/sdX'",其中X可以是任何有效的名称,如a、a1、b等。 - MountainX
@OneZero:我还没有所有的答案,但是我已经找到了在Ubuntu 12.04上创建家庭分区快照的正确命令,并将该信息作为下面的答案提供了出来。 - MountainX
真是奇怪。我在我的 btrfs 分区 btrfs sub snap @ /mnt/random 进行了检查,对我来说是有效的。再次强调,我当时处于挂载 @ 的 /mnt 目录下。对于造成困惑,我表示抱歉。 - turbo
@turbo:你的回答非常有帮助。不需要为试图提供帮助而道歉。即使Ubuntu页面也不够清晰。我们最终会弄明白一切的。 - MountainX

安装 apt-btrfs-snapshot 软件包,并使用其子命令 listsnapshotdeleteset-default

这是一个封装了较低级别的 btrfs 命令的脚本。它通过首先在某个位置挂载 btrfs 根文件系统来工作。我指的是真正的根目录,而不是通常作为 / 挂载的 /@ 子卷。换句话说,你需要运行 mount /dev/sda1 /mnt,这样你就可以查看将被列出为 /mnt/@/mnt/@home 和其他任何你创建过的子卷。从那里,你可以运行 btrfs subvolume snapshot /mnt/@home @snapshot-today,它会创建一个名为 /@snapshot-today/@home 快照。与此相比,如果你运行 btrfs subvolume snapshot /home /home/@snapshot_today,它会将快照作为 /@home 的子项创建,因此当你运行 ls /home 时,它会显示出来,其真实名称为 /@home/@snapshot-today

回滚快照只是一个简单的重命名操作:mv /mnt/@home @backup ; mv /mnt/@snapshot-today @home。下次启动时,当它在/home中挂载/@home时,它会找到快照。
这有点棘手,因为你必须记住btrfs和内核看待事物的方式之间的差异,这受到挂载选项(特别是subvol=参数)的影响。