Linux Btrfs 文件系统

1、Btrfs文件系统简介

文件系统似乎是内核中比较稳定的部分,多年来,人们一直使用ext2/3,ext文件系统以其卓越的稳定性成为了事实上的Linux标准文件系统。近年来ext2/3暴露出了一些扩展性问题,于是便催生了ext4。在2008年发布的Linux 2.6.19内核中集成了ext4的dev版本。2.6.28内核发布时,ext4结束了开发版,开始接受用户的使用。似乎ext就将成为Linux文件系统的代名词。然而当阅读很多有关ext4的文章时,会发现都不约而同地提到了btrfs,并认为ext4将是一个过渡的文件系统。ext4的作者Theodore Tso也盛赞btrfs,并认为btrfs将成为下一代Linux标准文件系统。Oracle,IBM,Intel等厂商也对btrfs表现出了极大的关注,投入了资金和人力。
Btrfs(B-tree, Butter FS, Better FS)是一种遵循GPL协定的文件系统,由Oracle公司于2007年发布,它的最突出特点是CoW(写时复制)。

2、Btrfs文件系统的核心特性

(1)扩展性
Btrfs最重要的设计目标是应对大型机器对文件系统的扩展性要求。Extent、B-Tree和动态inode创建等特性保证了btrfs在大型机器上仍有卓越的表现,其整体性能不会随着系统容量的增加而降低。
(2)数据一致性(data integrity)
系统面临不可预料的硬件故障,Btrfs采用写时复制更新机制(CoW)事务技术来保证文件系统的一致性。Btrfs还支持checksum,避免了silent corrupt的出现,而传统文件系统则无法做到这一点。
写时复制机制(CoW):复制、更新及替换指针,而非“就地”更新。
数据及元数据校验码:checksum,校验数据及元数据是否损坏。
多物理卷支持:btrfs可由多个底层物理卷组成,支持RAID,以及联机添加、移除,修改。
(3)多设备管理
Btrfs支持创建快照(snapshot)和克隆(clone)。Btrfs还能够方便的管理多个物理设备,使得传统的卷管理软件变得多余。
(4)高效性
Btrfs能够显著提高文件系统的时间/空间性能,包括延迟分配、小文件的存储优化、目录索引等。

3、扩展性相关的特性

Btrfs文件系统中所有的metadata都由BTree管理。使用BTree的主要好处在于查找、插入和删除操作都很高效。可以说BTree是Btrfs的核心。
一味地夸耀BTree很好很高效也许并不能让人信服,但假如稍微花费一点儿时间看看ext2/3中元数据管理的实现方式,便可以反衬出BTree的优点。、
妨碍ext2/3扩展性的一个问题来自其目录的组织方式。目录是一种特殊的文件,在ext2/3中其内容是一张线性表格。如下图所示。这种结构在文件个数有限的情况下是比较直观的设计,但随着目录下文件数的增加,查找文件的时间将线性增长。2003年,ext3设计者开发了目录索引技术,解决了这个问题。目录索引使用的数据结构就是BTree。如果同一目录下的文件数超过2K,inode中的i_data域指向一个特殊的block。在该block中存储着目录索引BTree。BTree的查找效率高于线性表,但为同一个元数据设计两种数据结构总是不太优雅。在文件系统中还有很多其他的元数据,用统一的BTree管理是非常简单而优美的设计。

Btrfs内部所有的元数据都采用BTree管理,拥有良好的可扩展性。Btrfs内部不同的元数据由不同的Tree管理。在superblock中,有指针指向这些BTree的根。如下图所示。

FS Tree管理文件相关的元数据,如inode,dir等;Chunk tree管理设备,每一个磁盘设备都在Chunk Tree中有一个item;Extent Tree管理磁盘空间分配,btrfs每分配一段磁盘空间,便将该磁盘空间的信息插入到Extent Tree。查询Extent Tree将得到空闲的磁盘空间信息;Tree of tree root保存很多BTree的根节点。比如用户每建立一个快照,Btrfs便会创建一个FS Tree。为了管理所有的树,Btrfs采用Tree of tree root来保存所有树的根节点:checksum Tree保存数据块的校验和。

