Btrfs (简体中文)

From ArchWiki
Jump to: navigation, search
翻译状态: 本文是英文页面 Btrfs翻译,最后翻译时间:2016-05-13,点击这里可以查看翻译后英文页面的改动。

来自 Wikipedia:Btrfs

Btrfs(B-tree 文件系统,通常念成 Butter FSBetter FSB-tree FS),一种支持写入时复制(COW)的文件系统,运行在 Linux 操作系统上,采用 GPL 授权。Oracle 于 2007 年对外宣布这项计划,并发布源代码,2014 年 8 月发布稳定版。目标是取代 Linux 当时主流的 ext3 文件系统,摆脱 ext3 的一些限制,特別是单文件大小,文件系统总大小和文件校验,并加入 ext3 不支持的一些功能,比如可写快照(writable snapshots)、快照的快照(snapshots of snapshots)、内建磁盘阵列(RAID),以及子卷(subvolumes)。Btrfs 也宣称专注于「容错、修复及易于管理」。

来自 Btrfs Wiki:

Btrfs 是一种新型的写时复制 (COW) Linux 文件系统已经并入内核主线。Btrfs 设计实现高级功能的同时,着重于容错、修复以及易于管理。它由 Oracle, Red Hat, Fujitsu, Intel, SUSE, STRATO 等企业和开发者共同开发, Btrfs 以 GNU GPL 协议授权,同时欢迎任何人的贡献.
Warning:

准备工作

Btrfs 支持已经包含在linuxlinux-lts的内核中.GRUB 2,mkinitcpioSyslinux 也已经支持 Btrfs,不需要额外配置。

要使用一些用户空间工具,安装 btrfs-progs 软件包.

分区

Tango-inaccurate.pngThe factual accuracy of this article or section is disputed.Tango-inaccurate.png

Reason: 不要对一个无分区硬盘使用 btrfs 文件系统,参见 Grub#Install_to_partition_or_partitionless_disk (Discuss in Talk:Btrfs (简体中文)#)

Btrfs 能在整个设备上使用,替代 MBRGPT 分区表,但是并不要求一定这么做,最简单的方法是 在一个已存在的分区上创建 btrfs 文件系统[broken link: invalid section]. 如果你选择用 btrfs 替代分区表, 可以用 子卷[broken link: invalid section]模拟不同的分区.

这是在单个设备上使用 btrfs 文件系统的限制:

运行下面的命令把整个设备的分区表替换成 btrfs:

# mkfs.btrfs /dev/sdX

例如 /dev/sda 而不是 /dev/sda1. 后一种形式会格式化现有的分区而不是替换掉原有的分区表.

像使用普通的 MBR 分区表存储设备一样安装 启动管理器, 例如GRUB[broken link: invalid section]:

# grub-install --recheck /dev/sdX

创建文件系统

可以新建或者从已有文件系统转化为 Btrfs.

新建文件系统

单一设备上的文件系统

要格式化一个分区:

# mkfs.btrfs -L mylabel /dev/partition

Btrfs 的默认块大小为 16KB. 使用更大的blocksize数据/元数据,为nodesize通过指定一个值-n开关使用,如本例所示16kb块:

# mkfs.btrfs -L mylabel -n 16k /dev/partition

多设备文件系统

用户可选择多个设备来创建RAID。支持的RAID级别有 RAID 0,RAID 1,RAID 10,RAID 5 和 RAID 6.数据和元数据的 RAID 等级可以用 -d-m 参数指定. 默认情况下元数据使用镜像 (RAID1),而数据被 strip (RAID0). 参阅 Btrfs Wiki:在多个设备上使用 btrfs 或查阅 mkfs.btrfs 的手册页获得更多信息.

# mkfs.btrfs -d raid0 -m raid1 /dev/part1 /dev/part2 ...
Note: Systemd 可能无法因为正确处理多设备 btrfs 文件系统上的每一个设备而不能正常启动,详见 这个bug报告 .

