Arch实战btrfs

其他Linux/Unix/BSD/OSX等发行版讨论
头像
sgsdxzy
帖子: 430
注册时间: 2008-07-19 11:14

Arch实战btrfs

#1

帖子 sgsdxzy » 2012-05-17 21:31

btrfs是linux下一代文件系统,由oracle、radhat、intel、suse等多个公司和社区研发,采用GPL协议发布(Linux Only),目前正逐步稳定下来。Arch的内核很新,也对btrfs提供了较好的支持,我尝试了一次全新的整个系统基于btrfs的安装,和大家分享一下心得。
首先,为什么我们要用btrfs?btrfs有很多吸引人的特性,比如:
1、类似lvm的多设备文件系统,目前支持raid0、raid1、raid10,预计在3.5内核中加入raid5/6的支持。
2、类似于ZFS的pool概念:一个分卷(volume)可以横跨多个物理分区,分卷内有subvolume共享volume的空间。比如为了重装能保留/home,你的/分了20G,/home分了60G,某天/不够用了,怎么办?btrfs可以把/和/home作为subvolume,共享剩余空间,同时在/遇到不可逆损坏时保持/home的完整性。不过有一个限制:btrfs上不能放置swap文件,会损坏文件系统。请使用独立的swap分区。
3、快照。btrfs能对任何subvolume进行快照,同时其copy-on-write的特性可以让多个快照引用同一个文件,当文件在一个快照中被修改时再复制一份储存在这个快照中,所以说,一个快照初始时几乎不占硬盘空间,随着系统使用快照和当前系统的差异越来越大,快照才占用越来越多的空间。
4、透明压缩。支持文件系统级的压缩,目前支持zlib和lzo两种算法,后续会加入snappy和lz4等。现在系统往往硬盘读取速度是瓶颈,牺牲一些CPU时间压缩数据而减少硬盘读写往往能提高整体效率。 测评:http://www.phoronix.com/scan.php?page=a ... 2638&num=1
5、设计时就考虑到了SSD的优化
我觉得以上是比较吸引桌面用户的地方,还有很多别的特性可见:https://btrfs.wiki.kernel.org/index.php/Main_Page 可以说,目前来看,除了ZFS的deduplication功能,btrfs是一个能和ZFS正面抗衡的linux文件系统。
上次由 sgsdxzy 在 2012-05-18 10:01,总共编辑 1 次。
头像
sgsdxzy
帖子: 430
注册时间: 2008-07-19 11:14

Re: Arch实战btrfs

#2

帖子 sgsdxzy » 2012-05-17 22:20