4、基于Extent的文件存储

现代很多文件系统都采用了extent替代block来管理磁盘。Extent就是一些连续的block,一个extent由起始的block加上长度进行定义。
Extent能有效减少元数据开销。为了进一步理解这个问题,我们还是看看ext2中的反面例子。ext2/3以block为基本单位,将磁盘划分为多个block。为了管理磁盘空间,文件系统需要知道哪些block是空闲的。Ext使用bitmap来达到这个目的。Bitmap中的每一个bit对应磁盘上的一个block,当相应block被分配后,bitmap中的相应bit被设置为1。这是很经典也很清晰的一个设计,但不幸的是当磁盘容量变大时,bitmap自身所占用的空间也将变大。这就导致了扩展性问题,随着存储设备容量的增加,bitmap这个元数据所占用的空间也随之增加。而人们希望无论磁盘容量如何增加,元数据不应该随之线性增加,这样的设计才具有可扩展性。
下图比较了block和extent的区别:

在ext2/3中,10个block需要10个bit来表示,在btrfs中则只需要一个元数据。对于大文件,extent表现出了更加优异的管理性能。
Extent是Btrfs管理磁盘空间的最小单位,由extent tree管理。Btrfs分配data或metadata都需要查询extent tree以便获得空闲空间的信息。

5、动态inode分配

为了理解动态inode分配,还是需要借助ext2/3。ext2文件系统的最大文件数量限制=文件系统空间大小/8192,比如100G大小的文件系统中,能创建的文件个数最大为131072。
下图显示了ext2的磁盘布局。

在ext2中inode区是被预先固定分配的,且大小固定,比如一个100G的分区中,inode table区中只能存放131072个inode,这就意味着不可能创建超过131072个文件,因为每一个文件都必须有一个唯一的inode。
为了解决这个问题,必须动态分配inode。每一个inode只是BTree中的一个节点,用户可以无限制地任意插入新的inode,其物理存储位置是动态分配的。所以btrfs没有对文件个数的限制。
针对SSD的优化支持
SSD是固态存储Solid State Disk的简称。在过去的几十年中,CPU/RAM等器件的发展始终遵循着摩尔定律,但硬盘HDD的读写速率却始终没有飞跃式的发展。磁盘IO始终是系统性能的瓶颈。
SSD采用flash memory技术,内部没有磁盘磁头等机械装置,读写速率大幅度提升。flash memory有一些不同于HDD的特性。flash在写数据之前必须先执行擦除操作;其次,flash对擦除操作的次数有一定的限制,在目前的技术水平下,对同一个数据单元最多能进行约100万次擦除操作,因此,为了延长flash的寿命,应该将写操作平均到整个flash上。
SSD在硬件内部的微代码中实现了wear leveling等分布写操作的技术,因此系统无须再使用特殊的MTD驱动和FTL层。虽然SSD在硬件层面做了很多努力,但毕竟还是有限。文件系统针对SSD的特性做优化不仅能提高SSD的使用寿命,而且能提高读写性能。Btrfs是少数专门对SSD进行优化的文件系统。btrfs用户可以使用mount参数打开对SSD的特殊优化处理。
Btrfs的COW技术从根本上避免了对同一个物理单元的反复写操作。如果用户打开了SSD优化选项,btrfs将在底层的块空间分配策略上进行优化:将多次磁盘空间分配请求聚合成一个大小为2M的连续的块。大块连续地址的IO能够让固化在SSD内部的微代码更好的进行读写优化,从而提高IO性能。

6、数据一致性相关的特性