RAID 文章有关于维护多设备上的 btrfs 文件系统的一些建议.

从 Ext3/4 转换

Warning: 到2015年中后期, btrfs 邮件列表中报告了多起失败的转换.尽管近期的更新有所修复,但还是建议小心使用.在开始之前确定你有可用的备份并且愿意承担丢失数据的风险. 详见 Btrfs Wiki:从 Ext3 文件系统转换 .

从安装 CD 启动,然后转化分区:

# btrfs-convert /dev/partition

挂载转换后的分区并修改/etc/fstab文件,指定分区类型(type 为 btrfs,fs_passno [最后一列] 修改为0,Btrfs在启动时并不进行磁盘检查). 还要注意的是分区的UUID将有改变,所以使用UUID时,更新fstab中相应的条目。 chroot 到系统并重建 GRUB 条目(如果对此过程不熟悉,参考Install from existing LinuxGRUB). 如果正在转换根目录,还需要在 chroot 环境中重建初始化内存盘 (mkinitcpio -p linux). 如果 GRUB 不能启动 (例如 'unknown filesystem' 错误),则需要重新安装 (grub-install /dev/partition) 并生成配置文件 (grub-mkconfig -o /boot/grub/grub.cfg).

确认没有问题后,完成转换通过删除备份ext2_saved子卷,请注意,如果没了它(备份子卷),你将没办法还原回 ext3/4 文件系统。

# btrfs subvolume delete /ext2_saved

最后通过 balance 回收空间.

设置文件系统

写时复制 (CoW)

默认情况下 btrfs 对所有文件使用 写时复制 (CoW).参阅the Btrfs Sysadmin Guide section 获得技术细节.写时复制具有许多优点和缺点.

停用 CoW

要对某个子卷上的新文件停用写时复制,使用 nodatacow选项,注意这只会影响新文件,并不改变已有文件的写时复制属性.

为单文件或目录禁用CoW特性,请使用下面的命令:

# chattr +C [文件/目录的地址(path)]

这会为这个文件的单个引用停用写时复制,如果这个文件不只有一个引用(例如通过 cp --reflink=always 生成或者在文件系统快照中),写时复制依然生效.

This will disable copy-on-write for those operation in which there is only one reference to the file. If there is more than one reference (e.g. through cp --reflink=always or because of a filesystem snapshot), copy-on-write still occurs.

