Btrfs(通常念成Butter FS),由Oracle于2007年宣布并进行中的COW(copy-on-write式)文件系统。目标是取代Linux目前的ext3文件系统,改善ext3的限制,特别是单一文件大小的限制,总文件系统大小限制以及加入文件校验和特性。

特性:

首先是扩展性 (scalability) 相关的特性,btrfs 最重要的设计目标是应对大型机器对文件系统的扩展性要求。 Extent,B-Tree 和动态 inode 创建等特性保证了btrfs在大型机器上仍有卓越的表现,其整体性能而不会随着系统容量的增加而降低。

其次是数据一致性 (data integrity) 相关的特性。系统面临不可预料的硬件故障,Btrfs 采用 COW 事务技术来保证文件系统的一致性。 btrfs 还支持 checksum,避免了 silent corrupt 的出现。而传统文件系统则无法做到这一点。

第三是和多设备管理相关的特性。 Btrfs 支持创建快照 (snapshot),和克隆 (clone)  子卷(sub_volume)透明压缩。btrfs还能够方便的管理多个物理设备,使得传统的卷管理软件变得多余。

最后是其他难以归类的特性。这些特性都是比较先进的技术,能够显著提高文件系统的时间 / 空间性能,包括延迟分配,小文件的存储优化,目录索引等。

扩展性相关的特性

B-Tree

btrfs 文件系统中所有的 metadata 都由 B-Tree 管理。使用 B-Tree 的主要好处在于查找,插入和删除操作都很高效。可以说 B-Tree 是 btrfs 的核心。

一味地夸耀 B-Tree 很好很高效也许并不能让人信服,但假如稍微花费一点儿时间看看 ext2/3 中元数据管理的实现方式,便可以反衬出 B-Tree 的优点。(之前的博客文件系统详解有讲解ext系列的文件系统)。

基于 Extent 的文件存储

现代很多文件系统都采用了 extent 替代 block 来管理磁盘。 Extent 就是一些连续的 block,一个 extent 由起始的 block 加上长度进行定义,能有效地减少元数据开销。


centos7默认支持btrfs文件系统


文件系统创建:

btrfs文件系统支持诸多子命令:filesystem, device, balance, subvolume

管理子卷:

    btrfs subvolume create [-i <qgroupid>] [<dest>/]<name>    

    btrfs subvolume delete [options] <subvolume> [<subvolume>...]  

    btrfs subvolume list [options] [-G [+|-]value] [-C [+|-]value] [--sort=gen,ogen,rootid,path] <path>

    btrfs subvolume snapshot [-r] <source> <dest>|[<dest>/]<name>

    btrfs subvolume get-default <path>

    btrfs subvolume set-default <subvolid> <path>

    btrfs subvolume find-new <path> <lastgen>

    btrfs subvolume show <subvol-path>

管理B-tree文件系统:

    btrfs filesystem df <path>    显示B-tree文件系统空间大小

    btrfs filesystem show [options] [<path>|<uuid>|<device>|label] 显示已有B-tree文件系统

    btrfs filesystem sync <path> 做同步

    btrfs filesystem defragment [options] <file>|<dir> [<file>|<dir>...]

    btrfs filesystem resize [devid:][+/-]<newsize>[kKmMgGtTpPeE]|[devid:]max <path> 调整大小

    btrfs filesystem label [<device>|<mount_point>] [<newlabel>]  加卷标

管理物理卷的数据:

    btrfs [filesystem] balance start [options] <path>  文件系统平衡

    btrfs [filesystem] balance pause <path>

    btrfs [filesystem] balance cancel <path>

    btrfs [filesystem] balance resume <path>

    btrfs [filesystem] balance status [-v] <path>

管理设备:

    btrfs device add [options] <device> [<device>...] <path>  新增物理卷

    btrfs device delete <device> [<device>...] <path>  移除物理卷

    btrfs device scan [(-d|--all-devices)|<device> [<device>...]]

    btrfs device ready <device>

    btrfs device stats [-z] <path>|<device>

擦除数据:

    btrfs scrub start [-BdqrRf] [-c ioprio_class -n ioprio_classdata] <path>|<device>

    btrfs scrub cancel <path>|<device>

    btrfs scrub resume [-BdqrR] [-c ioprio_class -n ioprio_classdata] <path>|<device>

    btrfs scrub status [-dR] <path>|<device>


    btrfs check [options] <device>