(1)COW事务
理解COW事务,必须首先理解COW和事务这两个术语。
什么是COW?所谓COW,即每次写磁盘数据时,先将更新数据写入一个新的block,当新数据写入成功之后,再更新相关的数据结构指向新block。
什么是事务?COW只能保证单一数据更新的原子性。但文件系统中很多操作需要更新多个不同的元数据,比如创建文件需要修改以下这些元数据:

  1. 修改extent tree,分配一段磁盘空间。
  2. 创建一个新的inode,并插入FS Tree中。
  3. 增加一个目录项,插入到FS Tree中。

任何一个步骤出错,文件便不能创建成功,因此可以定义为一个事务。
下面将演示一个COW事务。
A是FS Tree的根节点,新的inode的信息将被插入节点C。首先,btrfs将inode插入一个新分配的block C’中,并修改上层节点B,使其指向新的block C’;修改B也将引发COW,以此类推,引发一个连锁反应,直到最顶层的Root A。当整个过程结束后,新节点A’变成了FS Tree的根。但此时事务并未结束,superblock依然指向A。

接下来,修改目录项(E节点),同样引发这一过程,从而生成新的根节点A’’。

此时,inode和目录项都已经写入磁盘,可以认为事务已经结束。btrfs修改superblock,使其指向A’’。如下图所示。

COW事务能够保证文件系统的一致性,并且系统reboot之后不需要执行fsck。因为superblock要么指向新的A’’,要么指向A,无论哪个都是一致的数据。
(2)Checksum
Checksum技术保证了数据的可靠性,避免silent corruption现象。由于硬件原因,从磁盘上读出的数据会出错。比如block A中存放的数据为0x55,但读取出来的数据变成0x54,因为读取操作并未报错,所以这种错误不能被上层软件所察觉。
解决这个问题的方法是保存数据的校验和,在读取数据后检查校验和。如果不符合,便知道数据出现了错误。ext2/3没有校验和,对磁盘完全信任。而不幸的是,磁盘的错误始终存在,不仅发生在廉价的IDE硬盘上,昂贵的RAID也存在silent corruption问题。而且随着存储网络的发展,即使数据从磁盘读出正确,也很难确保能够安全地穿越网络设备。
btrfs在读取数据的同时会读取其相应的checksum。如果最终从磁盘读取出来的数据和checksum不相同,btrfs会首先尝试读取数据的镜像备份,如果数据没有镜像备份,btrfs将返回错误。写入磁盘数据之前,btrfs计算数据的checksum。然后将checksum和数据同时写入磁盘。
Btrfs采用单独的checksum Tree来管理数据块的校验和,把checksum和checksum所保存的数据块分离开,从而提供了更严格的保护。假如在每个数据block的header中加入一个域保存checksum,那么这个数据block就成为一个自己保护自己的结构。这种结构下有一种错误无法检测出来,比如本来文件系统打算从磁盘上读block A,但返回了block B,由于checksum在block内部,因此checksum依旧是正确的。btrfs采用checksum tree来保存数据块的checksum,避免了上述问题。
Btrfs采用CRC32算法计算checksum,在将来的开发中会支持其他类型的校验算法。为了提高效率,btrfs将写数据和checksum的工作分别用不同的内核线程并行执行。

7、多设备管理相关的特性

