Btrfs文件系统
Last updated
Was this helpful?
Last updated
Was this helpful?
Btrfs文件系统已经逐渐被各种Linux发行版本支持,虽然其似乎还存在一些小问题(unstable),但是在其各种诱人的功能面前似乎并不那么重要。 由于文件系统事关重大,在实际使用前,务必详细阅读,其中详细描述了许多有价值的细节,解释了文件系统的运作模式,也包括命令参数的详解。
写时复制(Copy-on-write, CoW)指了在多个调用者请求相同资源时,只有在某个调用者试图修改资源的内容时,系统才会为其复制一份专用副本。这样没有写操作的时候,就不会有多余的副本被创建。 CoW的缺点之一在于对于像VM镜像、数据库文件这样的就地更改(updated-in-place)的文件,会导致写入碎片化。所以对于这一类数据,不妨建一个子卷然后禁用CoW来储存他们。(别忘了修改fstab
)
Btrfs默认启用写时复制,要停止使用写时复制,使用nodatacow
选项,但是这一更改只会影响新创建的文件,对于已有文件(夹)使用下列命令进行修改,但仍存在一些细节问题,使用前务必参见参考资料中关于此节的详细描述。
Btrfs通过Subvolume来实现在备份时排除某些文件夹。
通过设置挂载的选项可以挂载指定的子卷:
使用后会列出对应path
下的所有子卷,其数量可能会很多,因为所有的快照也以subvolume的形式储存,有意思的是Docker镜像也被保存为了subvolume:
这里的
path
指的是子卷的绝对路径,比如当前挂载了@
到/mnt/@
目录下,则使用路径/mnt/@/home
创建出来的子卷为@/home
。
如果只移除文件目录,而不使用
btrfs subvolume delete
命令并不会真正删除一个子卷。
在openSUSE中查看当前的Btrfs的子卷,可能会显示大量的子卷,因为snapshot实际也是通过子卷来实现的,另外值得注意的是Docker镜像也被作为snapshot独立开了:
其中@
代表了文件系统的根(rootfs),但事实上它也仍然是一个snapshot,最顶层的卷是以0为标号的子卷,不过通常不使用。 同时默认的/
同样也不是@
子卷,一般也是某一个子卷,只是默认被挂载为了/
,通过查看默认子卷可以得知:
可见当前系统的/
实际上是一个路径为@/.snapshots/1/snapshot
的子卷,真正的@
在openSUSE中是隔离开的,作为独立的根来储存需要永久保存的子卷。
正如上述讨论,由于目前的系统目录也是一个(临时)快照。 如果我们此时要创建一个子卷,不可以建立在一个一个已有的快照下,否则在进行rollback操作后就不能再删除这个子卷了。正确的操作因该是将这个子卷建立在@
子卷下。
Btrfs的快照是建立在其“写时复制”的功能基础上的。 创建快照可以使用如下命令:
对于openSUSE,目标目录通常为
/.shapshots
,这一目录为默认的统一存放快照的目录。 另外添加参数-r
可以创建只读快照,在只读快照上再创建一个快照可以获得只读快照的一个可写版本。
注意快照不是递归包含的,意味着子卷里的子卷在快照中会是空目录。 这也是为什么openSUSE下部分目录被排除在默认的snapper备份之外:它们都被创建为了额外的子卷,由于上述非递归性,他们在对/
创建的快照中均被忽略了。
在openSUSE中是支持Btrfs的压缩功能的,通过mount
的参数可以启用压缩:
compress
的默认规则是:如果你创建了一个文件,Btrfs压缩后发现压缩率低,那对于之后的写入它都不再会进行压缩。如果不希望这样,可以使用compress-force
。 对于已经写入的文件,均不会被压缩,压缩仅对新写入的文件有效。
压缩有三种算法可选:
lzo:压缩率低但是CPU资源占用少。
zlib:压缩率高但是资源占用多。
zstd:旧版本内核和GRUB
引导对其缺乏支持,暂时忽略。
在fstab
中永久启用压缩,并指定压缩算法(算法以不指定):
snapper
通过一系列的配置来管理Btrfs分区,配置文件默认位于/etc/snapper/configs/
下。 默认的方案只为/
创建快照,且内容还要排除名下的子卷。
这一操作会创建一个快照并从/etc/snapper/config-templates/default
获取一套默认配置。
使用snapper -c home set-config "<KEY>=<value>"
来修改设置。
见openSUSE,以获得更准确的信息。