紧急救援和修复:

    btrfs rescue chunk-recover [options] <device>

    btrfs rescue super-recover [options] <device>

……


  mkfs.btrfs

    -L 'LABEL'  指定卷标

    -d <type>: raid0, raid1, raid5, raid6, raid10, single  指明数据如何跨设备存放

    -m <profile>: raid0, raid1, raid5, raid6, raid10, single, dup 指明元数据存放

    -O <feature>  在格式化时直接开启哪些特性,需版本支持

    -O list-all: 列出支持的所有feature;


在虚拟机上添加4个硬盘并创建文件系统:(首先使用3个,第四个备用)

wKioL1XjDmXQ1msRAAD8uHt-BsM217.jpg

属性查看:

  btrfs filesystem show 

wKioL1XjDxXChXglAADNpimuQnY855.jpg

挂载文件系统:

   mount -t btrfs /dev/sdb MOUNT_POINT

wKioL1XjDuTC8BUMAAJu4poVVAk392.jpg

透明压缩机制:

     mount -o compress={lzo|zlib} DEVICE MOUNT_POINT

wKiom1XjDxaRWK5JAACaePP-xho287.jpg

动态空间:

wKioL1XjGJHT1Xk4AAJ3d_M3PAc099.jpg

wKioL1XjGM_i2n3yAAEYvLfD7XA571.jpg

wKioL1XjGYjRtYiuAAIFkZtkGkY541.jpg

添加物理设备:

wKioL1XjGdjgRMzzAAIon7RaMCY424.jpg

数据平衡:(由于本例为新建,所以可平衡数据很少)

wKiom1XjF_bzkGfjAACCnQQ6G-M069.jpg

移除物理设备:

wKiom1XjGIrgZ99KAAEshOM_98I116.jpg

btrfs直接支持raid,如改变元数据的存储级别为raid5:

wKioL1XjGt6zXTHqAABUzwpkWMk707.jpg

btrfs支持子卷:

wKiom1XjG-nydhCOAACEbQPoa5A620.jpg

list列出子卷的详细信息,show用来查看给定子卷的详细信息

创建一个/mydata下的子卷logs,chche,并尝试单独挂载logs到/mnt,显示详细信息:

wKiom1XjHATCyf8SAAIwi83c78U591.jpg

重新挂载到/mydata,文件还在:

wKioL1XjHiKxjYuVAABhoiQTm-8764.jpg

注:挂载父卷时子卷的数据可访问,如单独挂载子卷则父卷无法访问只能访问子卷

    挂载子卷还可以用mount subvolid="子卷id" "挂载位置" 的方式实现


子卷也可以删除:

wKiom1XjI6CACoVkAACiMo9TKEY645.jpg

子卷支持创建快照:(为了方便查看,先行复制部分数据)

wKioL1XjJz6hEVdIAAGKzKsD2vw361.jpg

修改原卷的数据,快照卷不会改变。

快照用完可以删除:

[root@localhost ~]# btrfs subvolume delete /mydata/logs_snapshot


B-tree文件系统还支持对单个文件快照:

[root@localhost logs]# cp --reflink grub2.cfg grub2.cfg_snap

改变原文件,快照文件不会改变


另外,可以把EXT文件系统转换为btrfs:

   首先卸载掉一个物理设备:

   wKioL1XjK0eRb6YZAAFUAE-IYHE429.jpg

  创建磁盘分区:

   wKioL1XjK83i5rZTAAH53vadS4g589.jpg

    [root@localhost mydata]# partx -a /dev/sdd

     [root@localhost mydata]# mke2fs -t ext4 /dev/sdd1  格式化

     [root@localhost mydata]# mount /dev/sdd1 /mnt    挂载

     [root@localhost mydata]# cp /etc/fstab /mnt/  复制一个文件留作验证

     卸载/dev/sdd1,可执行强制检测

    wKioL1XjLZnRCMTNAAEDFYLMtOk177.jpg

     执行转换:

     wKioL1XjLi3RRaDNAAGdwq2lPzw728.jpg

     新的文件系统已出现,挂载到/mnt下并查看:

     wKiom1XjLJmSNTtcAABWyQdvdtw956.jpg

     可以回滚:

     wKioL1XjL2Tg5k3iAAClSersugE096.jpg

     这就是在btrfs和EXT4文件系统实现无损转换。