每个Unix管理员都曾面临为用户和各种应用分配磁盘空间的任务。多数情况下,人们无法事先准确地估计一个用户或者应用在未来究竟需要多少磁盘空间。磁盘空间被用尽的情况经常发生,此时人们不得不试图增加文件系统空间。传统的ext2/3无法应付这种需求。
很多卷管理软件被设计出来满足用户对多设备管理的需求,比如LVM。Btrfs集成了卷管理软件的功能,一方面简化了用户命令,另一方面提高了效率。
(1)多设备管理
Btrfs支持动态添加设备。用户在系统中增加新的磁盘之后,可以使用btrfs的命令将该设备添加到文件系统中。为了灵活利用设备空间,Btrfs将磁盘空间划分为多个chunk。每个chunk可以使用不同的磁盘空间分配策略。比如某些chunk只存放metadata,某些chunk只存放数据,一些chunk可以配置为mirror,而另一些chunk则可以配置为stripe。这为用户提供了非常灵活的配置可能性。
(2)Subvolume
Subvolume是很优雅的一个概念。即把文件系统的一部分配置为一个完整的子文件系统,称之为subvolume。采用subvolume,一个大的文件系统可以被划分为多个子文件系统,这些子文件系统共享底层的设备空间,在需要磁盘空间时便从底层设备中分配,类似的应用程序调用malloc()分配内存一样。可以称之为存储池。这种模型有很多优点,比如可以充分利用disk的带宽,可以简化磁盘空间的管理等。
所谓充分利用disk的带宽,指文件系统可以并行读写底层的多个disk,这是因为每个文件系统都可以访问所有的disk。传统的文件系统不能共享底层的disk设备,无论是物理的还是逻辑的,因此无法做到并行读写。
所谓简化管理,是相对于LVM等卷管理软件而言。采用存储池模型,每个文件系统的大小都可以自动调节。而使用LVM,如果一个文件系统的空间不够了,该文件系统并不能自动使用其他磁盘设备上的空闲空间,而必须使用LVM的管理命令手动调节。
Subvolume可以作为根目录挂载到任意mount点。subvolume是非常有趣的一个特性,有很多应用。假如管理员只希望某些用户访问文件系统的一部分,比如希望用户只能访问/var/test/下面的所有内容,而不能访问/var下面的其他内容,那么便可以将/var/test做成一个subvolume。/var/test这个subvolume便是一个完整的文件系统,可以用mount命令挂载。比如挂载到/test目录下,给用户访问/test的权限,那么用户便只能访问/var/test下面的内容了。
(3)快照和克隆
快照是对文件系统某一时刻的完全备份。建立快照之后,对文件系统的修改不会影响快照中的内容。这是非常有用的一种技术。比如数据库备份。假如在时间点T1,管理员决定对数据库进行备份,那么他必须先停止数据库。备份文件是非常耗时的操作,假如在备份过程中某个应用程序修改了数据库的内容,那么将无法得到一个一致性的备份。因此在备份过程中数据库服务必须停止,对于某些关键应用这是不能允许的。
利用快照,管理员可以在时间点T1将数据库停止,对系统建立一个快照。这个过程一般只需要几秒钟,然后就可以立即重新恢复数据库服务。此后在任何时候,管理员都可以对快照的内容进行备份操作,而此时用户对数据库的修改不会影响快照中的内容。当备份完成,管理员便可以删除快照,释放磁盘空间。Btrfs支持快照的快照,即增量快照机制。
快照一般是只读的,当系统支持可写快照,那么这种可写快照便被称为克隆。克隆技术也有很多应用。比如在一个系统中安装好基本的软件,然后为不同的用户做不同的克隆,每个用户使用自己的克隆而不会影响其他用户的磁盘空间。非常类似于虚拟机。
Btrfs支持snapshot和clone。这个特性极大地增加了btrfs的使用范围,用户不需要购买和安装昂贵并且使用复杂的卷管理软件。下面简要介绍一下btrfs实现快照的基本原理。
如前所述Btrfs采用COW事务技术,COW事务结束后,如果不删除原来的节点A,C,E,那么A,C,E,D,F依然完整的表示着事务开始之前的文件系统。这就是snapshot实现的基本原理。
Btrfs采用引用计数决定是否在事务commit之后删除原有节点。对每一个节点,btrfs维护一个引用计数。当该节点被别的节点引用时,该计数加一,当该节点不再被别的节点引用时,该计数减一。当引用计数归零时,该节点被删除。对于普通的Tree Root,引用计数在创建时被加一,因为Superblock会引用这个Root block。很明显,初始情况下这棵树中的所有其他节点的引用计数都为1。当COW事务commit时,superblock被修改指向新的Root A’’,原来Root block A的引用计数被减1,变为零,因此节点A被删除。A节点的删除会引发其子孙节点的引用计数也减1,其中的B,C节点的引用计数因此也变成了0,从而被删除。D,E节点在COW时,因为被A‘’所引用,计数器加一,因此计数器这时并未归零,从而没有被删除。
创建snapshot时,btrfs将Root A节点复制到sA,并将sA的引用计数设置为2。在事务commit的时候,sA节点的引用计数不会归零,从而不会被删除,因此用户可以继续通过Root sA访问snapshot中的文件。