Note: 来自 chattr 的手册页:在btrfs上,'C' 标志应该被设置在新建的或者是空白的文件/目录,如果被设置在已有数据的文件,当块分配给该文件时,文件将不确定是否完全稳定。如果'C' 标志被设置给一个目录,将不会影响目前的目录,但在该目录创建的新文件将具有No_COW属性。
Tip: 可以用下面的方法为已存在的文件或目录停用写时复制:
$ mv /path/to/dir /path/to/dir_old
$ mkdir /path/to/dir
$ chattr +C /path/to/dir
$ cp -a /path/to/dir_old/* /path/to/dir
$ rm -rf /path/to/dir_old

需要保证这个过程中目标文件不会被使用,同时注意下面描述的 mvcp --reflink 并不起作用.

强制启用写时复制

如果复制的文件停用了写时复制,可以这样强制开启:

$ cp --reflink source dest 

参阅 cp 的手册页获得关于 --reflink 标志的更多信息.

压缩

Btrfs支持透明压缩,这意味着分区里的每个文件都被自动压缩。这不单减小了文件的大小,还提高了性能,特别是在使用lzo算法时。用compress=gzipcompress=lzo挂载选项打开压缩功能。只有在加入挂载选项后创建或修改的文件会被压缩,所以要充分利用压缩特性,最好安装时就启用压缩功能。

不过也可以在安装以后通过 btrfs filesystem defragment -calg (也可以使用其它压缩算法,例如 zlib / lzo) 压缩一个分区 (例如从 ext3/4 转换以后的文件系统).

要将整个文件系统通过 lzo 重新压缩,运行下面的命令:

# btrfs filesystem defragment -r -v -clzo /
Tip: 通过 chattr +c ,也可以在不使用 compress 选项的情况下为单个文件启用压缩属性.对目录启用会使这个目录下新文件自动压缩.

在一个新的 btrfs 分区上安装 Arch Linux 时,要充分利用压缩特性,最好安装时就启用压缩功能。在File systems 时使用 compress 参数: mount -o compress=lzo /dev/sdxY /mnt/.在 时把 compress=lzo 添加到 fstab 中的根目录中的选项上.

子卷

"btrfs 子卷不是 (也不能看作) 块设备,一个子卷可以看作 POSIX 文件名字空间.这个名字空间可以通过子卷上层访问,也可以独立挂载."[1]

每个 btrfs 文件系统都有一个 ID 为5的子卷.默认情况下它可以作为 / 挂载.

参阅下面的链接获得更多信息:

创建子卷

要创建一个子卷:

# btrfs subvolume create /path/to/subvolume

列出子卷列表

要列出当前路径 (path) 下的子卷:

# btrfs subvolume list -p path

删除子卷

要删除一个子卷:

# btrfs subvolume delete /path/to/subvolume

只是移除子卷的目录 /path/to/subvolume 而不使用这个命令并不会删除一个子卷.

挂载子卷

通过 subvol=/path/to/subvolume 或者 subvolid=objectid 挂载选项,子卷可以像文件系统一样挂载.例如创建一个名为 subvol_root 的子卷并挂载到 / 上.通过创建不同的子卷也可以用来模拟传统的文件系统,然后挂载到合适的位置.

Tip: 为了方便修改子卷,请考虑创建新的子卷,然后挂载它 (例如/) 而不是使用顶层子卷 (ID=5) 挂载为根目录.

参阅 Snapper#Suggested filesystem layout, Btrfs SysadminGuide#Managing SnapshotsBtrfs SysadminGuide#Layout 获得子卷应用的示例.

更改子卷的挂载选项

当以 subvol= 参数挂载子卷时,可以使用某些参数 (例如影响压缩和写时复制的参数).

参阅 Btrfs Wiki Mount optionsBtrfs Wiki Gotchas 获得更多信息. 作为正开发中的文件系统,不同的挂载选项可能会影响文件系统的性能.[[#另见|]] 一节中有一些评测文章可供参考.

Warning: 某些挂载选项可能会停用安全功能并增加损坏文件系统的风险.

改变默认子卷

如果挂载时不指定 subvol= 选项便会挂载默认子卷.要改变默认子卷:

# btrfs subvolume set-default subvolume-id /

subvolume-id 可以通过列出子卷列表[broken link: invalid section]获得.

Note: 在安装了 GRUB 的系统上,在改变默认子卷以后不要忘记运行 grub-install . 参见 this forum thread.
Warning: 如果对正挂载默认子卷的文件系统上使用 btrfs subvolume set-default 可能会导致其无法访问,参阅 Btrfs Wiki Sysadmin Guide.

Commit intervals setting

The resolution at which data are written to the filesystem is dictated by Btrfs itself and by system-wide settings. Btrfs defaults to a 30 seconds checkpoint interval in which new data are committed to the filesystem. This is tuneable using mount options (see below)

System-wide settings also affect commit intervals. They include the files under /proc/sys/vm/* and are out-of-scope of this wiki article. The kernel documentation for them resides in Documentation/sysctl/vm.txt.

Checkpoint 间隔

从 Linux 内核 3.12 开始,用户可以通过在 /etc/fstab 改变 commit 的值来改变 Checkpoint 周期 (默认是30秒).

LABEL=arch64 / btrfs defaults,noatime,ssd,compress=lzo,commit=120 0 0

SSD TRIM

在支持 TRIM 的固态硬盘上 btrfs 文件系统可以自动释放不使用的块.

Solid State Drives#TRIM 有关于使用 TRIM 的更多信息.

使用

显示已使用的/空闲空间

/usr/bin/df 这样的用户空间工具可能不会准确的计算剩余空间 (因为并没有分别计算文件和元数据的使用情况) .推荐使用 /usr/bin/btrfs 来查看使用情况. 下面的例子会同时使用 df -hbtrfs filesystem df.

$ df -h /
Filesystem      Size  Used Avail Use% Mounted on
/dev/sda3       119G  3.0G  116G   3% /
$ btrfs filesystem df /
Data: total=3.01GB, used=2.73GB
System: total=4.00MB, used=16.00KB
Metadata: total=1.01GB, used=181.83MB

注意到 df -h 报告使用了 3.0GB 但 btrfs filesystem df 报告数据使使用了 2.73GB . 这是因为 btrfs 将文件分配到池中,真正的已使用空间是三个 "Used" 的总和. (约等于 df -h 的结果) .

Note: 如果在 Linux 内核 版本3.15 以后的输出中看到了 unknown at kernel >= 3.15,这是个显示问题. (参阅 这个 patch,这是 GlobalReserve, 表示没有刷新的缓冲区 (在 RAID 分区上可能会看到 unknown, single) 而且无法重新 balance .

btrfs filesystem show 命令也可以使用,输出的信息更少:

# btrfs filesystem show /dev/sda3

btrfs filesystem usage 是新增加的命令:

# btrfs filesystem usage
Note: The btrfs filesystem usageRAID5/RAID6 设备上可能无法正常工作.

碎片整理

btrfs 支持在线碎片整理,要整理根文件夹:

# btrfs filesystem defragment /

并不会'整理整个文件系统参阅 Btrfs Wiki上的这个页面 获得更多信息.

要整理整个文件系统并观看冗长的输出:

# btrfs filesystem defragment -r -v /

Scrub

Btrfs Wiki 术语表中写到 scrub 是一种 "在线文件系统检查工具".它读取文件系统中的文件和元数据,并使用效验值和 RAID 存储上的镜像区分并修复损坏的数据.

# btrfs scrub start /
# btrfs scrub status /
Warning: 运行 scrub 会阻止系统待机, 详见 这个讨论.

btrfs-progs 软件包带有 btrfs-scrub@.timer 系统单元,用来每月运行 scrub 命令.通过添加挂载点的参数来启用它,例如btrfs-scrub@-.timer (/) 或者 btrfs-scrub@home.timer (/home).

也可以通过启动 btrfs-scrub@.service 来手动运行 scrub (使用同样的挂载点参数) ,相对于 # btrfs scrub 这么做的优点是会记录在 Systemd 日志中.

Balance

"balance passes all data in the filesystem through the allocator again. It is primarily intended to rebalance the data in the filesystem across the devices when a device is added or removed. A balance will regenerate missing copies for the redundant RAID levels, if a device has failed." [2] .

参阅 上游的 FAQ.

# btrfs balance start /
# btrfs balance status /

RAID

Btrfs 提供对 RAID 一类的 多设备文件系统[broken link: invalid section]的原生支持.参阅 the Btrfs wiki page 获得更多信息. Btrfs 管理员手册 提供了技术背景信息.

快照

"快照是和特定子卷共享文件和元数据的特殊子卷, 利用了 btrfs 的写时复制特性." 详见 Btrfs Wiki SysadminGuide#Snapshots.

要创建一个快照:

# btrfs subvolume snapshot source [dest/]name

加入 -r 参数可以创建一个只读快照. 为只读快照创建一个快照可以获得一个只读快照的可写入版本.

Note: 快照不是递归包含的,这意味着子卷内的子卷在快照里是空目录。

发送和接收

可以通过 send 命令发送一个快照,通常会与 btrfs 中的 receive 组成管道.例如将快照 /root_backup (也许是/的备份) 发送到 /backup:

 # btrfs send /root_backup | btrfs receive /backup

只能发送只读快照,上面的命令在将子卷复制到外部设备 (例如备份驱动器) 时会很有用.

也可以只发送两个快照间发生变化的部分,例如如果你已经发送了快照 root_backup ,然后又建立了一个新的只读快照 root_backup_new ,可以这样完成增量发送:

 # btrfs send -p /root_backup /root_backup_new | btrfs send /backup

现在你 /backup 的快照会是 root_backup_new.

参阅 Btrfs Wiki's Incremental Backup page 获得更多信息 (例如使用工具自动化这一过程)

局限性

使用前请了解如下局限。

加密

Btrfs 目前还没有内建的加密支持,但可以在运行mkfs.btrfs前加密分区,参阅Dm-crypt with LUKS.

(如果已经创建了文件系统,可以使用EncFSTrueCrypt,但是这样会无法使用 btrfs 的一些功能。)

交换文件

Btrfs 不支持交换文件,因为 Btrfs 因为潜在的文件系统损坏风险,没有加入交换文件需要的功能,参阅这里. 交换文件可以挂载到 loop 设备中,但是性能比较差。systemd-loop-swapfileAUR[broken link: archived in aur-mirror]提供了需要的服务文件。

Linux-rt 内核

在版本 3.14.12_rt9中, linux-rt 内核不能引导Btrfs文件系统,这是因为 rt 补丁集的开发相对缓慢导致的。

提示和技巧

参阅 Btrfs - Tips and tricks.

故障排除

参阅 Btrfs Problem FAQ 获得排除一般问题的信息.

GRUB

分区偏移

Note: 在试图将 core.img 嵌入到已经分区的磁盘上时可能会发生偏移问题. 这意味着可以把 corg.img 嵌入到 btrfs 池或是无分区磁盘 (例如/dev/sdX) 上.

Grub 2可以启动 Btrfs 分区,但是因为模块比较大, grub-install 安装的 core.img 文件超过了 MBR 与第一个分区之间的空间大小 (63 扇区/31.5KiB) .更新后的 fdiskgdisk 的磁盘工具会通过第一个分区前空出 1-2M 的空间避免此问题.

Missing root

如果启动 RAID 卷设备后编辑了 /usr/share/grub/grub-mkconfig_lib 移除了 echo " search --no-floppy --fs-uuid --set=root ${hints} ${fs_uuid}" 中的引号,可能会遇到 error no such device: root 问题,重新生成 GRUB 设置文件应该能避免这个问题.

BTRFS: open_ctree failed

2014 年 11 月的 systemdmkinitcpio 中的 bug 可能导致使用 mkinitcpio.confbtrfs hook 的用户启动多设备文件系统的 btrfs 卷时出现错误\:

BTRFS: open_ctree failed
mount: wrong fs type, bad option, bad superblock on /dev/sdb2, missing codepage or helper program, or other error

In some cases useful info is found in syslog - try dmesg|tail or so.

You are now being dropped into an emergency shell.

一个临时解决方案是从 HOOKS 中移除 btrfs 并把它放入 MODULES 中,通过 mkinitcpio -p linux 重新生成 initramfs 并重新启动.

参阅 原来的论坛讨论FS#42884 获得更多的信息和讨论.

另外如果在挂载 RAID 卷组时缺少某个卷时也有可能会发生这个错误.这种情况下你需要把 degraded 加入到 /etc/fstab 中,如果根目录在卷组上,同时需要加入 rootflags=degraded 内核参数

检查 btrfs 文件系统

Warning: btrfs (特别是btrfs check 命令)仍在开发阶段, 强烈建议在加上 --repair 参数运行 btrfs check 时做一个备份.

btrfs check 可以检查并修复一个未挂载的 btrfs 文件系统.但是由于它并未开发完成,它并不能修复某些错误 (即使这些错误没导致无法挂载).

参阅 Btrfsck 获得更多信息.

另见