为了尝试btrfs,我在我的15G小硬盘上重装了系统。系统安装和别的大致无异,但要注意一下几个方面:1、选择软件包时,选上btrfs-progs 2、我要讲讲subvolume的意义:btrfs,顾名思义,Btree(二叉树)是文件系统组织方式。subvolume就是森林的根,标识一个subvolume有两个数据:名称和ID。建立文件系统后,会自动生成总树根,没有名称,ID为0。之后你可以在下面建立文件、文件夹和子树,文件夹和子树中又能包含别的文件、文件夹和子树。子树和文件夹的区别在于,子树能够用mount命令直挂载在到目录根部,也可以对其快照而文件夹不行。为了更好的扩展性与快照回滚能力,建议把/安装在一个新的subvolume而不是总树根上。很不幸,arch默认的安装脚本不能满足我们的要求,我们来手动安装arch。下面演示创建一个/、一个/home和一个pkg子树,并为了稳妥将/boot分在另一个独立的ext4分区上。为什么建这个pkg子树呢?因为可以对subvolume指定不同的挂载选项,像pkg里面全是压缩包,自然就不用透明压缩,所以不需要compress(很可惜,到3.3内核还没有支持不同subvolume使用不同的压缩选项,以后会改进,见:https://btrfs.wiki.kernel.org/index.php ... options.3F):
具体步骤可见:https://wiki.archlinux.org/index.php/In ... Btrfs_root,我想有意愿折腾btrfs的不会被手动安装arch难到。用mkfs.btrfs创建一个类型为btrfs的分区,挂载到/mnt。cd到/mnt,执行以下命令:

代码: 全选

btrfs subvolume create rootfs
btrfs subvolume create homefs
btrfs subvolume create pkg
之后用命令

代码: 全选

btrfs subvolume list /mnt
可以看到这样的结果:

代码: 全选

ID 256 top level 5 path rootfs
ID 260 top level 5 path homefs
ID 262 top level 5 path pkg
(我们的ID可能会不一样,以自己的为准)
三个subvolume建立完成!但是这样还不够,我们要按照结构挂载。btrfs的挂载选项也很有讲究,具体见:https://btrfs.wiki.kernel.org/index.php/Mount_options
执行:

代码: 全选

mount  -o remount,compress=lzo,space_cache,autodefrag /dev/sdaX /mnt
mkdir -p /mnt/rootfs/home /mnt/rootfs/var/cache/pacman/pkg /mnt/rootfs/dev /mnt/rootfs/proc /mnt/rootfs/sys
mkdir -p /mnt/rootfs/var/cache/pacman/pkg
mount  -o subvol=homefs,compress=lzo,space_cache,autodefrag /dev/sdaX /mnt/rootfs/home
mount  -o subvol=pkg,compress=lzo,space_cache,autodefrag /dev/sdaX /mnt/rootfs/var/cache/pacman/pkg
mount /dev/sdaY(ext4的boot分区) /mnt/rootfs/boot
subvol=<name>是指定挂载的subvol名称,也可以使用subvolid=ID。compress=lzo是在安装时就进行透明压缩,减小体积,提高性能。space_cache,autodefrag都是提高性能的选项。如果是ssd,可以加上ssd和discard。
然后到/mnt/rootfs/中,执行

代码: 全选

mount -o bind /dev dev/
mount -t proc /proc proc/
mount -t sysfs /sys sys/
最后来一步pacman -r . -Sy base grub2-bios --ignore grub 安装系统。我试过,grub1不能从subvolume中启动,syslinux我不熟,听说也有问题,所以推荐grub2。安装grub2不多说了,https://wiki.archlinux.org/index.php/GRUB2#Installation
之后就是/etc 中的设置了,按个人喜好,注意几个地方:
1、mkinitcpio的hook里加上btrfs,然后mkinitcpio -p linux重新生成镜像,不然多设备btrfs可能无法启动。会提示fsck.btrfs找不到,不用管,这个目前还没实现。
2、fstab要写好,我的是这样的:

代码: 全选

……
/dev/sda10 / btrfs subvolid=256,defaults,compress=lzo,space_cache,autodefrag  0 1
/dev/sda10 /home btrfs subvolid=260,defaults,compress=lzo,space_cache,autodefrag 0 1 
/dev/sda10 /var/cache/pacman/pkg/ btrfs subvolid=262,defaults,compress=lzo,space_cache,autodefrag 0 1
/dev/sda8 /boot ext4 defaults 0 1
/dev/sda9 swap swap defaults 0 0
……
3、/etc/default/grub里GRUB_CMDLINE_LINUX_DEFAULT="rootflags=subvolid=256"后生成grub.cfg。这是告诉内核启动时把subvolid=256当成/。以上所有用id的地方都可以用subvol=名称
设置好root密码--passwd root。然后你觉得差不多就可以重启了
上次由 sgsdxzy 在 2012-05-18 10:09,总共编辑 1 次。
头像
sgsdxzy
帖子: 430
注册时间: 2008-07-19 11:14

Re: Arch实战btrfs

#3

帖子 sgsdxzy » 2012-05-17 22:20

重启以后,按照自己的喜好配置系统吧!操作和别的文件系统完全一样。大家用df看看硬盘容量,一定会惊奇于大小的:我整个系统包括X、左面环境和日常软件一共只占了1.8G大小!大家肯定还有一个疑问:df显示的total != used+available,前者比后者大了1/8左右,这是为什么呢?还是来看挂载选项:
metadata_ratio=number
Sets the number of data chunks that need to be allocated to force a metadata chunk allocation. By default this is set to 8.
就是说,默认情况每分配8个data chunk会分配1个metadata chunk,所以那1/8是metadata的大小。难道说btrfs的硬盘利用率只有8/9?不用担心,btrfs会把能放进metadata chunk的小文件放在里面,所以那1/9的空间也是可以存储文件的!而命令

代码: 全选

btrfs filesystem balance
可以重新平衡文件分布,如果是raid,那么在多个设备上平衡负载;如果对单设备的metadata进行,就可以平衡小文件的分布。以后可能会自动后台进行metadata的balance。而且鉴于lzo平均2.08的压缩率,磁盘利用率会提高很多,尤其是对于大量的文本配置文件、源代码等。
再说一说snapshot这个吸引人的特性,snapshot就是依据现有的subvolume新建一个subvolume,有点像OO语言中的引用,对一个subvolume创建一个快照后,两者是平等的;一个文件有引用计数,可以在多个snapshot中被引用,或者由cp --reflink=always创建一个引用(目前cp的reflink不能做到跨subvolume引用,补丁还未合并),当引用数降为零时文件才被删除;和硬链接不同的是,当文件在一个快照中被修改时会新复制一份储存在这个快照中,而不会影响到别的引用,这就是copy-on-write。这样的快照能充分节省空间。我们来演示一下:
首先,我们要挂载总结点

代码: 全选

mount -o subvolid=0 /dev/sdaX /mnt
cd到/mnt,我们创建一个对于rootfs的快照:

代码: 全选

btrfs subvolume snapshot rootfs 20120516
建议:

代码: 全选

touch 20120516/This-is-snapshot-20120516
注意:btrfs的快照不具有递归性,即如果rootfs中还有二级subvolume,那么快照中不会包含二级subvolume的文件,而是包含一个对二级subvolume的引用,类似于这样:

代码: 全选

0----rootfs--------------------------------------------subvol2-----文件a
    |                     |                               ^
    |                     -----------文件夹b--文件c       |
    |                     ---文件d      ^        ^        |
    |                         ^         |        |        |
    |                         |         |        |        |
    --20120516---------------------------------------------
在rootfs中修改文件d、c会复制一份新的,对20120516不可见;而修改a的话在rootfs和20120516中都能看到。
所以为什么我们之前分了三个subvolume:
1、一般灾难都是/所致,所以不需要把/home也整个备份,而且/home中修改频繁,很容易创造大量新文件,占用空间;
2、能够对/home单独snapshot
3、pkg是pacman的包所在地,一般不需要备份。这样对rootfs快照后pkg不会被打进去,使用pacman -Scc后也不会因为20120516中仍有对其中软件包的引用而导致不能释放硬盘空间。

灾难恢复也变得很简单了,回滚到上一个/的状态,只要在开机时编辑grub菜单linux项里把rootflags=subvol=rootfs改成rootflags=subvol=20120516就回滚了。开机后如果你发现/下有刚才touch的文件This-is-snapshot-20120516,那么你就成功进入了快照中!
快照也是可读写的,所以对于/home的快照恢复不需要重新挂载一边,找个地方把/dev/sdaX挂上就能在里面把需要的文件cp出来。当然你想回滚整个/home的状态那么就改fstab好了。
定期创建和清理不需要的快照是个好习惯!清理快照能解除引用,释放你在当前系统中删除的文件的空间。对于重要文件,还是建议不要完全依赖快照,在别的文件系统或网络上留一个备份为好。
上次由 sgsdxzy 在 2012-05-18 11:21,总共编辑 2 次。
头像
sgsdxzy
帖子: 430
注册时间: 2008-07-19 11:14

Re: Arch实战btrfs

#4

帖子 sgsdxzy » 2012-05-17 22:21

最后说一下问题和修复的办法,我没有遇到过问题,就是摘录几个方法:
1、mount选项里的recovery会尝试找到上一次的节点,比如写入一个文件一半后断电,ext4下这个文件会损坏,而btrfs你可能会得到这个文件写入前的版本。所有没有执行flush的操作都会导致得到旧版本的文件。
2、btrfsck。btrfs有fsck,但是api和fsck.ext4等不同,所以还没有集成进去,mkinitcpio里也没有。建议在initramdisk里包含这个(mkinitcpio.conf的BINARY="btrfsck"),如果文件系统错误得挂载不了了,在ramfs里执行btrfsck /dev/sdaX
3、AUR里有一个mkinitcpio-btrfs,是方便回滚的脚本。我不太喜欢它的命名风格(当前/叫__active,我叫rootfs的,备份在__snapshot subvolume里,而我放在根节点下),所以我没用。经常回滚的可以参考一下。

还有几个提醒:
1、备份备份备份!光有回滚不能保证你的数据安全。
2、/boot是独立的,所以没有内核回滚能力,请自行备份内核。
3、(和2矛盾)如果用新版本内核提供的挂载选项挂载过btrfs文件系统,再用老版本内核可能会挂载出错!请仔细看挂载选项后表明的内核版本。

最后有一个疑问:为什么oracle要研发btrfs呢?当时sun的solaris和linux在服务器领域有竞争(我想他们不会认为bsd有和他们竞争的能力),sun的ZFS是一大法宝,而且采用CDDL发布,使Linux无法使用;oracle一方面闭源了ZFS,另一方面却开发GPL的btrfs,GPL意味着它不能将btrfs私有化。Oracle想什么呢?
上次由 sgsdxzy 在 2012-05-18 11:43,总共编辑 1 次。
头像
woodelf
帖子: 166
注册时间: 2010-05-25 10:26
系统: FreeBSD 9.1 amd64

Re: Arch实战btrfs

#5

帖子 woodelf » 2012-05-18 9:48

看我签名 :em09
BTW,LZ知不知道为何我用Slackware current,给/usr采用btrfs以后,每次启动都会运行fsck.btrfs。
公司的一台Arch也这死样子,还好是file not found fsck.btrfs :em04
/dev/ada1:Gentoo Linux+ZFS (GPT)
/dev/ada2:FreeBSD 9.1+ZFS (GPT)
头像
sgsdxzy
帖子: 430
注册时间: 2008-07-19 11:14

Re: Arch实战btrfs

#6

帖子 sgsdxzy » 2012-05-18 13:53

woodelf 写了:看我签名 :em09
BTW,LZ知不知道为何我用Slackware current,给/usr采用btrfs以后,每次启动都会运行fsck.btrfs。
公司的一台Arch也这死样子,还好是file not found fsck.btrfs :em04
把btrfsck改名为fsck.btrfs?我是把btrfsck打进ramfs里。
axlrose
帖子: 69
注册时间: 2007-02-11 15:58

Re: Arch实战btrfs

#7

帖子 axlrose » 2012-05-20 15:31

好文章
头像
ReiFFEXzyx
帖子: 1045
注册时间: 2010-08-14 13:13

Re: Arch实战btrfs

#9

帖子 ReiFFEXzyx » 2012-05-20 21:41

先收藏了,以后用得到 :em11
[fracting的大作]Wine使用中的一些常见误区
viewtopic.php?f=121&t=363147
顺便学习一下对待开源软件的正确态度
头像
cuihao
帖子: 4793
注册时间: 2008-07-24 11:33
来自: 郑州
联系:

Re: Arch实战btrfs

#10

帖子 cuihao » 2012-05-20 21:48

可以先用个脚本代替fsck.btrfs(直接link会有不支持-a的错误):

代码: 全选

#!/bin/sh

opts=""

for arg; do
    case "$arg" in
      -*)
        continue
      ;;
      *)
        opts="$opts $arg"
      ;;
    esac