(4)软件RAID
RAID技术有很多非常吸引人的特性,比如用户可以将多个廉价的IDE磁盘组合为RAID0阵列,从而变成了一个大容量的磁盘。RAID1和更高级的RAID配置还提供了数据冗余保护,从而使得存储在磁盘中的数据更加安全。
Btrfs很好的支持了软件RAID,RAID种类包括RAID0,RAID1和RAID10。Btrfs缺省情况下对metadata进行RAID1保护。前面已经提及btrfs将设备空间划分为chunk,一些chunk被配置为metadata,即只存储metadata。对于这类chunk,btrfs将chunk分成两个条带,写metadata的时候,会同时写入两个条带内,从而实现对metadata的保护。

8、其他特性

在Btrfs的主页上罗列的其他特性不容易分类,这些特性都是现代文件系统中比较先进的技术,能够提高文件系统的时间或空间效率。
(1)Delay allocation
延迟分配技术能够减少磁盘碎片。在Linux内核中,为了提高效率,很多操作都会延迟。在文件系统中,小块空间频繁的分配和释放会造成碎片。延迟分配是这样一种技术,当用户需要磁盘空间时,先将数据保存在内存中,并将磁盘分配需求发送给磁盘空间分配器,磁盘空间分配器并不立即分配真正的磁盘空间,只是记录下这个请求便返回。
磁盘空间分配请求可能很频繁,所以在延迟分配的一段时间内,磁盘分配器可以收到很多的分配请求,一些请求也许可以合并,一些请求在这段延迟期间甚至可能被取消。通过这样的等待,往往能够减少不必要的分配,也有可能将多个小的分配请求合并为一个大的请求,从而提高IO效率。
(2)Inline file
系统中往往存在大量的小文件,比如几百个字节或者更小。如果为其分配单独的数据block,便会引起内部碎片,浪费磁盘空间。btrfs将小文件的内容保存在元数据中,不再额外分配存放文件数据的磁盘块。改善了内部碎片问题,也增加了文件的访问效率。

