在Linux中理解和使用BtrFS文件系统

时间:2020-02-23 14:31:29  来源:igfitidea点击:

本文旨在开始使用B树文件系统(BtrFS)。 Linux内核树中基于内核的文件系统目前超过55个,每个文件系统都有其优缺点。这里很好地介绍了如何在Linux中管理BtrFS文件系统。

一些文件系统的使用受到限制或者非常特定,并且被认为是真正通用的文件系统是extN系统,例如ext2,ext3,ext4. 它们虽然稳定且功能强大,但仍然存在某些限制。

B树文件系统(BtrFS),发音为Better FS,已经在Linux领域流行了一段时间。在撰写本文时,稳定的可用版本是4.9. 现在让我们了解Linux管理中BtrFS文件系统的基础。

什么是BtrFS?

BtrFS是下一代通用Linux文件系统,具有独特的功能,如高级集成设备管理,可伸缩性和可靠性。 BtrFS可扩展到16艾字节(EB),并专注于其他Linux文件系统所没有的功能,甚至有人认为Btrfs是Linux对Sun/Oracle ZFS的回应,但其体系结构比ZFS更可扩展。实际上,Linux中的BtrFS文件系统目前正受到广泛关注。

BtrFS为Ceph分布式文件系统及其用于云技术的RADOS对象存储层奠定了基础。它包含来自ext4,XFS,HP aufs和Reiser文件系统的想法。 BtrFS的开发非常活跃,并且以惊人的速度添加了新功能。

为什么选择BtrFS

Linux中的BtrFS文件系统提供以下功能和功能内置复制副本功能强大的快照功能内置卷管理和子卷最大可扩展性16 EB内置数据完整性(校验和)SSD优化压缩功能云端存储内置的BtrFSRAID RAID手动碎片整理在线文件系统管理数据和元数据完整性就地转换来自ext2/3/4和ReiserFSQuota组的在线扩展和减少文件系统大小对象级别RAID播种设备支持多种设备

Btrfs Specs最大卷大小:16 EB(2 ^ 64字节)最大文件大小:16 EB最大文件名大小:255字节文件系统检查:在线和离线目录查找算法:文件名中的B-TreeCharacters:任意,0x00除外兼容性硬和符号链接访问控制列表( ACL)扩展属性(xattrs)POSIX文件所有者/权限异步和直接I/OSparse文件

BtrFS真正支持最大文件大小为16艾字节。如果术语Exabytes使我们有些困惑,请参考下面的图表,该图表可以可视化透视图。

了解文件系统的大小

要检查内核当前支持哪些文件系统,可以在文件/proc/filesystems中找到。下面是我的本地系统的示例。

# cat /proc/filesystems 

nodev   sysfs
nodev   rootfs
..............
    btrfs
    ext3
    ext2
    ext4
    vfat
    xfs
    fuseblk
nodev   fuse
nodev   fusectl

为了支持BtrFS,输出应包含关键字btrfs。

安装BtrFS

在基于Debian的系统上:

sudo apt-get -y install btrfs-progs

基于RHEL的系统:

sudo yum -y install btrfs-progs

Arch Linux

sudo pacman -S btrfs-progs

Gentoo

sudo emerge --ask sys-fs/btrfs-progs

BtrFS有用的挂载选项

|
|

有关可用选项的更多详细信息,请阅读btrfs手册页

$man 5 btrfs

使用示例使用BtrFS

我的实验室机器当前有两个辅助硬盘驱动器,每个辅助硬盘驱动器包含1 GB,可在演示中很快使用。为了顺利进行,我们可以旋转虚拟机,安装btrfs-progs软件包并添加两个辅助硬盘驱动器。

创建和挂载BtrFS分区