done

exec /sbin/btrfsck $opts
就等于是放弃除了设备号之外的所有参数。
求人不如求它仨: 天蓝的Wiki 屎黄的Wiki 绿
Site: CUIHAO.TK    Twitter: @cuihaoleo
Machine: Athlon64 X2 5200+ / 2x2GB DDR2-800 / GeForce GTS 450
AD: ~まだ見ぬ誰かの笑顔のために~
头像
Gehaowu
帖子: 35
注册时间: 2009-07-16 15:53
系统: FreeBSD 10-CURRENT
来自: 浙江杭州
联系:

Re: Arch实战btrfs

#11

帖子 Gehaowu » 2012-06-25 18:27

sgsdxzy 写了: 最后有一个疑问:为什么oracle要研发btrfs呢?当时sun的solaris和linux在服务器领域有竞争(我想他们不会认为bsd有和他们竞争的能力),sun的ZFS是一大法宝,而且采用CDDL发布,使Linux无法使用;oracle一方面闭源了ZFS,另一方面却开发GPL的btrfs,GPL意味着它不能将btrfs私有化。Oracle想什么呢?

CDDL许可证发布的ZFS同样意味着Oracle不能私有化ZFS,

GPL的的Btrfs如果甲骨文愿意,后续版本同样可以闭源,
个人主页:https://www.7axu.com/ - GTalk:ghw@7axu.com
GnuPG Public Key: 368FDC55,89DC 1FF9 A639 B94E 2B43 C9BC 61C2 6E2C 368F DC55
jtshs256
帖子: 22323
注册时间: 2010-07-19 21:41
系统: OS X