上图显示了一个BTree的叶子节点。叶子中有两个extent data item元数据,分别用来表示文件file1和file2所使用的磁盘空间。
假设file1的大小仅为15个字节,file2的大小为1M。如图所示,file2采用普通的extent表示方法,extent2元数据指向一段extent,大小为1M,其内容便是file2文件的内容。
而对于file1,btrfs会把其文件内容内嵌到元数据extent1中。如果不采用inline file技术。如虚线所示,extent1指向一个最小的extent,即一个block,但file1有15个字节,其余的空间便成为了碎片空间。
采用inline技术,读取file1时只需要读取元数据block,而无需先读取extent1这个元数据,再读取真正存放文件内容的block,从而减少了磁盘IO。
得益于inline file技术,btrfs处理小文件的效率非常高,也避免了磁盘碎片问题。
(3)目录索引Directory index
当一个目录下的文件数目巨大时,目录索引可以显著提高文件搜索时间。Btrfs本身采用BTree存储目录项,所以在给定目录下搜索文件的效率是非常高的。然而,btrfs使用BTree管理目录项的方式无法同时满足readdir的需求。readdir是POSIX标准API,它要求返回指定目录下的所有文件,并且这些文件要按照inode number排序。而btrfs目录项插入BTree时的Key并不是inode number,而是根据文件名计算的一个hash值。这种方式在查找一个特定文件时非常高效,但却不适于readdir。为此,btrfs在每次创建新的文件时,除了插入以hash值为Key的目录项外,还同时插入另外一种目录项索引,该目录项索引的Key以sequence number作为BTree的键值。这个sequence number在每次创建新文件时线性增加。因为inode number也是每次创建新文件时增加的,所以sequence number和inode number的顺序相同。以这种sequence number作为Key在BTree中查找便可以方便的得到一个以inode number排序的文件列表。
另外,以sequence number排序的文件往往在磁盘上的位置也是相邻的,所以,以sequence number为序访问大量文件会获得更好的IO效率。
(4)压缩
大家都曾使用过zip,winrar等压缩软件,将一个大文件进行压缩可以有效节约磁盘空间,Btrfs内置了压缩功能。通常人们认为将数据写入磁盘之前进行压缩会占用很多的CPU计算时间,必然降低文件系统的读写效率。但随着硬件技术的发展,CPU处理时间和磁盘IO时间的差距不断加大。在某些情况下,花费一定的CPU时间和一些内存,但却能大大节约磁盘IO的数量,这反而能够增加整体的效率。
比如一个文件不经过压缩的情况下需要100次磁盘IO。但花费少量CPU时间进行压缩后,只需要10次磁盘IO就可以将压缩后的文件写入磁盘。在这种情况下,IO效率反而提高了。当然,这取决于压缩率。目前btrfs采用zlib提供的DEFALTE/INFLATE算法进行压缩和解压。在将来,btrfs应该可以支持更多的压缩算法,满足不同用户的不同需求。
目前btrfs的压缩特性还存在一些不足,当压缩使能后,整个文件系统下的所有文件都将被压缩,但用户可能需要更细粒度的控制,比如针对不同的目录采用不同的压缩算法,或者禁止压缩。
对于某些类型的文件,比如jpeg文件,已经无法再进行压缩,尝试对其压缩将纯粹浪费CPU。为此,当对某文件的若干个block压缩后发现压缩率不佳,btrfs将不会再对文件的其余部分进行压缩操作。这个特性在某种程度上提高了文件系统的IO效率。
Btrfs支持透明压缩,即保存时自动压缩,读取时自动解压缩,该特性节省空间,但消耗更多的CPU时间。
(5)预分配
很多应用程序有预先分配磁盘空间的需要。他们可以通过posix_fallocate接口告诉文件系统在磁盘上预留一部分空间,但暂时并不写入数据。如果底层文件系统不支持fallocate,那么应用程序只有使用write预先写一些无用信息以便为自己预留足够的磁盘空间。
由文件系统来支持预留空间,更加有效,而且能够减少磁盘碎片,因为所有的空间都是一次分配,因而更有可能使用连续的空间。Btrfs支持posix_fallocate。
(6)缺点
Btrfs也有一个重要的缺点,当BTree中某个节点出现错误时,文件系统将失去该节点之下的所有的文件信息。而ext2/3却避免了这种被称为“错误扩散”的问题。

9、Btrfs文件系统的使用

(1)btrfs文件系统创建
mkfs.btrfs
-L ‘LABEL’
-d:raid0, raid1, raid5, raid6, raid10, single:数据如何实现跨多设备存放;
-m:raid0, raid1, raid5, raid6, raid10, single, dup(此为放两份),元数据如何实现跨多设备存放;
-O
-O list-all:列出支持的所有feature;

mkfs.btrfs -O list-all
mkfs.btrfs -L mydata /dev/sdb /dev/sdc

示例:在设备sda5上建立一个btrfs文件系统,并将其挂载到/btrfsdisk目录下。

# mkfs.btrfs /dev/sda5
# mkdir /btrfsdisk
# mount -t btrfs /dev/sda5 /btrfsdisk