要开始演示,首先在单个1 GB分区上创建BtrFS文件系统,然后将其挂载到/data目录。将在/dev/vdb上创建一个分区,该分区覆盖块设备的`30%'。要制作并安装基本的BtrFS文件系统,请使用以下命令:

sudo parted --script /dev/vdb "mklabel gpt"
sudo parted --script /dev/vdb "mkpart primary 1 30%"
sudo parted  /dev/vdb print 
sudo mkdir /data
sudo mkfs.btrfs /dev/vdb1
sudo mount /dev/vdb1 /data

为了确认挂载的分区能够按照我们希望的方式工作,请按以下步骤将一些数据复制到该分区:

sudo find /usr/share/doc -name '*[a,b].html' -exec cp {} /data \;
ls -l /data

同样使用btrfs命令检查文件系统:

btrfs filesystem show /dev/vdb1
btrfs filesystem df -h /data/
btrfs filesystem usage /data/

从这些命令中,我们将看到我们复制了一些现有的html文件,从而为我们提供了一些用于演示的真实数据。最后一条命令确认大小接近" 300MB(1 GB的30%)"。

列出根卷的子卷

$btrfs subvolume list /data/

查看磁盘空间利用率:

$btrfs filesystem df -h /data
$btrfs filesystem show /dev/vdb1

扩展btrfs文件系统

从dev/vdb的先前分区来看,我们仍有约700MB的未分区空间。将要使用它来扩大btrfs文件系统。

sudo parted /dev/vdb mkpart primary 30% 60%
sudo btrfs device add /dev/vdb2 /data/
btrfs filesystem show /data
df -h /data/

卸下btrfs设备

使用" btrfs device delete"命令删除在线设备。它将使用中的所有扩展区重新分配给文件系统中的其他设备,以便安全地将其删除。

例:

sudo btrfs device delete /dev/vdb2 /data

这就是我们增长BtrFS文件系统所需要做的一切。从以下显示的输出中确认了这一点:

增长BtrFS文件系统

我们还可以通过指定预期大小直接调整大小,语法为:

sudo btrfs filesystem resize amount /mount-point

该数量可以是设置的大小,例如+ 3g表示增加3 GiB,或者最大数量可以扩展文件系统以填充整个块设备。使用-3g减少3 GiB。考虑下面的示例,将新分区"/dev/sda4"添加到"/home"并扩展它。

$sudo btrfs device add /dev/sda4 /home -f
$sudo btrfs filesystem resize max /home
$sudo btrfs filesystem show /home

Label: 'home'  uuid: b40ffd9b-c09d-403e-a5f3-b79b5c314505
    Total devices 2 FS bytes used 79.71GiB
    devid    1 size 88.81GiB used 88.81GiB path /dev/mapper/arch-home
    devid    2 size 8.89GiB used 1.00GiB path /dev/sda4

请注意,新设备已成功添加。

平衡文件系统

如果我们用完了原始卷中的磁盘空间,则可以添加一个额外的分区。这些设备上的元数据和数据仍仅存储在/dev/vdb1上。现在必须使用以下命令来平衡它,以使其分布在所有分区上:

$sudo btrfs balance start -d -m /data

参数:

-d:代表数据

-m:表示元数据

这将确保磁盘被平等使用。

测试:

是时候在Linux上的BtrFS文件系统上进行一些测试了。为了测试平衡是否有效,必须生成两个大小均为100MB的随机数据。

$sudo dd if=/dev/urandom of=/data/hugefile1 bs=1M count=100
$sudo dd if=/dev/urandom of=/data/hugefile2 bs=1M count=100
$sudo btrfs balance start -d -m /data
$sudo btrfs filesystem show /data

我们应注意,两个卷之间的数据平衡良好。

如果我们想在引导时挂载/data目录,请将以下条目添加到/etc/fstab文件中:

/dev/vdb1  /data btrfs device=/dev/vdb1,device=/dev/vdb2 0 0

多设备文件系统创建

Linux中的WithBtrFS文件系统。可以进行多设备管理。这与mkfs.btrfs命令一起使用-d和-m选项。有效规格为:singleraid0:无冗余条带化raid1:磁盘镜像raid10:条带化镜像

-m single选项指示不进行元数据重复。使用硬件突袭时可能需要这样做。

要将新设备添加到已创建的多设备文件系统中,请使用:

sudo mkfs.btrfs /dev/device1 /dev/device2 /dev/device3
sudo mount /dev/device3 /mount-point

重新加载btrfs模块,然后运行:

sudo btrfs device scan

发现所有多设备文件系统。

让我们考虑下面的示例来创建raid10raid1btrfs文件系统。请注意,raid 10至少需要四个设备才能正常运行。

四个具有元数据镜像和数据条带化的设备

sudo mkfs.btrfs /dev/device1 /dev/device2 /dev/device3 /dev/device4

两台设备,元数据分条但无镜像

sudo mkfs.btrfs -m raid0 /dev/device1 /dev/device2

raid10用于数据和元数据

sudo mkfs.btrfs -m raid10 -d raid10 /dev/device1 /dev/device2 /dev/device3 /dev/device4

当驱动器大小不同时,正在使用的每个设备的全部容量:

sudo mkfs.btrfs /dev/device1 /dev/device2 /dev/device3
sudo mount /dev/device1 /mount-point

不要在单个驱动器上复制元数据。

sudo mkfs.btrfs -m single /dev/device

BtrFS设备扫描

扫描/dev下的所有块设备,并使用以下方法探测BtrFS卷:

sudo btrfs device scan
sudo btrfs device scan /dev/device

创建BtrFS子卷

子卷允许BtrFS文件系统内的离散管理标识。在本节中,将创建两个子卷,subvolume1和subvolume2. 为此,首先在/dev/vdb3设备上创建一个新的BtrFS,创建一个挂载点并将其挂载,

sudo parted /dev/vdb mkpart primary 60% 100%
sudo mkfs.btrfs /dev/vdb3
sudo mkdir /subvol_btrfs
sudo mount /dev/vdb3 /subvol_btrfs

现在让我们在/subvol_btrfs上创建两个子卷。

sudo btrfs subvolume create /subvol_btrfs/subvolume1
sudo btrfs subvolume create /subvol_btrfs/subvolume2

当我们定义子卷时,目录和BtrFS子卷实体都将在文件系统中创建。

/subvol_btrfs和子卷中创建一些文件:

sudo touch /subvol_btrfs/btrfsmainfile.txt
sudo touch /subvol_btrfs/subvolume1/subvolume1file.txt
sudo touch /subvol_btrfs/subvolume2/subvolume2file.txt

/subvol_btrfs中列出当前可用的子卷:

$sudo btrfs subvolume list /subvol_btrfs

ID 256 gen 9 top level 5 path subvolume1
ID 257 gen 9 top level 5 path subvolume2
sudo umount /subvol_btrfs

安装子卷

我们可以将子卷安装到安装点。让我们这样做,并使用ls -l命令比较结果:

$sudo mount /dev/vdb3 /subvol_btrfs/
$ls -l /subvol_btrfs/
$sudo umount  /subvol_btrfs/

$sudo mount -o subvol=subvolume1 /dev/vdb3 /subvol_btrfs/
$ls -l /subvol_btrfs/

$sudo mount -o subvol=subvolume2 /dev/vdb3 /subvol_btrfs/
$ls -l /subvol_btrfs/

将子卷设为默认子卷,而不是当前根卷:

让" subvolume1"成为默认子体积。我们需要的是其ID:

$sudo umount /subvol_btrfs/2>/dev/null
$sudo mount /dev/vdb3 /subvol_btrfs/
$ID=`btrfs subvolume list /subvol_btrfs/| grep subvolume1 | awk '{print }'`
$btrfs subvolume set-default ${ID} /subvol_btrfs

通过重新挂载/dev/vdb3进行测试:

$sudoumount  /subvol_btrfs/
$sudo mount /dev/vdb3 /subvol_btrfs/

$ls -l /subvol_btrfs/
total 0
-rw-r--r--. 1 root root 0 Jan 10 11:22 subvolume1file.txt

请注意,从上面的输出中可以看到,我们在subvolume1上创建的数据是挂载在/dev/vdb3上的默认数据。

要将默认值设置回根卷,请使用ID 0或者5:

$sudo btrfs subvolume set-default 0 /subvol_btrfs
$sudo umount /subvol_btrfs 
$sudo mount /dev/vdb3 /subvol_btrfs/

$ls -l /subvol_btrfs/
total 0
-rw-r--r--. 1 root root  0 Jan 10 11:22 btrfsmainfile.txt
drwxr-xr-x. 1 root root 36 Jan 10 11:22 subvolume1
drwxr-xr-x. 1 root root 36 Jan 10 11:22 subvolume2

使用BtrFS快照

Linux快照中的BtrFS文件系统功能可以用作只读或者读/写数据副本。快照可以通过以下方式使用:

1.创建快照为只读,然后实现快照的备份。这样,备份将在创建快照时备份到主机文件系统。

2.修改多个文件时,将其用作还原点。如果修改导致负面结果,则可以轻松还原到快照副本。

必须在与目标数据相同的文件系统上创建快照,因为快照的快速创建受文件系统内内部链接形式的影响。

注意:我们无法创建完整文件系统的快照。这是因为对快照的更改将需要写回到自身,从而导致无限递归。

为了演示的目的,请充分使用我们之前创建的两个子卷。我们的场景是创建一个工作子卷subvoume1的只读快照。

$sudo btrfs subvolume snapshot -r /subvol_btrfs/subvolume1 /subvol_btrfs/subvolume2/backup/

Create a readonly snapshot of '/subvol_btrfs/subvolume1' in '/subvol_btrfs/subvolume2/backup'

我们可以使用以下命令列出可用的子卷:

$sudo btrfs subvolume list  /subvol_btrfs/

ID 256 gen 24 top level 5 path subvolume1
ID 257 gen 24 top level 5 path subvolume2
ID 258 gen 24 top level 257 path subvolume2/backup

从输出中,我们可以看到快照显示为新的子卷。列出两个目录的内容应表明内容相同:

$ls /subvol_btrfs/subvolume2/backup/
subvolume1file.txt

$ls /subvol_btrfs/subvolume1/
subvolume1file.txt

如果我们从/subvol_btrfs/subvolume1 /中删除所有文件,则BtrFS中的写时复制(COW)技术将在/subvol_btrfs/subvolume2/backup中创建文件。如果发生灾难,我们可以简单地将文件复制回原始位置,因为如果原始文件发生更改,它们将不会被修改。

BtrFS就地迁移;将ext4文件系统转换为BtrFS

在此示例中,我们将介绍如何将ext4文件系统转换为BtrFS。由于我在KVM上运行CentOS服务器,因此我将添加辅助硬盘驱动器,创建一个" ext4"分区,然后将其转换为BtrFS,以便我们可以了解如何完成操作。

添加" 1GB"辅助块设备,这将在主机上完成:

$syudo virsh vol-create-as default  --name btrfs-sec.qcow2 1G
$sudo virsh vol-list --pool default
$sudo virsh attach-disk --domain cs1 --source /var/lib/libvirt/images/btrfs-sec.qcow2 --persistent --target vdc

确认其已添加到vm上:

$lsblk  /dev/vdc 

NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT
vdc  252:32   0   1G  0 disk

创建ext4分区:

$sudo parted --script /dev/vdc "mklabel gpt mkpart primary 0% 100%"
$sudo parted --script /dev/vdc print
$sudo lsblk -f /dev/vdc

挂载新创建的文件系统,创建一些文件和目录,然后卸载该文件系统:

$sudo mkdir /ext4tobtrfs
$sudo mount /dev/vdc1 /ext4tobtrfs/
$sudo mkdir /ext4tobtrfs/test-{1-4}-dir
$sudo touch /ext4tobtrfs/test-file{1..10}.txt
$sudo ls -l  /ext4tobtrfs/
$sudo umount /ext4tobtrfs/

将文件系统转换为Btrfs:

# btrfs-convert -l convertedfs /dev/vdc1 
create btrfs filesystem:
    blocksize: 4096
    nodesize:  16384
    features:  extref, skinny-metadata (default)
creating btrfs metadata.
copy inodes [o] [         0/       22]
creating ext2 image file.
set label to 'convertedfs'
cleaning up system chunk.
conversion complete.

再次挂载文件系统并查看文件系统类型:

# mount /dev/vdc1 /ext4tobtrfs/
# df -hT /ext4tobtrfs/
Filesystem     Type   Size  Used Avail Use% Mounted on
/dev/vdc1      btrfs 1022M   51M  643M   8% /ext4tobtrfs

注意,/ext4tobtrfs的文件系统是btrfs类型。

要查看子卷,BtrFS信息和内容,请使用:

# btrfs filesystem show /ext4tobtrfs/
Label: 'convertedfs'  uuid: 3e985770-66a0-4b85-810e-2e93182696f3
    Total devices 1 FS bytes used 34.78MiB
    devid    1 size 1022.00MiB used 616.25MiB path /dev/vdc1

# btrfs subvolume list /ext4tobtrfs/
ID 256 gen 6 top level 5 path ext2_saved

# ls -l /ext4tobtrfs/
total 16
drwxr-xr-x. 1 root root 10 Jan 10 13:22 ext2_saved
drwx------. 1 root root  0 Jan 10 13:14 lost+found
drwxr-xr-x. 1 root root  0 Jan 10 13:19 test-{1-4}-dir
-rw-r--r--. 1 root root  0 Jan 10 13:19 test-file10.txt
-rw-r--r--. 1 root root  0 Jan 10 13:19 test-file1.txt
-rw-r--r--. 1 root root  0 Jan 10 13:19 test-file2.txt
-rw-r--r--. 1 root root  0 Jan 10 13:19 test-file3.txt
-rw-r--r--. 1 root root  0 Jan 10 13:19 test-file4.txt
-rw-r--r--. 1 root root  0 Jan 10 13:19 test-file5.txt
-rw-r--r--. 1 root root  0 Jan 10 13:19 test-file6.txt
-rw-r--r--. 1 root root  0 Jan 10 13:19 test-file7.txt
-rw-r--r--. 1 root root  0 Jan 10 13:19 test-file8.txt
-rw-r--r--. 1 root root  0 Jan 10 13:19 test-file9.txt

# file  /ext4tobtrfs/ext2_saved/image
/ext4tobtrfs/ext2_saved/image: Linux rev 1.0 ext4 filesystem data, UUID=7e6849f2-8560-4b9d-add8-d344ef577650 (extents) (64bit) (large files) (huge files)

> To mount subvolume or the image in ext2_saved subvolume, use:

# mount -o subvol=ext2_saved /dev/vdc1 /mnt/
# ls -l /mnt
# umount /mnt
# mount -o loop /ext4tobtrfs/ext2_saved/image /mnt/
# ls -la /mnt/
回滚到ext4文件系统:
# umount /ext4tobtrfs/

# btrfs-convert -r /dev/vdc1
rollback complete.

# mount /dev/vdc1 /ext4tobtrfs/

# df -hT /ext4tobtrfs/
Filesystem     Type  Size  Used Avail Use% Mounted on
/dev/vdc1      ext4  990M  2.6M  921M   1% /ext4tobtrfs

如果在/ext4tobtrfs /中查看文件,我们会注意到在BtrFS上创建的目录已消失,只有在ext4文件系统上最初创建的目录在那里。

转换现有的单设备系统

为了防止单个磁盘故障,将现有的单设备系统(在这种情况下为"/dev/vdb1")转换为两个设备" raid1"系统,请使用以下命令:

# umount  /subvol_btrfs/
# mount /dev/vdb1 /subvol_btrfs/
# btrfs device add /dev/vdb2 /subvol_btrfs/-f
# btrfs balance start -dconvert=raid1 -mconvert=raid1 /subvol_btrfs/

BtrFS维护任务

Linux中的BtrFS文件系统将始终需要管理员知道如何执行以下维护任务。

1.用擦洗验证校验和:

打开一个终端窗口并运行:

# watch btrfs scrub status  /subvol_btrfs/

打开另一个终端窗口并运行:

# btrfs scrub start /subvol_btrfs/

第一个提示中的"监视"将显示清理进度。

2.手表余额:

在一个终端上运行:

# watch btrfs balance status /subvol_btrfs/

在另一个终端上,运行:

# btrfs balance start /subvol_btrfs/

3.递归对文件系统进行碎片整理,

# btrfs filesystem defragment -r /subvol_btrfs/

更换btrfs文件系统上的故障设备

如果设备丢失或者超级块损坏,则需要在降级模式下挂载文件系统,然后再进行故障排除。示例如下所示:

# mkfs.btrfs -m raid1 /dev/vdb /dev/vdc /dev/vdd 
# mount -o degraded /dev/vdb /mnt
# btrfs device delete missing /mnt