Re: Arch实战btrfs

#12

帖子 jtshs256 » 2012-06-25 18:30

现在 native zfs on linux 似乎也实用了⋯⋯
躺平
detroy
帖子: 149
注册时间: 2012-02-25 10:58

Re: Arch实战btrfs

#13

帖子 detroy » 2012-06-27 9:15

btrfs还不够用,拿来玩的机器装一装无所谓,用来做事的机器最好还是用稳定的文件系统,比如XFS

当然,arch要折腾那是再合适不过,没有比它更合适的实验室了 :em09

ZFS从来不是拿给单机用的东东…… :em06
头像
雨坤毅
帖子: 232
注册时间: 2010-08-28 14:34
系统: ArchLinux
联系:

Re: Arch实战btrfs

#14

帖子 雨坤毅 » 2012-06-27 9:33

哥用btrfs一天就出现问题
文件系统错误,有一个目录没法删除,btrfs报了一堆的错误了。然后挂掉。。。。。
---------------------------------------
http://yky.me
---------------------------------------
头像
sgsdxzy
帖子: 430
注册时间: 2008-07-19 11:14

Re: Arch实战btrfs

#15

帖子 sgsdxzy » 2012-06-27 11:14

Gehaowu 写了:
sgsdxzy 写了: 最后有一个疑问:为什么oracle要研发btrfs呢?当时sun的solaris和linux在服务器领域有竞争(我想他们不会认为bsd有和他们竞争的能力),sun的ZFS是一大法宝,而且采用CDDL发布,使Linux无法使用;oracle一方面闭源了ZFS,另一方面却开发GPL的btrfs,GPL意味着它不能将btrfs私有化。Oracle想什么呢?

CDDL许可证发布的ZFS同样意味着Oracle不能私有化ZFS,

GPL的的Btrfs如果甲骨文愿意,后续版本同样可以闭源,
我好奇的是oracle为什么不移植zfs到linux而是重新写了btrfs。oracle是zfs的作者,有权利修改发布协议。
由于法律上的不溯既往,之前开源的zfs仍能被别人按照cddl使用。现在*bsd用的zfs是社区版本,基于最后一个开源的zfs。solaris的zfs已经闭源。
GPL要闭源需要所有作者同意,由于redhat、intel、富士通等很多公司都有代码,所以Oracle不能闭源GPL的btrfs,除非他把其中别人的代码都剔除。
回复