mkfs.btrfs参数如下:
Nodesize和leafsize用来设定btrfs内部BTree节点的大小,缺省为一个page大小。但用户可以使用更大的节点,以便增加fanout,减小树的高度。
Alloc-start参数用来指定文件系统在磁盘设备上的起始地址,这使得用户可以方便的预留磁盘前面的一些特殊空间。
Byte-count参数设定文件系统的大小,用户可以只使用设备的一部分空间,当空间不足时再增加文件系统大小。
(2)属性查看
btrfs filesystem show
btrfs filesystem show --mounted:显示挂载的文件系统;
btrfs filesystem show --all-devices:显示该文件系统下的所有设备;
btrfs filesystem show /dev/sdb:通过硬件设备显示该文件系统的信息;
btrfs filesystem df:查看一个已挂载的btrfs文件系统空间使用情况;
btrfs filesystem label /dev/sdb:显示卷标;
mount -t btrfs /dev/sdb MOUNT_POINT:挂载文件系统
在线联机调整文件系统大小:
btrfs filesystem resize -10G /mydata
btrfs filesystem df /mydata
df -lh
btrfs filesystem resize max /mydata:直接将文件系统大小调整为最大;
透明压缩机制:mount -o compress={lzo|zlib} DEVICE MOUNT_POINT
lzo和zlib为两种压缩算法,例如:mount -o compress=lzo /dev/sdb /mydata
(3)子命令:filesystem, device, balance, subvolume
btrfs device add /dev/sdd /mydata:向文件系统中添加设备/dev/sdd,挂载点/mydata;
btrfs balance start/pause/resume(继续) /mydata:启动/暂停/继续btrfs文件系统的balance;
btrfs balance status /mydata:查看挂载点/mydata中btrfs的状态;
btrfs device delete /dev/sdb /mydata:联机拆除设备,从btrfs文件系统中删除设备/dev/sdb,挂载点为/mydata(其中数据先移动再删除);
btrfs balance start -mconvert=raid5 /mydata:btrfs文件系统的元数据块转换为RAID5格式(至少3块硬盘);
btrfs subvolume list /mydata:列出btrfs文件系统上的所有子卷信息;
btrfs subvolume create /mydata/logs:创建子卷;
btrfs subvolume list /:列出btrfs文件系统的根下的内容;
mount -o subvol=logs /dev/sdb /mnt:子卷挂载,挂载设备/dev/sdb,挂载到/mnt目录下;
btrfs subvolume show /mnt:查看/mnt子卷的详细信息;
mount -o subvolid= /dev/sdb /mnt:通过子卷ID挂载子卷;
btrfs subvolume delete /mydata/logs:删除子卷;
btrfs subvolume snapshot /mydata/logs /mydata/logs_snapshot:子卷的快照必须与子卷在同一个父卷中;
btrfs subvolume delete /mydata/logs_snapshot:删除快照卷;
cp --reflink grub2.cfg grub2.cfg_snap:创建文件的快照,文件与文件的快照需在同一卷下;
btrfs-convert /dev/sdd1:将ext格式转换为btrfs格式文件系统(无损转换);
btrfs-convert -r /dev/sdd1:将btrfs格式转换为ext格式文件系统(无损转换,-rollback)。
(4)修改文件系统的大小
当文件系统建立好之后,可以修改文件系统的大小。/dev/sda5挂载到了/btrfsdisk下,大小为800M。假如希望只使用其中的500M,则需要减小当前文件系统的大小,这可以通过如下命令实现:

[root@localhost ~]# df
Filesystem       1K-blocks          Used          Available           Use%            Mounted on
/dev/sda1        101086             19000         76867               20%             /boot
/dev/sda5        811248             32            811216              1%              /btrfsdisk
[root@localhost ~]# btrfsctl -r -300M /btrfsdisk
[root@localhost ~]# df
Filesystem       1K-blocks          Used          Available           Use%            Mounted on
/dev/sda1        101086             19000         76867               20%             /boot
/dev/sda5        504148             32            504106              1%              /btrfsdisk

也可以使用btrfsctl命令增加文件系统的大小。
(5)创建snapshot

[root@localhost ~]# ls /btrfsdisk
test1  tes2
[root@localhost btrfsdisk]# vim test1
This is a test
[root@localhost btrfsdisk]# btrfsctl -s snap1 /btrfsdisk
[root@localhost btrfsdisk]# vim test1
Test1 is modified
[root@localhost ~]# cd /btrfsdisk/snap1
[root@localhost snap1]# cat test1
This is a test

快照snap1保存的内容不会被后续的写操作所改变。
(6)创建subvolume
使用btrfs命令,用户可以方便的建立subvolume。假设/btrfsdisk已经挂载到了btrfs文件系统,则用户可以在这个文件系统内创建新的subvolume。比如建立一个/sub1的subvolume,并将sub1挂载到/mnt/test下。

[root@localhost ~]# mkdir /mnt/test
[root@localhost ~]# btrfsctl -S sub1 /btrfsdisk
[root@localhost ~]# mount -t btrfs -o subvol=sub1 /dev/sda5 /mnt/test

Subvolme可以方便管理员在文件系统上创建不同用途的子文件系统,并对其进行一些特殊的配置,比如有些目录下的文件关注节约磁盘空间,因此需要打开压缩,或者配置不同的RAID策略。
(7)创建RAID
mkfs的时候,可以指定多个设备,并配置RAID。下面的命令演示了如何使用mkfs.btrfs配置RAID1。sda6和sda7可以配置为RAID1,即mirror。用户可以选择将数据配置为RAID1,也可以选择将元数据配置为RAID1。
将数据配置为RAID1,可以使用mkfs.btrfs的-d参数。

[root@localhost ~]# mkfs.btrfs -d raid1 /dev/sda6 /dev/sda7
[root@localhost ~]# mount -t btrfs /dev/sda6 /btrfsdisk

(8)添加新设备
当设备的空间快被使用完的时候,用户可以使用btrfs-vol命令为文件系统添加新的磁盘设备,从而增加存储空间。下面的命令向/btrfsdisk文件系统增加一个设备/sda8。

[root@localhost ~]# btrfs-vol -a /dev/sda8 /btrfsdisk

(9)SSD支持
可以使用mount参数打开btrfs针对SSD的优化。命令如下:

[root@localhost ~]# mount -t btrfs -o SSD /dev/sda5 /btrfsdisk

(10)开启压缩功能
可以使用mount参数打开压缩功能。命令如下:

[root@localhost ~]# mount -t btrfs -o compress /dev/sda5 /btrfsdisk

(11)同步文件系统
为了提高效率,btrfs的IO操作由一些内核线程异步处理。这使得用户对文件的操作并不会立即反应到磁盘上。如果突然切断电源,可能导致刚进行的操作并没有保存到磁盘上,导致数据不一致。对于多数应用这并不是问题,但有些时候我们希望IO操作立即执行,这时就需要对文件系统进行同步。下面的btrfs命令用来同步文件系统:

[root@localhost ~]# btrfsctl -c /btrfsdisk

(12)Debug功能
下面的命令将设备sda5上的btrfs文件系统中的元数据打印到屏幕上。

[root@localhost ~]# btrfs-debug-tree /dev/sda5

通过对打印信息的分析,可以了解btrfs内部各个BTree的变化情况,从而进一步理解每一个文件系统功能的内部实现细节。我们可以在创建一个文件之前将BTree的内容打印出来,创建文件之后再次打印,通过比较两次的不同来了解btrfs创建一个文件需要修改哪些元数据,进而理解btrfs内部的工作原理。

发布了219 篇原创文章 · 获赞 603 · 访问量 129万+

猜你喜欢

转载自blog.csdn.net/gongxifacai_believe/article/details/88706503