Linux操作系统(十一):磁盘配额与高级文件系统管理

  • 磁盘配额的应用与实践
  • 软件磁盘阵列RAID
  • 逻辑卷管理器LVM
  • btrfs文件系统管理与应用

 一、关于本文内容的导读

这部分不涉及具体内容的解析,只是作为浏览和查找相关知识点的引导内容,采用【主题 | 命令 | 对应内容小节编号】三个关键信息的组合模式,依照这些信息可以快速查找到相关详细的示例和解析。

在了解这篇博客的内容之前,需要先了解磁盘分区、磁盘与文件系统的管理,这些内容之前我有两篇博客做了详细的介绍,分别是:磁盘分区磁盘与文件系统管理,当然还有自盘配额肯定会涉及用户及权限相关内容,这些内容都在前面的博客中有详细的介绍,如果遇到相关内容不了解的话可以查看我之前的博客。

这篇博客一开始没想写的这么详细,但写着写着就控制不住想把想到的都表达清楚,写完发现这篇博客可能是我有史以来最大的篇幅,就算可能是一小节内容可能比别人的单篇都详细,我不认为这种详细的描述和细节展示是优点,仅仅只是想把它做成一个在将来自己查阅的时候可以尽可能的不再用去参考其他资料,也就是只想把它做成一个合格的工具而已,大家在阅读的时候按照目录和命令标记查找相关内容即可,非必要不必研读整篇博客。

管理xfs文件系统磁盘配额 | xfs_quota | 2.4~2.6
管理md设备及软件磁盘阵列RAID | mdadm | 3.4
创建物理卷PV | pvcreate | 4.2.2
查找当前系统上具有物理卷PV的磁盘 | pvscan | 4.2.2
查看物理卷PV的状态详细信息 | pvdisplay | 4.2.2
将物理卷PV上的数据移除 | pvmove | 4.3 | 该物理卷PV上的数据会被移到当前LV上的其他物理卷PV上
删除物理卷PV的属性 | pvremove | 4.3 | 删除属性以后依然还会保持LVM的system的类型,但不再是物理卷,如果要当作物理卷使用需要重新使用pvcreate创建
创建卷组VG | vgcreate | 4.2.3
查找当前系统上的卷组VG | vgscan | 4.2.3
查看卷组的状态详细信息 | vgdisplay | 4.2.3
在卷组上增加物理卷PV | vgextend | 4.3
在卷组上删除物理卷PV | vgreduce | 4.3
设置卷组VG的属性 | vgchange | 4.6
删除卷组VG | vgremove | 4.6
创建逻辑卷LV | lvcreate | 4.2.4~4.5 | 创建逻辑卷分区设备、thin pool LV逻辑卷容量池、virtual LV虚拟逻辑卷、lv snap逻辑卷快照
查询系统上的逻辑卷LV | lvscan | 4.2.4
查看逻辑卷LV的状态详细信息 | lvdisplay | 4.2.4
增加逻辑卷LV容量 | lvextend | 4.3
减少逻辑卷LV容量 | lvreduce | 4.3
调整逻辑卷LV的容量大小 | lvresize | 4.3
创建Btrfs文件系统 | mkfs.btrfs | 5.2
管理Btrfs文件系统 | btrfs | 5.*  #更多具体的Btrfs文件系统相关命令见具体内容

 二、磁盘配额的应用与实践

2.1什么是磁盘配额

所谓磁盘配额就是针对个别用户、者用户组、服务使用磁盘空间容量进行限制,在每个系统上的磁盘容量都是有限的,而一个系统可能同时需要支持多个用户或服务的应用,在这种有限的资源情况下,为了确保每个用户能够正常的使用系统资源,确保不同用户和服务之间不会因为有限的资源产生冲突,系统管理者就需要对不同的用户、用户组及服务使用磁盘空间容量进行限制,比如磁盘配额具体应用操作有:

1.针对网站服务器,例如每个人的网页空间的容量限制;

2.针对邮件服务器,例如每个人的邮件空间限制;

3.针对文件服务器,例如每个人的可用网络硬盘空间;

4.限制某一用户组所能使用的最大磁盘配额(使用用户组限制):grpquota;

5.限制某个用户的最大磁盘配额:usrquota;

6.限制某个目录的最大磁盘配合:prjquota;

2.2磁盘配额的系统环境限制

磁盘配额虽然能够有效的实现磁盘空间容量使用权限的管理,但在不同的系统环境下的支持程度也不是一样的,系统环境对磁盘配额的具体限制包括:

1.ext文件系统仅能针对整个文件系统实现磁盘配额:所以ext文件系统无法实现单一目录设计磁盘配额,因此在磁盘配额设计时需要注意文件系统的支持情况,而xfs文件系统可以使用project来设计不同目录的磁盘配额。

2.内核必须支持磁盘配额:要想实现磁盘配额必须要内核支持,CentOS 7.X的默认内核支持文件系统配额,其他Linux版本需要注意内核的支持情况,如果是自己编译的内核还需要注意是否开启磁盘配额功能。

3.只针对一般用户身份有效:并不是所有账号都可以设置磁盘配额,例如root就不能设置磁盘配额,因为几乎整个系统的所有资源root都有权限使用。

4.若启用SELinux不是所有目录都可以设置磁盘配额:新版本的CentOS会默认启用SELinux这个特殊权限内核功能,该功能会加强某些特殊权限控制,后面的相关博客会详细的介绍SELinux的内容,如果需要关闭SELinux的限制后需要会介绍。

2.3xfs文件系统的磁盘配额限制选项可以分为以下几个部分

1.分别针对用户、用户组或个别目录:xfs文件系统的磁盘配额限制中,主要针对用户组group、单个用户user或单个目录project进行磁盘使用率的限制;

2.容量限制或文件数量限制:所谓容量限制就是针对文件系统中的区块block的容量实现用户磁盘容量的限制,而文件数量限制就是基于inode的数量限制实现用户磁盘容量的限制;

3.软限制与硬限制:这里的软硬设置简单的来说就是当容量使用到了一个设置限额是直接不能再超过,还是可以在一定范围内超过,硬限制就是指定一个容量限制后使用容量不会超过该限制;而软限制就是可以在指定的容量限制上适当超过,当然软限制也还有一个不能超过的容量限制,比如软限制设置为400~500MB就是用户可以超过400MB但不能超过500MB。通常使用soft表示软限制,使用hard表示硬限制。

4.限制的宽限时间:所谓宽限时间是用来配合软限制的,就是当容量超过soft的限制就会在一定时间内发出警告,如果超过这个时间不删除超过soft的数据就会将限制容量最大使用量变成sotf,此时磁盘使用就会锁定而无法新增文件。

2.4xfs文件系统的磁盘配额实践示例

如果要实现磁盘配额,首先要检查系统内核是否支持,如果支持再在挂载的时候配置fstab的磁盘配额的参数,然后在配置前查看文件系统的磁盘配额是否启动及相关信息,确定以上都没有问题以后就可以开始对文件系统进行磁盘配额设置了。

 grep CONFIG_QUOTA /boot/config-【tab键补全】  #检查内核对磁盘配额的支持,下面是我当前测试的系统对磁盘配额支持情况的相关数据:

 CONFIG_QUOTA=y
CONFIG_QUOTA_NETLINK_INTERFACE=y
# CONFIG_QUOTA_DEBUG is not set
CONFIG_QUOTA_TREE=y
CONFIG_QUOTACTL=y      #这里说明内核支持磁盘配额,如果不支持就需要手动安装磁盘配额相关内核模块(超出当前内容范围,有机会再在相关博客补充)
CONFIG_QUOTACTL_COMPAT=y

 #虽然这里不能将手动安装内核模块做一个完全的解析,但这里还是提供一下安装磁盘配额软件的命令:

 yum -y install  quota xfsprogs  #如果内核已经支持就可以不用安装了

建立磁盘配额的测试环境:

为了测试磁盘配额,首先我们需要相应的实验磁盘(挂载点:/data/myquota)、测试用户myquota*、测试用户组myquotagrp,当然也可以使用现成的文件系统和用户,只要能满足测试条件即可。下面是我建立测试环境的命令,详细说明见注释:

 mkdir /data/myquota  #创建目录作为挂载点

 groupadd myquotagrp  #创建用户组,用作演示用户组配额grpquota

 #下面创建五个测试用户,账户密码设置为password

 useradd -g myquotagrp myquota1;echo "password" | passwd --stdin myquota1

 useradd -g myquotagrp myquota2;echo "password" | passwd --stdin myquota2

 useradd -g myquotagrp myquota3;echo "password" | passwd --stdin myquota3

 useradd -g myquotagrp myquota4;echo "password" | passwd --stdin myquota4

 useradd -g myquotagrp myquota5;echo "password" | passwd --stdin myquota5

 chgrp myquotagrp /data/myquota  #将目录的用户组修改为myquotagrp

 chmod 2770 /data/myquota  #修改目录的权限,只有root和目录用户组成员具有可读可写可执行权限,并且每个用户创建的文件只有自己和root有权删除

创建磁盘分区并格式化为xfs文件系统(如果有现成的分区可以跳过这一步):

 #查看当前系统上的磁盘信息

 lsblk  #下面是命令执行后打印出的磁盘信息列表数据:

 NAME            MAJ:MIN RM  SIZE RO TYPE MOUNTPOINT
 sda               8:0    0  120G  0 disk
 ├─sda1            8:1    0    1G  0 part /boot
 ├─sda2            8:2    0   19G  0 part
 │ ├─centos-root 253:0    0   17G  0 lvm  /
 │ └─centos-swap 253:1    0    2G  0 lvm  [SWAP]
 ├─sda3            8:3    0   20G  0 part /iso
 └─sda4            8:4    0    1K  0 part
 sdb               8:16   0   20G  0 disk
 sr0              11:0    1  4.4G  0 rom  /run/media/tx/CentOS 7 x86_64

 #从上面的数据可以看到当前测试系统上有两个磁盘sda、sdb,然后通过parted +print来查看它们的详细磁盘分区信息:

 parted /dev/sda print  #查看sda的磁盘分区信息:

 Model: VMware, VMware Virtual S (scsi)
 Disk /dev/sda: 129GB
 Sector size (logical/physical): 512B/512B
 Partition Table: msdos
 Disk Flags:
 
 Number  Start   End     Size    Type      File system  标志
  1      1049kB  1075MB  1074MB  primary   xfs          启动
  2      1075MB  21.5GB  20.4GB  primary                lvm
  3      21.5GB  42.9GB  21.5GB  primary   xfs
  4      42.9GB  129GB   85.9GB  extended

 parted /dev/sdb print  #查看sdb的磁盘分区信息:

 Model: VMware, VMware Virtual S (scsi)
 Disk /dev/sdb: 21.5GB
 Sector size (logical/physical): 512B/512B
 Partition Table: msdos
 Disk Flags:
 
 Number  Start  End  Size  Type  File system  标志

 #从上面的磁盘分区信息可以看到目前sda的扩展分区有85.9GB容量、sdb总共有21.5GB容量没有划分分区,这里我从sda中划分一个10GB容量的磁盘分区作为测试使用

 parted /dev/sda mkpart logical xfs 42.9G 53.7G  #这里我是用parted +mkpart创建分区,你也可以基于你的磁盘分区格式使用fdisk或者gdisk实现分区

 mkfs.xfs /dev/sda5  #格式化磁盘分区

挂载文件系统并配置fstab的磁盘配额参数(如果是之前现有的文件系统,就参考下面挂载配置参数重新挂载文件系统)

 vim /etc/fstab  #编辑挂载配置信息

 /dev/sda5 /data/myquota xfs defaults,usrquota,grpquota 0 0  #将这一行配置添加到fstab中,注意两个参数usrquota,grpquota

 mount -a  #根据/etc/fstab中的磁盘挂载配置信息更新系统上的磁盘挂载

 df /dev/sda5  #查看sda5的文件系统:

 文件系统          1K-块  已用     可用 已用% 挂载点
 /dev/sda5      10486784 33000 10453784    1% /data/myquota

注意挂载文件系统的时候在配置文件中添加两个参数,usrquota,grpquota,这两个参数分别表示启动用户磁盘配额和用户组磁盘配额,这是启动磁盘配额的关键,如果没有添加这两个参数,后面就没办法实现磁盘配额,如果是原来现有的文件系统就在原来的配置信息中添加这两个参数,然后来查看文件系统的磁盘配额是否启动。

查看文件系统是否启动磁盘配额功能

由于我测试的磁盘配额设置是基于xfs文件系统,所以这里使用的命令是xfs_quota,如果是其他文件系统注意使用相对应的工具命令,这里先来看如何查看磁盘配额的命令语法及相关参数解析(设置xfs文件系统的磁盘具体限制参数也是通过这个命令,但参数不一样,后面在具体解析):

 xfs_quota -x -c "子命令" [挂载点]

xfs_quota查看磁盘配额报告的选项和参数:

//选项:
-x:专家模式,后续才能够加入-c的命令参数;
-c:启用子命令与xfs_quota进行交互,可以使用多个子命令,执行顺序按照给定的顺序运行;
//子命令:
print:列出目前主机内的文件系统参数等数据,如果指定挂载点就只列出指定的文件系统;
df:跟df命令一样,可以加上-b(block)、-i(inode)、-h(指定单位)参看文件系统的容量即使用情况等信息;
report:列出目前的磁盘配额选项,有-ugr(user、group、project)及bi等,实际上就是查看用户或用户组容量使用数据及用户对应的限额数据;
state:说明目前支持磁盘配额的文件系统的信息,有没有使用相关选项等,实际上就是查看文件系统的限额具体设置数据;

这里就不测试print、df这两个子命令了,如果有兴趣可以执行测试,具体来看report、state的查询结果:

 xfs_quota -x -c "report" /data/myquota  #report子命令默认情况会将当前使用了磁盘分区资源的用户和用户组的使用量与及其对应的限额数据打印出来:

                                Blocks                     
 User ID          Used       Soft       Hard    Warn/Grace     
 ---------- --------------------------------------------------
 root                0          0          0     00 [--------]

 Group quota on /data/myquota (/dev/sda5)
                               Blocks                     
 Group ID         Used       Soft       Hard    Warn/Grace     
 ---------- --------------------------------------------------
 root                0          0          0     00 [--------]
 myquotagrp          0          0          0     00 [--------]
 #注意看上面打印出来的数据排版是表格形式,在表格的上方有Blocks标题表示当前容量描述单位是块,可以使用-b(块)-i(inode)-h(易读的容量单位比如字节等)方式来描述,需要注意的是指定多个容量描述就会在数据后面添加列来数据

 #然后每一栏数据表达的含义:User ID/Group ID==>用户或用户组ID、Used==>已经使用的容量、Soft==>软限制的容量、Hard==>应限制的容量、Warn/Grace==>宽限时间

 #同样还可以使用-u或-g指定输出用户和用户的数据,比如查看当前测试文件系统的用户容量使用情况及限额数据,单位使用inode

 xfs_quota -x -c "report -ui" /data/myquota  #测试结果就不粘贴了,可以执行测试

 xfs_quota -x -c "state" /data/myquota  #查看当前文件系统的磁盘限额设置

 User quota state on /data/myquota (/dev/sda5)  #表示用户的磁盘限额设置
  Accounting: ON  #有启用计算功能
  Enforcement: ON  #有实际磁盘限额管理的功能
  Inode: #67 (1 blocks, 1 extents)
 Group quota state on /data/myquota (/dev/sda5)  #表示用户组的磁盘限额设置
  Accounting: ON  #有启用计算功能
  Enforcement: ON  #有实际磁盘限额管理的功能
  Inode: #68 (2 blocks, 2 extents)
 Project quota state on /data/myquota (/dev/sda5)  #表示文件系统的目录磁盘限额设置
  Accounting: OFF  #没有启用计算功能
  Enforcement: OFF  #没有启用磁盘限额管理的功能
  Inode: #68 (2 blocks, 2 extents)
 Blocks grace time: [7 days]  #容量的限额宽限时间
 Inodes grace time: [7 days]  #文件限额宽限时间
 Realtime Blocks grace time: [7 days]  #时间交换区限额宽限时间

文件系统的用户与用户组磁盘限额设置实践

在上面的示例中已经将磁盘限额的环境配置完成了,并且通过xfs_quota的report和state子命令查看确认了相关配置是没问题的,现在就根据前面配置用户限额和用户组限额来实现一个磁盘限额设置示例,假设有需求是/data/myquota挂载的文件系统需要给用户组myquotagrp的软限额为5G、硬限额为7.5G,每个用户的软限额为1G、硬限额为1.5G,下面来看具体实现。

在实现需求前先解析一下基于xfs文件系统的磁盘限额管理工具xfs_quota的磁盘限额设置的语法:

 xfs_quota -x -c "limit [ -ug ] b[ soft | hard ]=N i[ soft | hard ]=N name"  #设置磁盘配额的具体参数

 xfs_quota -x -c "timer [ -bir ] Ndays"  #设置磁盘配额的宽限时间

xfs_quota查看磁盘配额的具体设置选项及参数解析:

//子命令
limit:用于设置磁盘限额的具体限制数据,相关参数含义下面具体分析:
  [-ug]:用于指定设置用户或用户组的磁盘配额;
  b[soft | hard]=N:用于设置容量限制;
  i[soft | hard]=N:用于设置文件数量限制;
  name:用于指定用于或用户组名称; timer:用于设置磁盘限额的宽限时间,相关参数含义下面具体解析:
  [-bir]:b表示容量限额的宽限时间、i表示文件个数限额宽限时间、r表示时实运行区的限额宽限时间。
  Ndays:表示设定宽限时间为N天

实现文件系统基于用户和用户的磁盘限额设置:

 #设置用户磁盘限额

 xfs_quota -x -c "limit -u bsoft=1024M bhard=1536M myquota1" /data/myquota  #由于命令中无法解析带小数的值,所以这里将容量单位G转换成M的值

 xfs_quota -x -c "limit -u bsoft=1024M bhard=1536M myquota2" /data/myquota

 xfs_quota -x -c "limit -u bsoft=1024M bhard=1536M myquota3" /data/myquota

 xfs_quota -x -c "limit -u bsoft=1024M bhard=1536M myquota4" /data/myquota

 xfs_quota -x -c "limit -u bsoft=1024M bhard=1536M myquota5“ /data/myquota

 xfs_quota -x -c "report -ubih" /data/myquota  #查看磁盘用户配额以后的配额信息,对照前面文件系统磁盘配额的初始信息理解,下面是打印结果:

 User quota on /data/myquota (/dev/sda5)
                        Blocks                            Inodes              
 User ID      Used   Soft   Hard Warn/Grace     Used   Soft   Hard Warn/Grace  
 ---------- --------------------------------- ---------------------------------
 root            0      0      0  00 [------]      3      0      0  00 [------]
 myquota1        0     1G   1.5G  00 [------]      0      0      0  00 [------]
 myquota2        0     1G   1.5G  00 [------]      0      0      0  00 [------]
 myquota3        0     1G   1.5G  00 [------]      0      0      0  00 [------]
 myquota4        0     1G   1.5G  00 [------]      0      0      0  00 [------]
 myquota5        0     1G   1.5G  00 [------]      0      0      0  00 [------]

 xfs_quota -x -c "limit -g bsoft=5120M bhard=7680M myquotagrp" /data/myquota  #设置用户组磁盘限额

 xfs_quota -x -c "report -gbih" /data/myquota  #查看用户组配额以后的配额信息

 Group quota on /data/myquota (/dev/sda5)
                        Blocks                            Inodes              
 Group ID     Used   Soft   Hard Warn/Grace     Used   Soft   Hard Warn/Grace  
 ---------- --------------------------------- ---------------------------------
 root            0      0      0  00 [------]      2      0      0  00 [------]
 myquotagrp      0     5G   7.5G  00 [------]      1      0      0  00 [------]

 #实现磁盘配额宽限时间的设置

 xfs_quota -x -c "timer -b 14days" /data/myquota  #设置宽限时间

 xfs_quota -x -c "state" /data/myquota  #查看文件系统的限额设置,检查宽限时间设置是否设置成功,下面是打印的信息:

 User quota state on /data/myquota (/dev/sda5)
  Accounting: ON
  Enforcement: ON
  Inode: #67 (2 blocks, 2 extents)
 Group quota state on /data/myquota (/dev/sda5)
  Accounting: ON
  Enforcement: ON
  Inode: #68 (2 blocks, 2 extents)
 Project quota state on /data/myquota (/dev/sda5)
  Accounting: OFF
  Enforcement: OFF
  Inode: #68 (2 blocks, 2 extents)
 Blocks grace time: [14 days]  #容量限额宽限时间已经被设置为14天了
 Inodes grace time: [7 days]
 Realtime Blocks grace time: [7 days]

以上就是用户和用户的磁盘限额设置的全部设置示例,下面再来基于用户和目录实现磁盘限额设置,这里还是要提醒一下,因为我测试的xfs文件系统,所以可以实现目录的磁盘限额,其他文件系统不一定可以实现,比如ext文件系统就不能实现。然后就是磁盘限额中目录和用户组的限额操作不能同时存在,所以如果要在之前的文件系统上操作测试,就要将之前的文件系统配置取消,实际上也就是将fstab的配置参数修改下一,然后重新挂载文件系统。

重新挂载文件系统并配置fstab文件系统系统参数为用户和目录配额

 vim /etc/fstab

 /dev/sda5 /data/myquota xfs defaults,usrquota,prjquota 0 0  #用这一行配置替换之前sda5的文件系统系统挂载配置

 umount /data/myquota  #卸载之前的文件系统挂载

 mount -a  #重新挂载文件系统

 xfs_quota -x -c "state" /data/myquota  #查看重新挂载的文件系统磁盘配额设置

 User quota state on /data/myquota (/dev/sda5)
  Accounting: ON
  Enforcement: ON
  Inode: #67 (2 blocks, 2 extents)
 Group quota state on /data/myquota (/dev/sda5)
  Accounting: OFF
  Enforcement: OFF
  Inode: #68 (2 blocks, 2 extents)
 Project quota state on /data/myquota (/dev/sda5)
  Accounting: ON
  Enforcement: ON
  Inode: #68 (2 blocks, 2 extents)
 Blocks grace time: [14 days]
 Inodes grace time: [7 days]
 Realtime Blocks grace time: [7 days]

重新挂载的文件系统,会将之前的磁盘配额设置全部清除,并根据fstab的配额参数启动相应的磁盘配额功能。

实现磁盘目录配额使用的命令是 xfs_quota -x -c "limit -p ..." ,但它需要子命令project来配置一些目录信息,下面来看这个子命令的语法:

 project [ -cCs [ -d depth ] [ -p path ] id | name ]  #一般使用的就是 project -s name来实现配置

关于这个子命令的选项在man文档中也没有太详细的介绍,这里是对文档内容简单的理解:-c、C、s 就是表示允许不同的维护目录配额机制;-d表示限制目录的递归级别;-p表示使用命令的方式来配置,采用这个方式就不需要手动去创建配置文件了。然后就是id和name表示的是选项标识符和选项名,它们由配置文件来提供,本质上配置文件的逻辑就是通过配置文件的id和name可以找到真正的配额目录,下面来看如何创建目录配额的配置文件:

 #磁盘目录配额指定方案识别码与目录的对应在/etc/projects

 echo "11:/data/myquota" >> /etc/projects  #这里就是给配额的目录配置一个标识符,即id,取值自己随意指定,不重复即可

 #磁盘目录配额规范方案名称与标识符的对应在/etc/projid

 echo "myquotaproject:11" >> /etc/projid  #这里就是给配额的标识符配置一个名称,即name,取值自己随意指定,不重复即可

给要实现磁盘配额的目录配置好标识符和名称以后,下面就通过project子命令来实现目录配额方案的初识化:

 mkdir /data/myquota/www  #创建一个测试目录

 echo "11:/data/myquota/www" >> /etc/projects  #添加配额目录的标识配置

 echo "myquotaprojwww:11" >> /etc/projid  #添加配额目录的名称配置

 xfs_quota -x -c "project -s myquotaprojwww"  #基于名称实现目录配额方案初识化,执行命令以后会打印一堆信息,只要不报错就没问题

 xfs_quota -x -c "print" /data/myquota  #通过print子命令可以查看到各项文件系统与project目录对应,可以用来检查初识化是否成功

 Filesystem          Pathname
/data/myquota       /dev/sda5 (uquota, pquota)
/data/myquota       /dev/sda5 (project 11, myquotaproject)

 xfs_quota -x -c "report -pbih" /data/myquota  #还可以使用report查看限额数据信息来检查初识化是否成功

 Project quota on /data/myquota (/dev/sda5)
                        Blocks                            Inodes              
Project ID   Used   Soft   Hard Warn/Grace     Used   Soft   Hard Warn/Grace  
---------- --------------------------------- ---------------------------------
#0              0      0      0  00 [------]      2      0      0  00 [------]
myquotaproject      0      0      0  00 [------]      1      0      0  00 [------]

磁盘目录配额方案初识化成功以后,就可以正式的实现磁盘目录的配额了,前面在初识化磁盘目录配额时创建了一个测试目录/data/myquota/www,也给这个目录实现了配额初识化设置了,下面就基于这个目录来配置这个目录软限额为1G、硬限额为1.5G,下面是示例的具体实现命令:

 xfs_quota -x -c "limit -p bsoft=1G bhard=1536M myquotaprojwww" /data/myquota  #给/data/myquota/www目录设置磁盘配额

 xfs_quota -x -c "report -pbih" /data/myquota  #查看文件系统的目录磁盘配额数据即信息

 Project quota on /data/myquota (/dev/sda5)
                        Blocks                            Inodes              
Project ID   Used   Soft   Hard Warn/Grace     Used   Soft   Hard Warn/Grace  
---------- --------------------------------- ---------------------------------
#0              0      0      0  00 [------]      2      0      0  00 [------]
myquotaprojwww      0     1G   1.5G  00 [------]      2      0      0  00 [------]

以上就是基于目录的磁盘配额设置,在示例中我使用了www这个目录,这其实在实际应用中非常常见,因为一般www服务都是由一个名为httpd的账号管理,www服务产生的数据都属于httpd这个账号,这个服务可能会需要在不同的磁盘或者目录中有不同的容量需求,有xfs文件系统支持的目录磁盘配额就非常方便管理。

 2.5磁盘配额的其他命令

上面介绍了如何启动和设置磁盘配额,最后再来介绍一下取消、恢复、关闭、删除磁盘配额四个子命令:

disable:暂时取消磁盘配额限制,取消以后磁盘配额的设置就不会再限制用户对磁盘的使用了,比如在一些紧急情况下可以直接使用这个子命令暂时取消磁盘的限额。
enable:与disable的限额相对应,可以将取消的磁盘配额限制恢复,如果此时磁盘的容量的使用超过限制,启动以后就会因为限额的限制导致无法使用,所以在恢复之前要整理好文件数据,保证有足够的容量使用;
off:关闭磁盘配额功能,关闭以后无法恢复,需要重新挂载文件系统才能重新恢复文件系统的磁盘配额功能,关闭以后的磁盘限额设置不会被清除,重新挂载文件系统以后会自动恢复设置;
remove:可以删除磁盘配额的设置,但必须是在关闭所有配额功能的情况下才可以,即执行过off子命令,删除以后的磁盘配额设置重新挂载文件系统也无法恢复,需要重新设置。

下面就简单的演示一下磁盘配额的取消、恢复、关闭、删除的子命令应用:

 xfs_quota -x -c "disable -up" /data/myquota  #暂时取消磁盘配额的用户和目录配额功能

 xfs_quota -x -c "state" /data/myquota  #查看磁盘配额设置信息:

 User quota state on /data/myquota (/dev/sda5)
  Accounting: ON
  Enforcement: OFF  #用户磁盘配额功能已经关闭
  Inode: #67 (2 blocks, 2 extents)
 Group quota state on /data/myquota (/dev/sda5)
  Accounting: OFF
  Enforcement: OFF
  Inode: #68 (2 blocks, 2 extents)
 Project quota state on /data/myquota (/dev/sda5)
  Accounting: ON
  Enforcement: OFF  #目录磁盘配额功能已经关闭
  Inode: #68 (2 blocks, 2 extents)
 Blocks grace time: [7 days]
 Inodes grace time: [7 days]
 Realtime Blocks grace time: [7 days]

 xfs_quota -x -c "enable -p" /data/myquota  #恢复磁盘配额的目录配额功能

 xfs_quota -x -c "state" /data/myquota  #查看磁盘配额的设置信息

 User quota state on /data/myquota (/dev/sda5)
  Accounting: ON
  Enforcement: OFF  #用户的磁盘配额功能还是关闭的
  Inode: #67 (2 blocks, 2 extents)
 Group quota state on /data/myquota (/dev/sda5)
  Accounting: OFF
  Enforcement: OFF
  Inode: #68 (2 blocks, 2 extents)
 Project quota state on /data/myquota (/dev/sda5)
  Accounting: ON
  Enforcement: ON  #目录的磁盘配额功能已经恢复
  Inode: #68 (2 blocks, 2 extents)
 Blocks grace time: [7 days]
 Inodes grace time: [7 days]
 Realtime Blocks grace time: [7 days]

 xfs_quota -x -c "off -p" /data/myquota  #关闭磁盘配额的目录限制功能

 xfs_quota -x -c "state" /data/myquota  #查看磁盘配额的设置

 User quota state on /data/myquota (/dev/sda5)
  Accounting: ON
  Enforcement: OFF
  Inode: #67 (2 blocks, 2 extents)
 Group quota state on /data/myquota (/dev/sda5)
  Accounting: OFF
  Enforcement: OFF
  Inode: #68 (2 blocks, 2 extents)
 Project quota state on /data/myquota (/dev/sda5)
  Accounting: OFF
  Enforcement: OFF  #可以看到磁盘配额的目录配额功能已经关闭
  Inode: #68 (2 blocks, 2 extents)
 Blocks grace time: [7 days]
 Inodes grace time: [7 days]
 Realtime Blocks grace time: [7 days]

 xfs_quota -x -c "report" /data/myquota  #查看磁盘配额的限额数据,这时候就只有用户配额的数据了:

 User quota on /data/myquota (/dev/sda5)
                               Blocks                     
 User ID          Used       Soft       Hard    Warn/Grace     
 ---------- --------------------------------------------------
 root                0          0          0     00 [--------]
 myquota1            0    1048576    1572864     00 [--------]
 ...

 #然后重新挂载文件系统,恢复磁盘配额的目录限制

 umount /data/myquota;mount -a

 xfs_quota -x -c "report -hb" /data/myquota  #查看磁盘配额的限额数据

 User quota on /data/myquota (/dev/sda5)
                        Blocks              
 User ID      Used   Soft   Hard Warn/Grace   
 ---------- ---------------------------------
 root            0      0      0  00 [------]
 myquota1        0     1G   1.5G  00 [------]
 ...
 Project quota on /data/myquota (/dev/sda5)
                        Blocks              
 Project ID   Used   Soft   Hard Warn/Grace   
 ---------- ---------------------------------
 #0              0      0      0  00 [------]
 myquotaprojwww      0     1G   1.5G  00 [------]  #可以看到目录限额设置又恢复了

 #关闭并删除磁盘配额的目录限制

 xfs_quota -x -c "off -up" /data/myquota  #注意这里将用户磁盘配额和目录磁盘限额都关闭了,不然无法使用remove子命令,那怕只删除目录配额设置都不行

 xfs_quota -x -c "remove -p" /data/myquota  #删除磁盘配额的目录限制设置

 umount /data/myquota;mount -a  #重新挂载文件系统

 xfs_quota -x -c "report -hb" /data/myquota  #查看磁盘配额信息

 User quota on /data/myquota (/dev/sda5)
                        Blocks              
 User ID      Used   Soft   Hard Warn/Grace   
 ---------- ---------------------------------
 root            0      0      0  00 [------]
 myquota1        0     1G   1.5G  00 [------]
...
 Project quota on /data/myquota (/dev/sda5)
                        Blocks              
 Project ID   Used   Soft   Hard Warn/Grace   
 ---------- ---------------------------------
 #0              0      0      0  00 [------]
 myquotaprojwww      0      0      0  00 [------]  #这里可以看到磁盘配额的目录配额限制设置是初始数据,之前设置限制被删除了没有恢复

2.6xfs文件系统与ext文件系统的磁盘限额命令及功能对照表

前面说过磁盘配额会因为内核和文件系统系统的差异,出现不同的支持情况,这里我就不演示ext文件系统的磁盘配额操作了,原理都差不多。

设置流程选项 xfs文件系统 ext文件系统
 /etc/fstab参数设置  usrquota/grpquota/prjquota  usrquota/grpquota
 磁盘配额配置文件  不需要  quotacheck
 设置用户/用户组限制值  xfs_quota -x -c "limit [-u | g] ..."  edquota或setquota
 设置宽限时间  xfs_quota -x -c "timer ..."  edquota
 设置目录限制值  xfs_quota -x -c "limit -p ..."  不支持
 查看报告  xfs_quota -x -c "report..."  repquota或quota
 启动与关闭磁盘配额限制  xfs_quota -x -c "[disable|enable]..."  quotaoff,quotaon
 发送警告信息给用户  目前版本不支持  warnquota

 

 三、磁盘阵列RAID

磁盘阵列(RAID)的全称是Redundant Arrays of Inexpensice Disks,即独立冗余磁盘阵列。简单的理解就是将多个磁盘组合在一起当作一个大磁盘设备,通过组合磁盘除了扩大系统的容量的空间,还可以实现提高读写性能和安全性等应用,组合的方式不同形成不同的磁盘阵列模式,不同的磁盘阵列模式实现的功能也不一样,常用的磁盘阵列模式有RAID0、RAID1、RAID2、RAID4、RAID5、RAID6、RAID10、以及RAID7,下面就逐个来了解这些磁盘阵列模式实现的功能和特性:

3.1了解磁盘的一些基础概念和IO相关的问题

条带:把连续的数据分隔成相同大小的数据块,把每段数据分别写入到阵列中的不同磁盘上的方法。简单的说,条带是一种将多个磁盘驱动器合并为一个卷的方法。大部分情况,是通过硬件控制器来完成。

磁盘的IO性能:在计算机系统中CPU的消费数据是由内存提供,为什么不直接由硬盘提供呢?实际上就是因为磁盘的IO性能跟不上CPU的消费速度,当然内存还解决了很多其他问题,但内存本身依然没有解决磁盘本身的IO性能问题。假设现在CPU的工作内容有且只有唯一的一个,就是从硬盘中获取数据,这时候只有一块磁盘,CPU从内存中每读取一段数据就会要等待内存从磁盘中加载一段,因为CPU从内存中读取数据的速度远远大于内存从磁盘中读取数据的速度,也就是说实际上这时候的数据处理效率是取决于磁盘IO的性能。为了提高磁盘IO性能,就提出了将多个磁盘组合在一起,内存同时向多个不同的磁盘获取数据,这样解决了磁盘IO性能低于内存IO性能的问题。

磁盘的数据安全与备份:磁盘的数据安全性问题是由于在任何情况下,不可能保证磁盘不损坏等情况,如果磁盘损坏就意味着磁盘内存储的数据就会被丢失,这对于数据安全来说就是一个几乎无解的问题。为了解决这个问题,我们只能将同一份数据同时存储到多个磁盘上,以此来降低磁盘损坏带来风险,这种处理方式就叫做备份。

外接式磁盘阵列:通过磁盘阵列卡来完成磁盘阵列功能,磁盘阵列卡上面有一块专门的芯片用于处理RAID的任务,系统必须拥有磁盘阵列卡的驱动程序,才能正确的识别到磁盘阵列所产生的磁盘驱动器;

内接式磁盘阵列:主板集成RAID控制器,相当于主板上內置了磁盘阵列卡;

软件式磁盘阵列(Software RAID):无论是外接还是内接磁盘整列,都是基于硬件厂商提供的专用的磁盘整列实现方案,价格会偏贵,所以就有了软件式磁盘阵列,简单的理解就是磁盘阵列驱动程序由操作系统上的软件实现。通过软件仿真数组任务模拟磁盘整列阵列的任务,因此软件会损耗系统资源,比如CPU的运算与IO总线的资源等,所以在生产环境中一般不会使用软件磁盘阵列解决方案。

热备份磁盘:在磁盘损坏后需要将坏掉的磁盘拔除,软后换一块新的磁盘,然后磁盘阵列会主动重建原本坏掉的那块磁盘数据到新的磁盘上,实现恢复磁盘数据。不过这个过程需要停止磁盘阵列的工作,为了解决这个问题,不需要手动拔除磁盘,再接入新的磁盘然后恢复数据,就有热备份磁盘的概念。热备份磁盘是一块不包含在磁盘阵列级别中的磁盘,这块磁盘平时不会被使用,只有当磁盘阵列中出现损坏的磁盘时,磁盘阵列自动接入热备份磁盘,并将损坏的磁盘移除磁盘阵列,然后自动重建数据。

通过上面对磁盘相关问题的介绍会发现,在解决磁盘相关问题的时候都会采用到多个磁盘组合的方式来解决,围绕这些问题和实际需求的解决方案就形成了不同的磁盘组合模式,也就是磁盘阵列模式。当然磁盘阵列除了解决IO性能和安全性问题,还同时具备将单个容量的磁盘通过组合多个磁盘扩大一个文件系统的容量的能力,下面就来具体了解磁盘阵列模式。

3.2磁盘阵列模式

RAID0:等量(stripe)模式,性能最佳,可用空间N*min(S1,S2,...),无容错能力,最少磁盘数2,2+。

使用相同型号与容量的磁盘来组成,如果磁盘容量不同会基于最小容量的磁盘来处理,大于最小容量的磁盘多余空间不能被磁盘阵列使用。这种磁盘整列的数据存储方式是通过将连续的数据条带化依次逐个写入多个磁盘,假设现在由三个磁盘组成的RAID0模式的磁盘阵列,条带化后的数据块有10个,RAID0会将数据块按照1~3或3~1的顺序依次将每个数据块写入不同的磁盘,这样就实现了类似同时由3个磁盘IO通过磁盘阵列组合成一个磁盘IO在工作,提高了磁盘IO的性能。所以RAID0模式的性能也是最好的,但该模式没有数据备份机制,数据风险高。

RAID1:镜像(mirror)模式,完整备份,可用空间1*min(S1,S2,...),有冗余能力可以减低数据风险,最少磁盘数2,2+。

使用相同型号与容量的磁盘来组成,如果磁盘容量不同会基于最小容量的磁盘来处理,大于最小容量的磁盘多余空间不能被磁盘阵列使用。这种磁盘整列的数据存储方式是通过将条带传输过来的每个数据块同时写入两个磁盘,也就是说在两个磁盘中数据是相同的,也就是说至少需要两个磁盘,超过两个磁盘会先存储满两个磁盘然后再使用剩余的其他磁盘空间。这种模式的磁盘性能没有提升,反而会有所下降,因为将数据同时写入两个磁盘时IO性能取决于性能较差的那一个。而磁盘空间利用率会下降一半,且这种磁盘空间冗余的备份降低数据风险并不是一个完善的机制,因为谁又能保证两个磁盘不会同时顺坏呢?

RAID4:校验恢复模式,读写性能提升,有容错能力。

该模需要最少三块磁盘,在一次数据写入时要同时使用三个磁盘,使用两个磁盘基于RAID1的方式来存储数据,第三块基于两块磁盘的数据生成校验码,校验码基于两个磁盘的数据取其异或值。比如前两块存储数据的磁盘数据为1101、0110,那么生成的异或值即校验码就是1011。有了校验码的存在就可以保证当前两块存储数据的磁盘中一个磁盘损坏时,可以使用第三块磁盘中的校验码在新的磁盘中恢复数据,而且两个磁盘来处理IO也可以提高性能,第三块磁盘的校验码又可以有能力恢复前两块磁盘的数据保证数据安全性,这种模式相当于同时实现了RAID0和RAID1的功能,但这种模式存储数据依然不能保证数据百分百安全,因为一旦一个存储磁盘和校验磁盘同时顺坏,数据就没办法恢复了。当在RAID4模式中有一块磁盘损坏时,系统依然能工作,这种工作方式也被称为降级模式,甚至校验盘顺坏都可以降级工作。关于校验模式的性能并不能达到RAID0的性能,因为每一次IO都需要经过校验盘校验,这种模式下校验盘的性能压力是非常大的。

在RAID4模式中还可以使用第四个磁盘作为备用盘,用于自动对损坏的磁盘进行数据恢复,也就是热备分磁盘。

RAID5:性能与数据备份的均衡考虑,读写性能提升,有容错能力。可用空间(N-1)*min(S1,S2,...),最少磁盘数3,3+;最多可容错1块磁盘。

该模式跟RAID4差不多,只是没有独立的校验盘,而是轮流使用每个做磁盘存储校验码,这样就解决了RAID4模式中的校验盘的性能压力问题。校验码的存储方式一半有两种,分别是左对齐或右对齐,左对齐就是比如当写入数据时,第一个磁盘作为第一次前两个数据块的校验盘,第二、三个磁盘存储实际的数据,再依次使用第三个和第四个磁盘作为校验盘,然后再轮流回来使用第一个磁盘作为校验盘,依次往复;右对齐则刚好相反,第一个校验码先写入第三个磁盘,以此往复。左对齐与右对齐有一些性能差异,总体上是左对齐的方式性能稍微好一点,所以大部分情况下都是采用左对齐的校验方式。

总体上来看RAID5相比RAID4的性能好一点,但安全性一样没有差别,依然只能容忍一个磁盘出错,否则数据就无法恢复。

RAID6:偶校验模式,读写性能相比RAID5从理论上来说要弱一点,但容错能力更好,可用空间(N-2)*min(S1,S2,...),最少磁盘数4,4+;最多可容错2块磁盘。

该模式是在基于RAID5的基础上添加一个校验盘,也就是说在RAID6中校验码会被存储到两个磁盘内,也就是偶校验的意思。由于在RAID5的基础上添加了一个校验盘,实际存储数据还是是两个磁盘,RAID6相比RAID5会有两个指标性能下降:IO性能会因为多一个磁盘导致性能下滑、多用一个磁盘存储校验码磁盘总体容量利用率就会下降。这些性能上的损耗,相比数据安全角度来说就提升了很多,所以如果对数据安全要求较高的话RAID6比RAID5更合适。

RAID7:这个模式是一个独立的外接硬件磁盘阵列,它是EMC(易安信)独有的技术,目前最优化的异步高I/O速率和搞数据传输率的磁盘整列模式,RAID7相比前面的模式完全可以将其理解为一个独立存储计算机了,它自带操作系统和管理工具,完全可以独立运行。由于这篇博客的目的是介绍软件式磁盘阵列的相关操作,这里就不对RAID7做更深入的介绍了,有兴趣的话可以自己查资料。

RAID01:这种组合性能上相比RAID0要差,且数据安全几乎没有提升。

先使用RAID0组织磁盘,然后再使用RAID1将RAID0磁盘阵列组合起来,条带切割的数据基于每组RAID0的磁盘个数依次存储,IO性能取决于组织RAID0磁盘的个数,但必须保证有一个完整的RAID0组合,因为在两个RAID0组中数据的条带化切割出来的数据块可能是不同的,所以RAID0组之间不能相互恢复数据。

RAID10:读写新能提升,可用空间N*(S1,S2,...)/2,有容错能力,但每组RAID1最多只能坏一块。

先使用RAID1组织磁盘,然后再使用RAID0将RAID1磁盘阵列组合起来,条带切割的数据先分别按RAID1的组依次存储,IO性能取决于RAID1组的个数,以实现提高磁盘的性能和安全性。

然后还可以采用RAID50的模式,关于这种模式的性能和安全性就不做具体分析了,因为每组RAID5不同磁盘数的组合整体性能是不同的,要看具体应用中有多少个磁盘,要根据具体的总磁盘数来规划。

还有一种独特的磁盘整合模式JBOD,它可以将多个磁盘整合到一起使用,但不做异步IO的性能提升处理也不错安全备份,仅仅是将多个磁盘当作一个大磁盘使用,存储方式是将数据先写满一个磁盘然后再写下一个磁盘,也就是将多个磁盘整合成一个连续的空间使用。

 3.3磁盘阵列模式数据对比

项目RAID0RAID1RAID10RAID5RAID6
最少磁盘数 2 2 4 3 4
最大容错磁盘数(1) n-1 n/2 1 2
数据安全性(1) 完全没有 最佳 最佳 比 RAID5 好
理论写入性能(2) n 1 n/2 <n-1 <n-2
理论读出性能(2) n n n <n-1 <n-2
可用容量(3) n 1 n/2 n-1 n-2
一般应用 强调性能但数据不重要的环境 数据与备份 服务器、云系统常用 数据与备份 数据与备份

 3.4磁盘阵列的设置:MD内核模块及MDADM工具

在操作系统使用的是MD(multi devices)这个内核模块来实现组织多个磁盘作为单个磁盘使用,而各个磁盘阵列都是通用模式,MD就基于这些通用模式提供了管理不同模式的磁盘阵列的工具:mdadm命令,下面就来了解一下这个命令的语法:

 mdadm [mode] <raiddevice> [options] <component-devices>

mdadm的选项及参数解析(这里仅列举了必须和当前示例使用到选项,更多选项参考man文档):

-A,--assemble:装配模式。
-C,--create:创建模式,其中包含可用option即选项有:
  -n:使用n个磁盘设备/块设备;
  -l,-level=[015]:指定要创建的RAID的级别,支持的级别有很多,这里建议是0、1、5;
  -a{yes|no},--auto={yes|no}:自动创建目标RAID设备的设备文件;
  -c,--chunk=Nk:指定块大小;
  -x:指定空闲磁盘个数;
-F,--follow,--monitor:监控模式。
<raiddevice>:磁盘设备名称,比如/dev/md#,需要注意可能因为系统版本差异,系统重启后对磁盘的识别名称可能会发生变化,但可以通过格式化指定卷标等方式来固定。
<component-devices>:任意块设备,也就是说可以使用分区也可以使用整个磁盘来实现磁盘阵列。在实际工作中肯定是使用整个磁盘,但我们在测试实验的时候可以使用磁盘分区来实现。
管理模式:mdadm --manage <磁盘阵列名称> [--add 设备] [--remove 设备] [--fail 设备]
  -f,--fail:将指定的设备设置为错误状态;
  -r,--remove:将指定的设备从这个md中删除;
  -a,--add:将指定的设备添加到md中;
-D,detail <磁盘阵列名称>:用于查看磁盘阵列设备的详细信息;
-S:停止md设备;

3.4.1创建磁盘阵列

假设现在要创建一个10G可用空间的RAID5的磁盘阵列,假设每个磁盘为5G,那就需要3个磁盘作为磁盘阵列数据存储盘,如果实现热备份的话至少需要一个磁盘作为备份磁盘,那么总共需要4个磁盘,假设现在使用磁盘分区来做实验就需要4个5G的磁盘分区,总共需要的实验容量是20G,当然你可以根据自己的实际情况来设计实验空间容量。

 #关于磁盘分区创建这里就不演示了,如果需要了解相关命令及其创建方法,可以参考这篇博客:磁盘与文件系统管理的3.2.2,但需要注意的是这些磁盘分区需要指定分区类型,可以在fdisk的l子命令中查看分区类型的编号,找到Linux raid auto这个类型,然后通过子命令t来使用Linux raid auto的编号fd修改刚刚创建的磁盘分区。

 fdisk -l /dev/sda  #查看刚刚创建磁盘分区的可以看到dsa6~9四个磁盘分区,类型为Linux raid autodetect,下面就通过这四个分区来演示创建磁盘阵列

    设备 Boot      Start         End      Blocks   Id  System
/dev/sda1   *        2048     2099199     1048576   83  Linux
/dev/sda2         2099200    41943039    19921920   8e  Linux LVM
/dev/sda3        41943040    83886079    20971520   83  Linux
/dev/sda4        83886080   251658239    83886080    5  Extended
/dev/sda5        83888128   104882175    10497024   83  Linux
/dev/sda6       104884224   115369983     5242880   fd  Linux raid autodetect
/dev/sda7       115372032   125857791     5242880   fd  Linux raid autodetect
/dev/sda8       125859840   136345599     5242880   fd  Linux raid autodetect
/dev/sda9       136347648   146833407     5242880   fd  Linux raid autodetect

 mdadm -C /dev/md0 -a yes -n 3 -x 1 -l 5 /dev/sda[6,7,8,9]  #创建磁盘阵列,指定磁盘设备名称为/dev/md0,其他子命令和参数参考命令的选项和参数解析

 mdadm: Defaulting to version 1.2 metadata
 mdadm: array /dev/md0 started.  #这是创建成功以后打印的信息;

 mdadm -D /dev/md0  #查看刚刚创建的磁盘阵列详细信息:

 /dev/md0:
           Version : 1.2
     Creation Time : Thu Aug 11 12:45:59 2022    #创建磁盘分区的时间
        Raid Level : raid5               #磁盘阵列模式级别是:RAID 5级别
        Array Size : 10475520 (9.99 GiB 10.73 GB)    #整组RAID的可用容量
     Used Dev Size : 5237760 (5.00 GiB 5.36 GB)    #每块磁盘设备的容量
      Raid Devices : 3                #组成磁盘阵列的磁盘设备数量
     Total Devices : 4                #包括备份磁盘的总磁盘数
       Persistence : Superblock is persistent     

       Update Time : Thu Aug 11 12:46:37 2022
             State : clean                #目前磁盘阵列的使用状态
    Active Devices : 3                 #启动active的设备数量
   Working Devices : 4              #目前用于此阵列的设备数
    Failed Devices : 0                #损坏的设备数
     Spare Devices : 1               #热备份磁盘的数量

            Layout : left-symmetric
        Chunk Size : 512K             #每个块的容量

 Consistency Policy : resync

              Name : localhost.localdomain:0  (local to host localhost.localdomain)
              UUID : b39cd3af:e5326617:baaa28f4:c4c2785f
            Events : 18

    Number   Major   Minor   RaidDevice State
       0       8        6        0      active sync   /dev/sda6
       1       8        7        1      active sync   /dev/sda7
       4       8        8        2      active sync   /dev/sda8

       3       8        9        -      spare   /dev/sda9

 #还可以通过查看/proc/mdstat这个文件来了解当前磁盘阵列信息

 cat /proc/mdstat

 Personalities : [raid6] [raid5] [raid4]
 md0 : active raid5 sda8[4] sda9[3](S) sda7[1] sda6[0]  #active:表示当前磁盘阵列为启动状态,raid5:模式,然后是磁盘阵列使用的设备名称,sda9后面的S表示这个设备为备份磁盘
      10475520 blocks super 1.2 level 5, 512k chunk, algorithm 2 [3/3] [UUU]  #10475520表示当前磁盘阵列拥有的区块数量,使用raid5级别,512k表示每个区块的容量,使用algorithm 2磁盘阵列算法,[m/n]表示此磁盘阵列需要m个设备,且n个正常,[UUU]表示三个设备的启动情况,U表示正常,若为_则表示不正常;
      
 unused devices: <none>

 #磁盘阵列格式化与挂载

 mkfs.xfs /dev/md0  #格式化其实跟磁盘分区格式化没有什么区别,这里我使用了xfs文件系统的默认格式化参数格式化该磁盘阵列

 mkdir /data/raid_md0  #创建一个目录,用于挂载磁盘阵列

 mount /dev/md0 /data/raid_md0  #挂载磁盘阵列

 df -Th /data/raid_md0  #查看磁盘阵列信息:

 文件系统       类型  容量  已用  可用 已用% 挂载点
 /dev/md0       xfs    10G   33M   10G    1% /data/raid_md0

3.4.2模拟磁盘阵列错误的恢复模式

关于模拟错误和恢复使用的mdadm的选项其实就是管理模式的-a、-r、-f,详细参考前面的选项解析,不过为了更好的测试磁盘阵列,可以先向磁盘阵列中添加一些数据,然后将磁盘阵列的某个磁盘或分区手动设置为出错状态,接着就是如何恢复磁盘阵列的具体操作了,下面就来根据这个思路进行实验,具体操作步骤如下:

添加数据及设置磁盘错误:

这个步骤是为了演示恢复磁盘阵列人为的制造一个错误,以此来表示生产环境中的实际错误情况,为恢复磁盘阵列制造一个环境。

 cp /iso/mirroring/custom.iso /data/raid_md0  #给磁盘阵列添加数据(这里可以自行添加一些数据)

 df -Th /data/raid_md0  #查看磁盘阵列的容量相关使用情况

 文件系统       类型  容量  已用  可用 已用% 挂载点
 /dev/md0       xfs    10G  1.1G  9.0G   11% /data/raid_md0

 mdadm --manage /dev/md0 -f /dev/sda7  #将磁盘阵列中的磁盘设备sda7设置为错误状态(不使用--manage选项也行)

 mdadm -D /dev/md0  #查看磁盘阵列详细信息:

 /dev/md0:
           Version : 1.2
     Creation Time : Thu Aug 11 12:45:59 2022
        Raid Level : raid5
        Array Size : 10475520 (9.99 GiB 10.73 GB)
     Used Dev Size : 5237760 (5.00 GiB 5.36 GB)
      Raid Devices : 3
     Total Devices : 4
       Persistence : Superblock is persistent

       Update Time : Fri Aug 12 12:07:20 2022
             State : clean
    Active Devices : 3
   Working Devices : 3
    Failed Devices : 1              #注意这一行信息,这里表示有一个磁盘设备出错了。
     Spare Devices : 0              #热备份磁盘数为0

            Layout : left-symmetric
        Chunk Size : 512K

 Consistency Policy : resync

              Name : localhost.localdomain:0  (local to host localhost.localdomain)
              UUID : b39cd3af:e5326617:baaa28f4:c4c2785f
            Events : 37

    Number   Major   Minor   RaidDevice State
       0       8        6        0      active sync   /dev/sda6
       3       8        9        1      active sync   /dev/sda9    #原来的热备份磁盘sda9成为磁盘阵列的数据盘
       4       8        8        2      active sync   /dev/sda8

       1       8        7        -      faulty   /dev/sda7      #这里的信息也可以看到,现在sda7标记为错误磁盘

上面就是很简单的手动设置磁盘错误,有了错误的磁盘阵列环境,下面就进入恢复磁盘阵列的操作,正常的实际工作中的操作步骤是:1.将错误磁盘设备从磁盘阵列中删除;2.整个Linux系统关机,拔出损坏的磁盘设备,并安装新的磁盘设备,之后再启动;3.将新的磁盘设备添加到磁盘阵列中;

但是需要注意,由于在之前的md中有热备份磁盘,此时的磁盘阵列依然是能正常工作的,在raid 5模式下如果在前面示例的基础上再损坏一个磁盘,磁盘阵列就会进入降级模式,解决方式都一样,坏两个磁盘设备就删除两个然后添加两个新的磁盘设备,这里就不演示了。

恢复磁盘阵列的操作:

 mdadm /dev/md0 -r /dev/sda7  #删除错误磁盘

 #关机、拔除替换设备操作这里就不演示了,因为sda7是我们手动设置错误状态,实际上它并没有损坏,下面就假设我们安装了新的磁盘设备依然叫做sda7,再把新的磁盘设备添加进来即可。

 mdadm /dev/md0 -a /dev/sda7  #将新的磁盘设备添加到当前md中

 mdadm -D /dev/md0  #再来查看磁盘阵列的信息

 /dev/md0:
           Version : 1.2
     Creation Time : Thu Aug 11 12:45:59 2022
        Raid Level : raid5
        Array Size : 10475520 (9.99 GiB 10.73 GB)
     Used Dev Size : 5237760 (5.00 GiB 5.36 GB)
      Raid Devices : 3
     Total Devices : 4
       Persistence : Superblock is persistent

       Update Time : Fri Aug 12 12:44:12 2022
             State : clean
    Active Devices : 3
   Working Devices : 4
    Failed Devices : 0          #可以看到错误磁盘数变成了0
     Spare Devices : 1          #备份磁盘变成了1

            Layout : left-symmetric
        Chunk Size : 512K

 Consistency Policy : resync

              Name : localhost.localdomain:0  (local to host localhost.localdomain)
              UUID : b39cd3af:e5326617:baaa28f4:c4c2785f
            Events : 39

    Number   Major   Minor   RaidDevice State
       0       8        6        0      active sync   /dev/sda6
       3       8        9        1      active sync   /dev/sda9
       4       8        8        2      active sync   /dev/sda8

       5       8        7        -      spare   /dev/sda7    #刚刚添加的新的磁盘就自动被设置为了备份磁盘

以上就是整个磁盘阵列恢复的操作内容,然后前面还有一个非常重要的操作没有演示,就是自动挂载磁盘阵列,下面就来看挂载磁盘阵列的具体操作。

3.4.2开机自动启动RAID并自动挂载

这部分其实跟文件系统的启动自动挂载没有啥区别,同样是在fstab配置文件中配置挂载参数,可以参考之前的文件系统挂载操作,但需要注意的是关于磁盘设备名的系统版本差异自动配置的问题,可以在mdadm.conf配置文件中使用配置设置固定,下面就是具体的操作:

 mdadm -D /dev/md0 | grep -i uuid  #查看磁盘阵列向系统注册的UUID识别码

 UUID : b39cd3af:e5326617:baaa28f4:c4c2785f

 vim /etc/mdadm.conf  #配置mdadm.conf信息,具体配置信息如下:

 ARRAY /dev/md0  UUID=b39cd3af:e5326617:baaa28f4:c4c2785f

 blkid /dev/md0  #查看文件系统的UUID,用于设置磁盘阵列的文件系统的挂载

 /dev/md0: UUID="1aa9019d-9f9a-4c67-a316-4da89d0acc1f" TYPE="xfs"

 vim /etc/fstab  #配置自动挂载参数,将下面一行配置信息添加到fstab中

 UUID=1aa9019d-9f9a-4c67-a316-4da89d0acc1f /data/raid_md0 xfs defaults 0 0

 umount /dev/md0; mount -a  #卸载md0原来的挂载,然后通过配置自动重新挂载

 df -Th /data/raid_md0  #然后通过df基于挂载点查看文件系统信息,如果能查看到磁盘阵列的文件系统信息就说明自动挂载成功

 文件系统       类型  容量  已用  可用 已用% 挂载点
/dev/md0       xfs    10G  1.1G  9.0G   11% /data/raid_md0

自动挂载成功以后,那相关操作有始有终,接下来在演示一下如何关闭和卸载磁盘阵列,这个操作在未来的工作中也是必然会有的。

3.4.3关闭磁盘整列及卸载操作

 umount /data/raid_md0  #卸载

 dd if=/dev/zero of=/dev/md0 bs=1M count=50  #覆盖RAID的metadata以及xfs的superblock

 mdadm -S /dev/md0  #停止md

 mdadm /dev/md0 -r /dev/sda{6,7,8,9}  #将分区或磁盘从磁盘阵列中删除

 vim /etc/fstab  #删除自动挂在配置

 #UUID=1aa9019d-9f9a-4c67-a316-4da89d0acc1f /data/raid_md0 xfs defaults 0 0

 vim /etc/mdadm.conf  #删除md的配置文件

 #ARRAY /dev/md0  UUID=b39cd3af:e5326617:baaa28f4:c4c2785f

 四、逻辑卷管理器LVM

4.1什么是逻辑卷管理器?

所谓逻辑卷管理器简单的来理解就是将几个物理磁盘或分区(PV)通过软件组合成一个看起来的大磁盘(卷组:VG),然后将这个大磁盘在经过划分成可用的分区(逻辑卷:LV),然后挂载使用,下面通过一些概念来了解具体内容:

1.物理卷(Physical Volume,PV):基于块设备或分区通过调整系统标识(system ID)称为8e(LVM的标识符),然后再通过pvcreate命令将它转换成LVM最底层的物理卷(PV),调整system ID的方式可以通过gdisk或fdisk实现(详细参考:磁盘与文件系统管理的3.2.2)。

2.卷组(Volume Group,VG):所谓的LVM大磁盘就是将多个PV整合成一个VG,所以VG就是LVM组合起来的大磁盘。这个大磁盘的容量在32位的Linux中LV最大支持65534个PE,如果使用PE默认的容量4MB的情况下,最大容量则仅达到256GB,不过现在基本都是64位系统,LV几乎没有容量限制了。

3.物理扩展快(Physical Extent,PE):所谓物理扩展快(PE)就是LVM中的最小存储数据单元,类似磁盘上的扇区或文件系统中的块(block)。LVM默认使用4MB的PE数据块,而LVM的LV在32位系统中最多支持65534个PE(lvm1的格式),因此默认的LVM的LV会有4MB*65534/(1024M/G)=256GB,所以调整PE大小可以调整LVM的最大容量,而在64位系统中(lvm2的各项格式功能)不再限制LV中的PE数量,所以64位系统中LVM可以理解为没有容量限制。

4.逻辑卷(Logical Volume,LV):所谓逻辑卷(LV)就是可以被格式化使用类似分区的东西,可以看作是卷组(VG)这个大磁盘切割出来的分区。为了方便用户使用LVM来管理系统,LV的设备文件名通常为【/dev/vgname/lvname】的样式,建议尽量遵循这个范式方便管理。

可以通过下面这些示例来更清晰的理解逻辑卷管理:

 

使用LVM的好处,可以灵活的调整文件文件系统的容量,传统文件系统基于分区,不同分区相对独立,在划分磁盘容量时可能因为后期的使用出现空间利用不平衡,而使用LVM的LV作为文件系统的载体,可以跨分区使用磁盘空间,提高磁盘空间的利用效率。

4.2创建LVM

刚好前面磁盘整列实验有四个磁盘分区sda{6,7,8,9},就使用这些磁盘分区做创建VG示例的PV,为了完整的演示LVM的基本特性与其功能,示例包括创建LVM、LVM扩容、LVM缩小容量。

4.2.1修改分区的system ID修改为Linux LVM

 fdisk -l /dev/sda  #查看分区信息

    设备 Boot      Start         End      Blocks   Id  System
 /dev/sda1   *        2048     2099199     1048576   83  Linux
 /dev/sda2         2099200    41943039    19921920   8e  Linux LVM
 /dev/sda3        41943040    83886079    20971520   83  Linux
 /dev/sda4        83886080   251658239    83886080    5  Extended
 /dev/sda5        83888128   104882175    10497024   83  Linux
 /dev/sda6       104884224   115369983     5242880   fd  Linux raid autodetect
 /dev/sda7       115372032   125857791     5242880   fd  Linux raid autodetect
 /dev/sda8       125859840   136345599     5242880   fd  Linux raid autodetect
 /dev/sda9       136347648   146833407     5242880   fd  Linux raid autodetect

 #修改分区的类型:system ID

 fdisk /dev/sda

 命令(输入 m 获取帮助):t  #修改磁盘分区类型
分区号 (1-9,默认 9):6    #指定修改磁盘分区的分区号
Hex 代码(输入 L 列出所有代码):8e  #指定分区类型编号为8e,8e是Linux LVM类型的编号,可以使用l子命令查看system id
已将分区“Linux raid autodetect”的类型更改为“Linux LVM”

 ......  #使用同样的方法将磁盘分区7、8、9一并修改,然后使用w命令写入退出

 partprobe -s  #更新分区表信息

 fdisk -l /dev/sda  #再查看确认分区信息

    设备 Boot      Start         End      Blocks   Id  System
/dev/sda1   *        2048     2099199     1048576   83  Linux
/dev/sda2         2099200    41943039    19921920   8e  Linux LVM
/dev/sda3        41943040    83886079    20971520   83  Linux
/dev/sda4        83886080   251658239    83886080    5  Extended
/dev/sda5        83888128   104882175    10497024   83  Linux
/dev/sda6       104884224   115369983     5242880   8e  Linux LVM  #==>可以看到分区类型已经修改成了LVM类型
/dev/sda7       115372032   125857791     5242880   8e  Linux LVM
/dev/sda8       125859840   136345599     5242880   8e  Linux LVM
/dev/sda9       136347648   146833407     5242880   8e  Linux LVM

4.2.2基于磁盘分区创建物理卷:PV

创建PV直接使用pvcreate即可,管理PV的常用命令包括:pvcreate(创建物理卷)、pvscan(查看当前系统中的PV的磁盘)、pvdisplay(显示当前系统上面的PV状态,即详细信息)、pvremove(将PV属性删除,让该分区不具有PV属性)等,下面来看具体的创建PV的相关操作和一些解决问题的方法:

 pvscan  #列出系统上的pv,CentOS发行版默认会安装LVM所需要软件,所以就会有pv工具及LVM相关的其他工具命令

 PV /dev/sda2   VG centos          lvm2 [<19.00 GiB / 0    free]  #安装系统时就是用了LVM,所以就会有这个/dev/sda2的存在
  Total: 1 [<19.00 GiB] / in use: 1 [<19.00 GiB] / in no VG: 0 [0   ]

-------------非必要步骤----------------------------------------------------------------------------------

 yum -y install lvm2  #如果系统上没有LVM软件可以使用这行命令安装

-------------------------------------------------------------------------------------------------------------

 pvcreate /dev/sda{6,7,8,9}  #创建PV

 Device /dev/sda6 excluded by a filter.  #弹出这个表示没成功,因为我之前的分区信息没有擦除,可以使用下面的方法来解决,如果创建成功就跳过下面这个步骤

 ...

-------------非必要步骤-----------------------------------------------------------------------------------

 parted /dev/sda6

 输入:mklabel msdos  #通过重建磁盘标签(分区表),可以清除之前的数据(原理分析可以参考:https://www.cnblogs.com/saryta/p/12979028.html

 输入:y  #如果没有报错就按照这个步骤继续就可以了,但很遗憾我这里报了错误: Partition(s)on /dev/sda9 have been written, but we have been unable to inform the kernel of the change, probably because it/they are in use.  As a result, the old partition(s) will remain in use.  You should reboot now before making further
changes.  #==>还好问题不大,这里是说重建分区表已经写入了,只是无法通知系统内核,重启以后就可以了(重启之前将你要sda7、8、9也同样操作一边)

 输入:q

------------------------------------------------------------------------------------------------------------

 #上面操作成功或重启系统之后就可以继续下面的操作了,以上的问题解决方案感觉不是很合理,如果有更合理的方案后续来补充

 pvcreate /dev/sda{7,8,9}  #然后再来创建PV

 WARNING: dos signature detected on /dev/sda7 at offset 510. Wipe it? [y/n]: y
  Wiping dos signature on /dev/sda7.
WARNING: dos signature detected on /dev/sda8 at offset 510. Wipe it? [y/n]: y
  Wiping dos signature on /dev/sda8.
WARNING: dos signature detected on /dev/sda9 at offset 510. Wipe it? [y/n]: y
  Wiping dos signature on /dev/sda9.
  Physical volume "/dev/sda7" successfully created.
  Physical volume "/dev/sda8" successfully created.
  Physical volume "/dev/sda9" successfully created.  #===>这次就成功了。

 pvscan  #列出pv,通过下面的pv列表信息可以看到创建的pv

  PV /dev/sda2   VG centos          lvm2 [<19.00 GiB / 0    free]
  PV /dev/sda9                      lvm2 [5.00 GiB]
  PV /dev/sda6                      lvm2 [5.00 GiB]
  PV /dev/sda8                      lvm2 [5.00 GiB]
  PV /dev/sda7                      lvm2 [5.00 GiB]
  Total: 5 [<39.00 GiB] / in use: 1 [<19.00 GiB] / in no VG: 4 [20.00 GiB]

 pvdisplay /dev/sda6  #查看详细的pv信息

  "/dev/sda6" is a new physical volume of "5.00 GiB"
  --- NEW Physical volume ---
  PV Name               /dev/sda6  #实际分区设备名称
  VG Name                     #因为尚未分配到具体的VG,所以这里是空白的
  PV Size               5.00 GiB  #容量大小
  Allocatable           NO    #是否已分配
  PE Size               0       #在此pv内的PE大小
  Total PE              0     #共划分出的PE个数
  Free PE               0     #没有被LV用掉的PE
  Allocated PE          0    #尚可分配出去的PE数量
  PV UUID               JUgZVi-Jfph-Z1j5-qMyq-J4th-wqQM-2cvDRa  #当前pv的唯一标识

4.2.3创建卷组:VG

创建VG使用vgcreate即可,管理VG的的常用命令包括:vgcreate(创建卷组)、vgdisplay(显示系统上的VG状态,即详细信息)、vgextend(在VG内增加额外的PV)、vgreduce(在VG内删除PV)、vgchange(设置VG是否启动:active)、vgremove(删除VG)等,下面先来看创建GV的命令语法:

 vgcreate [-s N[mgt] ] VG名称 PV名称  #创建VG的简化语法,详细的语法参考man文档

vgcreate命令的选项及参数解析:

-s:设置PE的一些参数,后面接PE大小(size),单位可以是m、g、t;

创建VG的具体操作:

 vgcreate myvg /dev/sda{6,7,8}  #这里我没有设置PE大小,就表示使用默认的PE大小,创建成功后会打印出一些提示:

 Volume group "myvg" successfully created

 vgdisplay myvg  #查看VG的状态,即详细信息

  --- Volume group ---
  VG Name               myvg
  System ID             
  Format                lvm2
  Metadata Areas        3
  Metadata Sequence No  1
  VG Access             read/write
  VG Status             resizable
  MAX LV                0
  Cur LV                0
  Open LV               0
  Max PV                0
  Cur PV                3
  Act PV                3
  VG Size               <14.99 GiB  #这里表示的是VG容量
  PE Size               4.00 MiB  #这里表示的是当前VG中的PE的大小
  Total PE              3837  #这里表示的是PE的数量
  Alloc PE / Size       0 / 0   
  Free  PE / Size       3837 / <14.99 GiB  #可以分配给LV的PE数量及可以分配给LV的VG容量
  VG UUID               y4fbte-BLu7-VN1y-ewjV-OGVh-p6yA-IhDhNb  #当前VG的唯一标识符

 pvdisplay /dev/sda6  #再来查看sda6的PV详细信息,看看它的变化

  --- Physical volume ---
  PV Name               /dev/sda6
  VG Name               myvg
  PV Size               5.00 GiB / not usable 4.00 MiB
  Allocatable           yes
  PE Size               4.00 MiB  #可以看到PE的大小变成了4MiB
  Total PE              1279     #当前PV的PE个数是1279个
  Free PE               1279    #没有被LV用掉的PE的个数也是1279个,因为当前PV所属的VG还没有划分LV
  Allocated PE          0
  PV UUID               JUgZVi-Jfph-Z1j5-qMyq-J4th-wqQM-2cvDRa

 #如果创建VG以后又要扩充VG容量,可以通过vgextend myvg 用于扩充容量的PV的磁盘名称,这里就不演示了,后续对LV扩容还会用到

4.2.4创建逻辑卷:LV

创建LV使用lvcreate即可,管理LV的常用工具命令包括:lvcreate(创建LV)、lvscan(查看当前系统上的LV)、lvdisplay(查看系统上LV的状态,即详细信息)、lvextend(增加LV的容量)、lvreduce(减少LV的容量)、lvremove(删除LV)、lvresize(对LV容量大小进行调整)等,下面先来看创建LV的命令语法:

 lvcreate [-L N[mgt] ] [-n LV名称] VG名称

 lvcreate [-l N ] [-n LV名称] VG名称  #lvcreate的选项有很多,这里仅列出创建LV必须用到的选项,更多的内容自行参考man文档

lvcreate的选项及参数解析:

-L:后面接容量,用于指定LV的容量,容量单位可以是M、G、T等,需要注意的是最小单位容量为PE的大小,因此容量大小必须是PE的倍数,如果不符合系统会自行计算相近的容量;
-l:后面接PE的个数、VG的容量比等,而不是容量,通过PE的个数、VG容量比等自行计算LV的容量;
-n:后面接创建LV的名称;

创建LV的具体操作:

 lvcreate -L 10G -n mylv myvg  #在myvg卷组上划分一个10G大小的逻辑卷mylv,创建成功以后会打印以下信息:

 Logical volume "mylv" created.

 ls /dev/mapper/  #打印出来的文件名有:centos-root  centos-swap  control  myvg-mylv,可以看到刚刚创建的逻辑卷myvg-mylv,这里实际上只是mylv的符号链接,实际文件是/dev/mapper/myvg/mylv

 mke2fs -t ext4 -b 1024 -L MYLV /dev/myvg/mylv  #将逻辑卷格式化为一个ext4文件系统,需要注意的是磁盘文件系统的块大小可以指定为比PE小,PE并不会限制文件系统的最小容量,文件系统的最小限制还是物理扇区的容量

 mke2fs 1.42.9 (28-Dec-2013)
文件系统标签=MYLV
OS type: Linux
块大小=1024 (log=0)
分块大小=1024 (log=0)
Stride=0 blocks, Stripe width=0 blocks
655360 inodes, 10485760 blocks
524288 blocks (5.00%) reserved for the super user
第一个数据块=1
Maximum filesystem blocks=44040192
1280 block groups
8192 blocks per group, 8192 fragments per group
512 inodes per group
Superblock backups stored on blocks:
    8193, 24577, 40961, 57345, 73729, 204801, 221185, 401409, 663553,
    1024001, 1990657, 2809857, 5120001, 5971969

Allocating group tables: 完成                            
正在写入inode表: 完成                            
Creating journal (32768 blocks): 完成
Writing superblocks and filesystem accounting information: 完成

 mkdir /data/mylv  #创建一个目录,用于挂载mylv文件系统

 mount /dev/myvg/mylv /data/mylv  #挂载文件系统

 df -Th /data/mylv  #查看各个挂载的文件系统信息:

 文件系统              类型  容量  已用  可用 已用% 挂载点
 /dev/mapper/myvg-mylv ext4  9.9G  3.8M  9.4G    1% /data/mylv

 cd /data/mylv  #进入到各个挂载的目录

 cp /etc/issue ./  #拷贝一个文件到这个目录下,看看文件系统是否能正常使用

 ls -l  #查看mylv下的文件信息:

 -rw-r--r--. 1 root root    23 8月  15 09:41 issue    #==>能看到这是各个复制进来的文件,说明文件系统没有问题
 drwx------. 2 root root 12288 8月  15 07:17 lost+found

以上就是创建LVM的全部过程,不过前面还说过LV在创建后还可以调整容量,这也是逻辑卷的最重要的特性,所以下面来看看LV的容量调整操作。

4.3调整LV的容量

调整LV的容量在实际应用中大部分情况下都是放大容量,当然也存在缩小容量的情况,如果要放大LV的容量那事先必须确认LV所属VG有可用剩余容量供放大LV容量使用,如果没有的话还需要给VG添加PV来扩充VG的容量。而缩小LV容量则是要确定当前LV的容量使用还有剩余,操作逻辑与放大刚刚相反,下面通过一些具体示例来演相关操作:

 lvextend -L [+]N[mgt] /dev/vgname/lvname  #扩充LV容量的命令lvextend最简语法,该命令还有很多其他选项和参数,详细参考man文档。当然使用lvresize命令实现扩容也行,如果想测试自行参考man文档

在lvextend命令中需要注意的是在设置扩充容量时的值前面是否使用[+]的区别,使用[+]表示在当前LV容量的基础上增加多少容量,不使用[+]表示将当前LV的容量增加到多大的容量。然后就是尽量不要随意调整LV的容量,如果需要调整建议备份好当前的数据,避免因为调整出错导致数据丢失,特别是缩小LV的容量一定要慎重,至于这其中可能发生问题的原因后期再在相关文件系统深度解析中介绍。

使用VG中现有空闲容量放大LV的容量

假设现在的需求是将mylv的容量扩大到12G,而当前LV的容量是10G,那么需要增加的容量就是2G。

 vgdisplay myvg  #查看当前LV所属VG的状态信息,确定是否有足够的可用扩容空间

   --- Volume group ---
  VG Name               myvg
  System ID             
  Format                lvm2
  Metadata Areas        3
  Metadata Sequence No  2
  VG Access             read/write
  VG Status             resizable
  MAX LV                0
  Cur LV                1
  Open LV               1
  Max PV                0
  Cur PV                3
  Act PV                3
  VG Size               <14.99 GiB
  PE Size               4.00 MiB
  Total PE              3837
  Alloc PE / Size       2560 / 10.00 GiB
  Free  PE / Size       1277 / <4.99 GiB  #==>当前VG剩余空间还有4.99,说明将mylv扩容到12G足够
  VG UUID               y4fbte-BLu7-VN1y-ewjV-OGVh-p6yA-IhDhNb

 lvextend -L 12G /dev/myvg/mylv  #实现将mylv的容量扩充到12G

 lsblk  #查看磁盘分区信息:

NAME            MAJ:MIN RM  SIZE RO TYPE MOUNTPOINT
sda               8:0    0  120G  0 disk
├─sda1            8:1    0    1G  0 part /boot
├─sda2            8:2    0   19G  0 part
│ ├─centos-root 253:0    0   17G  0 lvm  /
│ └─centos-swap 253:1    0    2G  0 lvm  [SWAP]
├─sda3            8:3    0   20G  0 part /iso
├─sda4            8:4    0    1K  0 part
├─sda5            8:5    0   10G  0 part /data/myquota
├─sda6            8:6    0    5G  0 part
│ └─myvg-mylv   253:2    0   12G  0 lvm  /data/mylv  #==>从磁盘分区信息中可以看到LV已经扩充到了12G
├─sda7            8:7    0    5G  0 part
│ └─myvg-mylv   253:2    0   12G  0 lvm  /data/mylv
├─sda8            8:8    0    5G  0 part
│ └─myvg-mylv   253:2    0   12G  0 lvm  /data/mylv
└─sda9            8:9    0    5G  0 part

 df -Th /data/mylv  #查看文件系统信息:

文件系统              类型  容量  已用  可用 已用% 挂载点
/dev/mapper/myvg-mylv ext4  9.9G  3.8M  9.4G    1% /data/mylv  #文件系统的容量还没有变化,假设原因是因为文件系统没有重新挂载

 umount /dev/myvg/mylv;mount /dev/myvg/mylv /data/mylv;df -Th /data/mylv  #重新挂载文件系统后再查看文件系统的信息

文件系统              类型  容量  已用  可用 已用% 挂载点
/dev/mapper/myvg-mylv ext4  9.9G  3.8M  9.4G    1% /data/mylv  #==>很遗憾,文件系统的容量依然没有变化

 #这种情况实际上因为前面仅仅相当于是扩充了磁盘分区的LV的容量,而文件系统的容量并不会因为LV的容量变化而自动变化,还需要手动调整文件系统的容量,因为这里使用的是ext4的文件系统,就需要使用resize2fs命令来实现文件系统的扩容,而如果是xfs文件系统xfs_growfs实现文件系统的扩容,命令的具体语法请查看man文档。

 resize2fs /dev/myvg/mylv  #实现文件系统扩容,不过在实现扩容之前建议先卸载文件系统(避免出错),下面是扩容成功后打印出来的信息:

resize2fs 1.42.9 (28-Dec-2013)
Filesystem at /dev/myvg/mylv is mounted on /data/mylv; on-line resizing required
old_desc_blocks = 80, new_desc_blocks = 96  
The filesystem on /dev/myvg/mylv is now 12582912 blocks long.

df -Th /dev/myvg/mylv  #查看mylv文件系统信息

文件系统              类型  容量  已用  可用 已用% 挂载点
/dev/mapper/myvg-mylv ext4   12G  3.6M   12G    1% /data/mylv  #==>这时候地文件容量就被真正扩充到了12G

当有需求扩大LV容量超过VG容量时,应该先给添加物理卷

假设现在的需求是将刚刚扩容到12G的mylv再次扩容到16G,而前面的示例中实现的VG容量只有14.99G,拿这种情况就只能先给VG添加物理卷,然后再扩容LV,下面来看具体的操作命令:

 pvscan  #查看当前系统上的PV物理卷

  PV /dev/sda2   VG centos          lvm2 [<19.00 GiB / 0    free]
  PV /dev/sda6   VG myvg            lvm2 [<5.00 GiB / 0    free]
  PV /dev/sda7   VG myvg            lvm2 [<5.00 GiB / 0    free]
  PV /dev/sda8   VG myvg            lvm2 [<5.00 GiB / <2.99 GiB free]
  PV /dev/sda9                      lvm2 [5.00 GiB]   #==>这里sda9是之前创建的PV剩余没有被添加到VG中的一个分区
  Total: 5 [38.98 GiB] / in use: 4 [33.98 GiB] / in no VG: 1 [5.00 GiB]

 vgextend myvg /dev/sda9  #将sda9添加到VG中,添加成功后会打印这一行信息:Volume group "myvg" successfully extended

 vgdisplay myvg  #查看VG的状态信息

 --- Volume group ---
  VG Name               myvg
  System ID             
  Format                lvm2
  Metadata Areas        4
  Metadata Sequence No  4
  VG Access             read/write
  VG Status             resizable
  MAX LV                0
  Cur LV                1
  Open LV               0
  Max PV                0
  Cur PV                4
  Act PV                4
  VG Size               19.98 GiB
  PE Size               4.00 MiB
  Total PE              5116
  Alloc PE / Size       3072 / 12.00 GiB  #这里是当前卷组已分配的PE个数和容量值
  Free  PE / Size       2044 / 7.98 GiB  #这里表示的是当前卷组未分配的PE个数和容量值
  VG UUID               y4fbte-BLu7-VN1y-ewjV-OGVh-p6yA-IhDhNb

 lvextend -L 16G /dev/myvg/mylv  #将LV的容量扩充到16G,到这里就与上一个示例一样了

 umount /dev/myvg/mylv  #卸载挂载(不然可能会出问题)

 resize2fs /dev/myvg/mylv  #然后再将文件系统进行扩容

 mount /dev/myvg/mylv /data/mylv  #然后在将扩容好的文件系统挂载到系统上

 df -Th /dev/myvg/mylv  #查看挂在后的文件系统信息

 文件系统              类型  容量  已用  可用 已用% 挂载点
 /dev/mapper/myvg-mylv ext4   16G  3.1M   15G    1% /data/mylv  #文件系统已经扩容到了16G

缩小LV的容量

前面说过缩小LV容量与扩充LV容量的逻辑刚好相反,具体来说就是在缩小LV之前,一定要先缩减文件系统的容量,然后才能缩小LV的容量,再在缩小LV的基础上如果VG未被LV使用的容量达到了VG某个物理卷容量的话,才可以考虑从VG中删除某个PV。从VG中删除PV之前还有一个操作就是需要将要删除的PV数据移动到其他磁盘上,这个操作荣光物理卷管理命令pvmove时间,具体操作见示例。

假设现在的需求是文件系统MYLV可以缩减到14G,按照测试的VG和PV容量来看就可以考虑删除一个PV,下面来看具体操作:

 umount /dev/myvg/mylv  #缩小LV之前一定要卸载文件系统,如果是实际应用中最好应该考虑配分数据,因为风险真不好说

 e2fsck -f /dev/myvg/mylv  #强制监测修复当前文件系统,保证文件数据不出错,当检查没有问题以后才可以操作文件系统的缩减,如果是xfs文件系统要使用相对应的工具命令执行这个操作。

 第一步: 检查inode,块,和大小
 第二步: 检查目录结构
 第3步: 检查目录连接性
 Pass 4: Checking reference counts
 第5步: 检查簇概要信息
 MYLV: 12/1048576 files (0.0% non-contiguous), 304079/16777216 blocks

 resize2fs /dev/myvg/mylv 14G  #执行文件系统缩减,还是一样如果是xfs文件系统或其他文件系统使用相对应的命令工具执行这个操作。

 lvreduce -L 14G /dev/myvg/mylv  #执行LV的缩减操作

  WARNING: Reducing active logical volume to 14.00 GiB.
  THIS MAY DESTROY YOUR DATA (filesystem etc.)
 Do you really want to reduce myvg/mylv? [y/n]: y  #这里会询问是否执行缩减操作,确认操作没有问题使用y确认执行,操作有风险,使用请谨慎
  Size of logical volume myvg/mylv changed from 16.00 GiB (4096 extents) to 14.00 GiB (3584 extents).
  Logical volume myvg/mylv successfully resized.

 df -Th /data/mylv  #再来查看文件系统的信息

 文件系统              类型  容量  已用  可用 已用% 挂载点
 /dev/mapper/myvg-mylv ext4   14G  3.3M   14G    1% /data/mylv  #可以看到文件系统容量已经缩减到了14G

 #然后还应该通过查看文件信息和文件内容来确认缩减操作后,数据是否还能被正常使用

 ls -l /data/mylv  #查看文件系统的文件

 -rw-r--r--. 1 root root    23 8月  15 09:41 issue
drwx------. 2 root root 12288 8月  15 07:17 lost+found

 cat /data/mylv/issue  #测试读取文件系统中的文件数据,如果文件数据还能被正常读取出来就说明应该是没问题的;

 \S
 Kernel \r on an \m

 pvdisplay  #查看当前系统上的PV信息,找到符合缩减需求的容量的磁盘移除,由于测试的数据较少,经查实数据存储在/dev/sda8上,这里用删除这个PV来测试

 pvmove /dev/sda8  #将数据从这个PV上移除,指定的时候它会输出数据移动进度:
  /dev/sda8: Moved: 0.19%
  /dev/sda8: Moved: 10.14%
  /dev/sda8: Moved: 100.00%

 vgreduce myvg /dev/sda8  #将sda8出myvg上删除,并会打印以下信息

 Removed "/dev/sda8" from volume group "myvg"

 lsblk  #查看磁盘信息:

 sda               8:0    0  120G  0 disk
├─sda1            8:1    0    1G  0 part /boot
├─sda2            8:2    0   19G  0 part
│ ├─centos-root 253:0    0   17G  0 lvm  /
│ └─centos-swap 253:1    0    2G  0 lvm  [SWAP]
├─sda3            8:3    0   20G  0 part /iso
├─sda4            8:4    0    1K  0 part
├─sda5            8:5    0   10G  0 part /data/myquota
├─sda6            8:6    0    5G  0 part
│ └─myvg-mylv   253:2    0   14G  0 lvm  /data/mylv
├─sda7            8:7    0    5G  0 part
│ └─myvg-mylv   253:2    0   14G  0 lvm  /data/mylv
├─sda8            8:8    0    5G  0 part   #可以看到磁盘已经从myvg中删除了
└─sda9            8:9    0    5G  0 part
  └─myvg-mylv   253:2    0   14G  0 lvm  /data/mylv

 vgdisplay myvg  #查看myvg的详细信息:

  --- Volume group ---
  VG Name               myvg
  System ID             
  Format                lvm2
  Metadata Areas        3
  Metadata Sequence No  16
  VG Access             read/write
  VG Status             resizable
  MAX LV                0
  Cur LV                1
  Open LV               1
  Max PV                0
  Cur PV                3
  Act PV                3
  VG Size               <14.99 GiB  #可以看到VG的容量减少了
  PE Size               4.00 MiB
  Total PE              3837
  Alloc PE / Size       3584 / 14.00 GiB
  Free  PE / Size       253 / 1012.00 MiB
  VG UUID               y4fbte-BLu7-VN1y-ewjV-OGVh-p6yA-IhDhNb

 cat /data/mylv/issue  #通过读取逻辑卷中的文件数据来确认文件系统中的数据是否正确

 \S
Kernel \r on an \m  #==>数据能正常读取,说明数据没有问题

 #如果被移除的PV磁盘分区不再作为物理卷使用,还可以通过pvremove来删除pv属性

 pvscan  #先来查看当前系统上的PV信息

 PV /dev/sda2   VG centos          lvm2 [<19.00 GiB / 0    free]
  PV /dev/sda6   VG myvg            lvm2 [<5.00 GiB / 0    free]
  PV /dev/sda7   VG myvg            lvm2 [<5.00 GiB / 0    free]
  PV /dev/sda9   VG myvg            lvm2 [<5.00 GiB / 1012.00 MiB free]
  PV /dev/sda8                      lvm2 [5.00 GiB]      #这些信息表示当前sda8虽然不再属于myvg卷组,但依然还是PV
  Total: 5 [38.98 GiB] / in use: 4 [33.98 GiB] / in no VG: 1 [5.00 GiB]

 pvremove /dev/sda8  #删除PV属性

 pvscan  #再来查看当前系统上的PV信息,通过下面的信息可以看到sda8已经不再是PV了,当然如果要使用它还需要调整使用它需要的system类型。

  PV /dev/sda2   VG centos          lvm2 [<19.00 GiB / 0    free]
  PV /dev/sda6   VG myvg            lvm2 [<5.00 GiB / 0    free]
  PV /dev/sda7   VG myvg            lvm2 [<5.00 GiB / 0    free]
  PV /dev/sda9   VG myvg            lvm2 [<5.00 GiB / 1012.00 MiB free]
  Total: 4 [33.98 GiB] / in use: 4 [33.98 GiB] / in no VG: 0 [0   ]

以上就是LVM容量调整的全部操作示例,但LVM除了通过手动调整容量,还可以LVM thin Volume自动调整磁盘使用率,下面就来看如何实现。

4.4动态自动调整LVM的使用率

所谓动态自动调整LVM的使用率是基于LVM thin Volume的存储虚拟化,简单的来理解就是虚拟一个大容量的磁盘(虚拟LV设备),而实际提供存储空间根据实际使用空间需要来提供(thin pool LV设备)。thin pool LV是提供真实容量的逻辑卷,用于实际的数据存储;虚拟LV设备是对用户提供存储服务的逻辑卷,这个逻辑卷的容量可以随意设置,但需要注意如果虚拟LV设备存储的数据超过实际提供存储容量的thin pool LV的话,可能会导致thin pool LV损坏,所以在实际应用中要注意实际存储数据的thin pool LV的使用情况,要及时给thin pool LV扩充容量保证数据能被正确存储。

LVM thin Volume的应用场景比如有网盘服务,比如用户向你购买了10T的容量,但他实际上现在只是用了1T,这时候你就可以给他提供一个看起来有10T的虚拟LV磁盘,而实际给他分配一个实际容量为2T的thin pool LV设备,当用户的容量使用增长到接近2T的时候在帮助他扩容一下thin pool LV设备即可。

创建thin pool的命令还是lvcreate,只是要使用T这个选线来实现,即thin或thinpool小容量词的意思;创建虚拟LV设备同样还是lvcreate命令,使用的选项是V,即virtualsize虚拟容量值的意思。下面是它们的语法:

 lvcreate -L N[mgt] -T VGName/thinpoolname  #创建thin pool的语法,VGName表示卷组,thinpoolname表示创建的thin pool的名称,-L表示thin pool从卷组中实际分配的容量

 lvcreate -V N[mgt] -T VGName/thinpoolname -n lvname  #表示基于VGname的卷组的thinpoolname创建虚拟逻辑卷lvname,-V表示指定虚拟逻辑卷容量

下面就通过一个简单的示例来演试一下创建虚拟逻辑卷以及容量调整的相关操作,需求是基于一个1G的thin pool创建一个10G的虚拟LV,并格式化成xfs文件系统,然后挂在使用500M实际容量,再给thin pool扩容到5G的实际使用容量。

相关演示操作还是基于前面的myvg卷组,由于前面将sda8从myvg中删除并清楚了pv属性,而且当前myvg的容量无法提供足够的实验容量,所以将要将sda8添加到myvg这个卷组中,再演示这部分的操作:

 pvcreate  /dev/sda8  #重新将sda8创建为PV,创建成功后打印出:Physical volume "/dev/sda8" successfully created.

 vgextend myvg /dev/sda8  #使用sda8这个PV给myvg这个卷组扩容,扩容成功后打印出:Volume group "myvg" successfully extended

 -----------上面两行命令是为演示示例做环境准备的,下面才是示例的真正内容-------------------------------------------------------------

 vgdisplay myvg  #查看卷组的状态信息:

 --- Volume group ---
  VG Name               myvg
  System ID             
  Format                lvm2
  Metadata Areas        4
  Metadata Sequence No  17
  VG Access             read/write
  VG Status             resizable
  MAX LV                0
  Cur LV                1
  Open LV               0
  Max PV                0
  Cur PV                4
  Act PV                4
  VG Size               19.98 GiB
  PE Size               4.00 MiB
  Total PE              5116
  Alloc PE / Size       3584 / 14.00 GiB
  Free  PE / Size       1532 / 5.98 GiB
  VG UUID               y4fbte-BLu7-VN1y-ewjV-OGVh-p6yA-IhDhNb

 lvcreate -L 1G -T myvg/mytpool  #创建thin pool LV,名称设置为mytpool,创建成功以后会打印出下面这些信息:

 Thin pool volume with chunk size 64.00 KiB can address at most 15.81 TiB of data.
  Logical volume "mytpool" created.

 lvdisplay /dev/myvg/mytpool  #查看各个创建的thin pool LV:mytool的详细状态信息

   --- Logical volume ---
  LV Name                mytpool
  VG Name                myvg
  LV UUID                u0fVuo-QRsb-s7tL-bMll-1cZf-Ayjd-MUuhJN
  LV Write Access        read/write
  LV Creation host, time localhost.localdomain, 2022-08-16 22:01:13 +0800
  LV Pool metadata       mytpool_tmeta
  LV Pool data           mytpool_tdata
  LV Status              available
  # open                 0
  LV Size                1.00 GiB
  Allocated pool data    0.00%
  Allocated metadata     10.94%
  Current LE             256
  Segments               1
  Allocation             inherit
  Read ahead sectors     auto
  - currently set to     8192
  Block device           253:5

 lvcreate -V 10G myvg/mytpool -n myvirtuallv  #基于mytpool创建虚拟LV:myvirtuallv,创建完以后会打印一些警告信息,但不要紧,创建成功即可

 WARNING: Sum of all thin volume sizes (10.00 GiB) exceeds the size of thin pool myvg/mytpool and the amount of free space in volume group (<4.98 GiB).
  WARNING: You have not turned on protection against thin pools running out of space.
  WARNING: Set activation/thin_pool_autoextend_threshold below 100 to trigger automatic extension of thin pools before they get full.
  Logical volume "myvirtuallv" created.

 lvdisplay /dev/myvg/myvirtuallv  #查看myvirtuallv的详细状态信息:

 --- Logical volume ---
  LV Path                /dev/myvg/myvirtuallv
  LV Name                myvirtuallv
  VG Name                myvg
  LV UUID                IWvTLY-MU8q-cMIE-zMWD-sf3u-UEAX-mxntIk
  LV Write Access        read/write
  LV Creation host, time localhost.localdomain, 2022-08-16 22:08:19 +0800
  LV Pool name           mytpool
  LV Status              available
  # open                 0
  LV Size                10.00 GiB
  Mapped size            0.00%
  Current LE             2560
  Segments               1
  Allocation             inherit
  Read ahead sectors     auto
  - currently set to     8192
  Block device           253:7

 mkfs.xfs /dev/myvg/myvirtuallv  #格式化myvirtuallv为xfs文件系统

 Discarding blocks...Done.
 meta-data=/dev/myvg/myvirtuallv  isize=512    agcount=16, agsize=163840 blks
         =                       sectsz=512   attr=2, projid32bit=1
         =                       crc=1        finobt=0, sparse=0
 data     =                       bsize=4096   blocks=2621440, imaxpct=25
         =                       sunit=16     swidth=16 blks
 naming   =version 2              bsize=4096   ascii-ci=0 ftype=1
 log      =internal log           bsize=4096   blocks=2560, version=2
         =                       sectsz=512   sunit=16 blks, lazy-count=1
 realtime =none                   extsz=4096   blocks=0, rtextents=0

 mkdir /data/myvirtuallv  #创建一个目录,用于挂载文件系统

 mount /dev/myvg/myvirtuallv /data/myvirtuallv  #挂载文件系统

 df -Th /data/myvirtuallv  #查看文件系统的信息

 文件系统                     类型  容量  已用  可用 已用% 挂载点
 /dev/mapper/myvg-myvirtuallv xfs    10G   33M   10G    1% /data/myvirtuallv  #==>看到了吧,创建的文件系统是10G

 dd if=/dev/zero of=/data/myvirtuallv/test.img bs=1M count=500  #在这个文件系统中添加一个500MB的文件

 lvs myvg  #查看myvg卷组上当前的逻辑卷信息

   LV          VG   Attr       LSize  Pool    Origin Data%  Meta%  Move Log Cpy%Sync Convert
  mylv        myvg -wi-a----- 14.00g                                                       
  mytpool     myvg twi-aotz--  1.00g                49.91  17.19                           #可以看到用于实际存储数据的thin pool的1G容量实际使用的比例为49.91%
  myvirtuallv myvg Vwi-aotz-- 10.00g mytpool        4.99  #可以看到现在虚拟逻辑卷中10G的容量,使用比例表示为4.99%

 lvextend -L 5G /dev/myvg/my  #将实际存储数据的mytpool的容量扩充到5G

 lvs myvg  #再来查看myvg卷组上的逻辑卷信息

  LV          VG   Attr       LSize  Pool    Origin Data%  Meta%  Move Log Cpy%Sync Convert
  mylv        myvg -wi-a----- 14.00g                                                       
  mytpool     myvg twi-aotz--  5.00g                9.98   13.77                        #实际存储数据的thin pool的容量被扩充到了5G,容量使用比例变成了9.98%
  myvirtuallv myvg Vwi-aotz-- 10.00g mytpool        4.99   #可以看到虚拟逻辑卷依然是10G容量,使用比例为4.99%没有发生变化

使用虚拟逻辑卷就可以保持对外使用的相关信息不变,而通过调整实际提供数据存储的thin pool容量来动态的管理空间使用,这比之前将文件系统建立在实际存储数据的逻辑卷上的管理就要方便一些了,因为那样多了一个调整文件系统容量的步骤。

4.5LVM的LV磁盘快照

关于快照其实很简单,在安装系统时为了将来可以在某个时间将系统还原到最初安装的状态就可以使用快照的方式来实现,快照的实现原理就是将当前的数据扫描一遍,并使用一个监控程序监控数据的变化,当数据发生变化时先将原数据备份出来然后再修改(存储备份数据的地方被称为快照区),当需要使用快照还原或备份数据时就可以使用已变化的原数据备份和未变化的数据来实现,所以快照的实现有两个机制:数据备份和数据监控,LVM的LV磁盘快照实现就是按照这样的原理实现的。

创建LV快照同样是使用lvcreate命令,只是要使用的选项是-s,因为一般情况下快照是不希望被修改的,所以还会使用-p r配置来实现LV快照为只读。而快照备份的数据可能并不会需要备份全部数据,可以根据实际的需求设置快照LV的容量小于原数据的容量,当未来要使用快照时跟使用普通LV差不多,下面来看具体的操作示例。

需要注意的是由于快照区与原LV共享很多数据,因此快照区与被快照的LV必须在同一个VG上面,假设现在要给前面示例中创建的mylv创建一个快照,就可以按照下面的步骤来实现:

 vgdisplay myvg  #因为LV快照要建立在同一个卷组上,所以先来看看当前VG还有多少容量

 ...

  Total PE              5116
  Alloc PE / Size       4868 / <19.02 GiB
  Free  PE / Size       248 / 992.00 MiB  #可以看到当前VG还剩238个PE即992MiB的容量,这里只是为了简单的演示,就不考虑数据有多大变化了,就是用这些容量来创建一个mylv的快照

 lvcreate -s -l 248 -n mylvsnap /dev/myvg/mylv  #创建一个mylv的快照为mylvsnap

 lvdisplay /dev/myvg/mylvsnap  #查看刚刚创建的mylv的快照mylvsnap的状态信息

  --- Logical volume ---
  LV Path                /dev/myvg/mylvsnap
  LV Name                mylvsnap
  VG Name                myvg
  LV UUID                2hEwU7-B2UV-531Y-bSRr-c1vv-S7Q0-0qka2k
  LV Write Access        read only
  LV Creation host, time localhost.localdomain, 2022-08-18 02:25:08 +0800
  LV snapshot status     active destination for mylv
  LV Status              available
  # open                 0
  LV Size                14.00 GiB  #这里表示的是原LV的大小
  Current LE             3584
  COW-table size         992.00 MiB  #这里是快照能够记录的最大容量
  COW-table LE           248
  Allocated to snapshot  0.00%  #目前快照区已被使用的容量比
  Snapshot chunk size    4.00 KiB
  Segments               1
  Allocation             inherit
  Read ahead sectors     auto
  - currently set to     8192
  Block device           253:10

 mkdir /data/mylvsnap  #创建一个目录用于话在mylv的快照mylvsnap

 mount /dev/myvg/mylvsnap /data/mylvsnap  #挂载mylvsnap到/data/mylvsnap目录上

 ll /data/mylv  #查看原lv的文件信息:

 总用量 13
 -rw-r--r--. 1 root root    23 8月  15 09:41 issue
 drwx------. 2 root root 12288 8月  15 07:17 lost+found
 ll /data/mylvsnap  #查看快照的文件信息(可以看到快照LV并没有创建文件系统,但拥有跟mylv一样的数据,这是因为它们当前是共用mylv的数据):
 总用量 13
 -rw-r--r--. 1 root root    23 8月  15 09:41 issue
 drwx------. 2 root root 12288 8月  15 07:17 lost+found

 cp /data/myvirtuallv/test.img /data/mylv  #这里复制一个一个测试数据到mylv中

 ll /data/mylv /data/mylvsnap  #再来查看当前mylv与其之前的快照mylvsnap的文件信息:

 总用量 512014
 -rw-r--r--. 1 root root        23 8月  15 09:41 issue
 drwx------. 2 root root     12288 8月  15 07:17 lost+found
 -rw-r--r--. 1 root root 524288000 8月  18 05:15 test.img  #这里是刚刚添加的数据,在之前的快照中并没有这个数据

 /data/mylvsnap:
 总用量 13
 -rw-r--r--. 1 root root    23 8月  15 09:41 issue
 drwx------. 2 root root 12288 8月  15 07:17 lost+found

以上就是创建LV快照的的全部操作过程,快照最多的应用就是用于将数据恢复到之前的某个时间节点,那么下面就可以来测试:比如将mylv卸载并删除,然后再创建一个新的LV来基于快照恢复数据。但是需要注意的是再卸载删除之前,需要将快照的包含的数据全部备份到快照区(其实关于数据备份在后面有专门的博客解析,这里只是简单的演示)。

 yum -y install dump  #安装ext文件系统备份工具

 dump -0uj -f /tmp/mylvsnap.bak.gz /data/mylvsnap  #基于mylv的快照mylvsnap备份数据到tmp下,备份数据文件为mylvsnap.bak.gz

 -----------------------这一部分是非必要的步骤,如果你有空闲的分区也可以直接使用---------------------------------------------------

 fdisk /dev/sdb  #在sdb磁盘上创建一个5G的分区sdb1,用于恢复备份数据,详细操作步骤参考:磁盘文件系统管理的3.2.2

 partprobe -s  #更新分区表信息

 mkfs.xfs /dev/sdb1  #将sdb1格式化为xfs文件系统

 mkdir /data/sdb1  #创建一个目录用来挂载文件系统

 mount /dev/sdb1 /data/sdb1  #挂载文件系统

 ----------------------------------------------------------------------------------------------------------------------------------------------------------

 cd /data/sdb1  #进入到sdb1目录下

 restore -r -f /tmp/mylvsnap.bak.gz  #将备份文件恢复成可使用的数据

 ll /data/mylvsnap /data/sdb1  #对比mylv的镜像mylvsnap与镜像备份恢复的数据

 /data/mylvsnap:
总用量 13
-rw-r--r--. 1 root root    23 8月  15 09:41 issue
drwx------. 2 root root 12288 8月  15 07:17 lost+found

/data/sdb1:      #===>通过下面的文件信息可以看到数据已经完整恢复
总用量 1452
-rw-r--r--. 1 root root      23 8月  15 09:41 issue
drwx------. 2 root root       6 8月  15 07:17 lost+found
-rw-------. 1 root root 1481400 8月  18 12:26 restoresymtable  #===>这个是备份文件恢复表,不用管他,后面专门解析备份相关的博客会解析

以上就是基于lv的镜像将数据恢复到某个时间点的状态的全部操作,需要注意的是不同的文件系统的备份工具各不相同,如果使用的是xfs文件系统就要使用到xfsdump实现备份,然后使用xfsrestore实现数据恢复操作,相关具体操作可以查看相关文档,这里就不赘述了,后面还会基于备份写一篇详细的博客。

4.6关于LVM相关命令与LVM的关闭

关于LVM的相关内容就全部写完了,最后使用一个表格汇总一下相关操作的命令

为了方便后期测试使用,最后还是将LVM创建的相关逻辑卷、卷组、物理卷卸载、删除,顺便也演示一下相关命令的使用:

 umount /dev/myvg/mylv /dev/myvg/mylvsnap  #先卸载挂载的文件系统;

 lvremove /dev/myvg/mylv /dev/myvg/mytpool /dev/myvg/myvirtuallv  #删除逻辑卷;

 vgchange -a -n myvg  #将卷组设置为不活动的状态;

 vgremove myvg  #删除卷组;

 pvremove /dev/sda{6,7,8,9}  #删除PV属性;

 fdisk /dev/sda  #修改磁盘分区系统类型(之前为了创建逻辑卷,系统类型被修改成了Linux LVM),如果是GPT分区模式要使用gdisk,根据自己的实际环境来;

 输入:l  #===>查看系统类型编号;

 输入:t  #===>进入修改磁盘系统类型;

 输入:6  #===>输入指定的磁盘分区编号;

 输入:83  #===>将磁盘分区sda6的系统类型修改成默认的Linux类型(当然也可以修改成你需要的类型,我这里就将它先还原)

 输入:w  #写入修改

 #这里我就暂时修改一个sda6,其他的安装这个模式修改即可,然后我这里还有一个sdb1磁盘分区也要删除,这里也演示一下吧,卸载文件系统就跳过了;

 fdisk /dev/sdb  #进入管理/dev/sdb这个磁盘

 输入:d  #由于我这里当前只有一个分区,就不用输入分区编号了,会直接删除这个唯一分区

 输入:w  #写入修改

 partprobe -s  #更新分区表信息,以上就是删除LV和磁盘分区的全部操作,做完以后可以使用lsblk查看确认

 五、btrfs文件系统管理与应用

btrfs从百科上看到的描述是Butter FS,也有说是B-tree、Better FS的简写,不论是哪一种说法归根到底都是由它的特性说决定的,btrfs第一大特性就是支持在多个物理磁盘上建立文件系统,所以无论上面三种哪一个说法都是相符合的。除此之外,btrfs的特性还包括:

第一大特性:基于多磁盘的多物理卷模式;
RAID:可以联机添加、移动、修改;
写时复制更新机制(CoW):复制、更新、替换指针,而非就地更新;
数据及原数据效验码:checksum;
子卷:sub_volume;
快照:支持快照的快照;
透明压缩:在挂载的时候可以直接使用挂载参数compress指明数据压缩算法为{lzo|zlib},这时候文件系统在存储数据时就会自动压缩数据,但这种压缩用户是感知不到的,因为存储数据不需要用户手动取对数据进行压缩和解压缩,所以被称为透明压缩机制。

关于btrfs更多的原理及相关文档可以参考:Btrfs (简体中文)Btrfs文件系统深度剖析|磁盘布局及BTree。这篇博客因为篇幅和内容核心指简单的介绍如何搭建和应用btrfs文件系统,关于btrfs的原理相关后期如果有时间的话再深入研究写一篇。

5.1btrfs文件系统相关命令及语法

实际管理btrfs文件系统的命令就是btrfs,其内部包含各种管理功能的子命令,然后还有一些与btrfs相关的系统管理命令,可以通过键入btrfs后连续按两次【tab】键来查看,创建btrfs文件系统的命令在CentOS7中也被mkfs集成封装,所以创建btrfs文件系统可以使用btrfs以外还可以使用mkfs.btrfs,下面先来了解都有哪些与btrfs相关的命令。另外btrfs在CentOS7中已经默认安装,如果是其他没有默认安装的系统内核可能还需要自己安装和编制相关组件,所以如果是测试的话建议使用有默认安装btrfs的系统内核。

 btrfs [tab] [tab]  #提示btrfs开头的命令:

 btrfs               btrfs-convert       btrfs-find-root     btrfs-map-logical   btrfstune           
 btrfsck             btrfs-debug-tree    btrfs-image         btrfs-select-super  btrfs-zero-log

btrfs相关的命令功能解析:

btrfs:btrfs:文件系统管理工具;
btrfs-convert:将ext2/3/4文件系统转换成btrfs文件系统;
btrfs-find-root:过滤查找btrfs的根文件系统;
btrfs-map-logical:将btrfs文件系统逻辑区段映射到物理区段;
btrfstune:调优各种文件系统参数;
btrfsck:检查或修复已卸载的btrfs文件系统;
btrfs-debug-tree:查询各种内部信息;
btrfs-image:创建或修复文件系统的映射;
btrfs-select-super:用备份副本覆盖主超级快;
btrfs-zero-log:恢复损坏的btrfs文件系统;

上面这些命令在后面的内容中不一定会详细的解析或介绍,详细介绍的命令会被列举到博客的第一部分命令与内容节点说明中,可以对照查看,没有详细介绍的命令工具可以自行查阅man文档了解和测试,下面来看要详细了解的btrfs命令,这个命令是用来管理btrfs文件系统的,其中有非常多的子命令:

 btrfs <command> [<args>]  #btrfs的语法,command表示管理文件系统的具体功能子命令,args表示命令需要的参数。

通过man文档可以查看到btrfs的<command>子命令共有15个,下面逐个来了解它们都提供了哪些功能,虽然它们都是子命令但都提供了btrfs-<command>这种结构的独立命令工具,要了解它们详细的内容可以通过man查看对应独立命令的文档:

balance:在单个或多个设备上平衡btrfs文件系统块,就是指将数据均衡分配到各个磁盘的操作,一般用于增删磁盘后将数据均衡到各个磁盘;
check:对btrfs文件系统进行脱机检查;
device:管理btrfs管理的设备,包括添加/删除/扫描等;
filesystem:管理btrfs文件系统,包括标签设置/同步等;
inspect-internal:开发人员/黑客的调试工具;
property:获取/设置一个btrfs对象的属性;
qgroup:管理btrfs文件系统配额组;
quota:管理btrfs文件系统上的配额,如启用/rescan等;
receive:从stdin/file接收子卷数据用于恢复等;
replace:btrfs替换设备;
rescue:尝试修复损坏的btrfs文件系统;
restore:尝试从损坏的btfs文件系统恢复文件;
scrub:擦洗btrfs文件系统;
send:将子卷数据发送到标准输出/文件进行备份等;
subvolume:创建/删除/清单/管理btrfs子卷;

 5.2创建Btrfs文件系统

在前面的命令Btrfs文件系统的相关命令介绍中就提到过,创建Btrfs文件系统使用mkfs.btrfs命令,下面就先来看这个命令的语法:

 mkfs.btrfs [options] <device> [<device>...]

mkfs.btrfs的选项及参数解析:

参数:
device:表示块设备,一般直接使用磁盘作为btrfs的物理卷,当可以使用磁盘分区,但磁盘分区后在用作btrfs的物理卷那分区的意义又何在呢?
选项:
-A|--alloc-start <offset>:用于指定从设备起始处的(物理)偏移量开始分配,默认为0;

-b|--byte-count <size>:用于指定文件系统的大小,如果不指定就默认为整个设备的空间;

-d|--data <profile>:用于指定数据块组的配置文件,可以说就是指定磁盘阵列模式(Raid),取值可以是raid0、raid1、raid5、raid6、raid10、single、Dup;

-m|--metadata <profile>:用于指定元数据块组的配置文件,也是用来指定磁盘阵列模式(Raid),取值可以是raid0、raid1、raid5、raid6、raid10、single、Dup;单个设备文件系统默认为DUP,除非检测到SSD,它将默认为single,检测方式为“/sys/block/DEV/queue/rotation”,其中DEV为设备的简称;

-M|--mixed:正常情况下,数据块组和元数据组是隔离的,混合模式将删除隔离,将这两种类型的快组存储在一起,这是为了更好的利用空闲空间,方便适用于小型设备。

-n|--nodesize <size>:用于指定node的大小,即文件系统元数据的树块大小,默认为16KiB或页面大小,取较大的一个值。

-s|--sectorsize <size>:用于指定扇区大小,默认值为自动检测的页面大小。如果扇区大小与页面大小不相同,则无法创建文件系统,所以不建议适用这个选项,除非文件系统必须挂载到指定的页面大小的系统上;

-L|--label <string>:用于指定文件系统的标签,限制长度为256字节且不能包含换行符;

-r|--rootdir <rootdir>:用来自rootdir的文件填充顶层子卷,这个不需要root权限,也不需要挂载文件系统;

-o|--features <feature1>[,<feature2>...]:打印文件系统特性列表,用来查看文件系统的特性。旧内核不支持所有特性,禁用的特性会在它前面加上^符号。可以查看指定的特性,如果指定就会输出所有特性;

-f|--force:当检测到当前设备已经存在文件系统时,这个选项会强制覆盖设备的文件系统创建。

-q|--quiet:启动打印错误或警告消息的功能,格式为(选项-功能-帮助);

-U|--uuid <UUID>:用于指定文件系统的UUID;

常用的mkfs.btrfs的选项一般是:-L、-d、-m、-o,在上面的选项介绍中有两个弃用的选项没有列出来,这两个是-l和-K,下面就来使用mkfs.btrfs来创建一个Btrfs文件系统,创建之前先准备三个供测试的硬盘,这在虚拟机上非常方便添加,就不演示了,下面就来看创建文件系统的具体命令:

 #测试硬盘:/dev/sdb /dev/sdc /dev/sdd

 mkfs.btrfs -L mybtr /dev/sdb /dev/sdc  #先使用sdb和sdc创建文件系统,sdd留着后面测试其他功能,使用-L指定文件系统的卷标为mybtr(如果你的sdb磁盘之前用于前面的示例测试,可能需要-f选项执行强制格式化操作)

 btrfs-progs v4.9.1  #==>当前btrfs的版本
 See http://btrfs.wiki.kernel.org for more information.

 Label:              mybtr  #文件系统卷标
 UUID:               b341458a-d998-4acb-947b-e1067b36b1a5  #文件系统的唯一标识
 Node size:          16384
 Sector size:        4096
 Filesystem size:    40.00GiB  #文件系统的容量
 Block group profiles:
  Data:             RAID0             2.00GiB
  Metadata:         RAID1             1.00GiB
  System:           RAID1             8.00MiB
 SSD detected:       no
 Incompat features:  extref, skinny-metadata
 Number of devices:  2
 Devices:
   ID        SIZE  PATH
    1    20.00GiB  /dev/sdb
    2    20.00GiB  /dev/sdc

上面示例btrfs文件系统创建完就可以直接挂载使用了,但在老版本的Btrfs创建时它不会打印出UUID这些信息,所以需要先查看文件系统的信息,获取UUID才能挂载,下面为了示范老版本的btrfs文件系统挂载,先来查看文件系统的信息然后再进行挂载操作,顺便也演示一下相关管理命令的使用:

 btrfs filesystem show  #使用btrfs的文件系统管理子命令filesystem的show子命令可以查看当前系统上的所有btrfs文件系统信息

 Label: 'mybtr'  uuid: b341458a-d998-4acb-947b-e1067b36b1a5
    Total devices 2 FS bytes used 112.00KiB
    devid    1 size 20.00GiB used 2.01GiB path /dev/sdb
    devid    2 size 20.00GiB used 2.01GiB path /dev/sdc

 #除了使用btrfs的文件系统管理工具查看,还可以使用blkid查看btrfs文件系统包含的磁盘信息来获取UUID

 blkid /dev/sdb  #打印的信息:/dev/sdb: LABEL="mybtr" UUID="b341458a-d998-4acb-947b-e1067b36b1a5" UUID_SUB="9c370e2a-34a8-48b9-88f2-03c3514bfa65" TYPE="btrfs

 blkid /dev/sdc  #打印的信息:/dev/sdc: LABEL="mybtr" UUID="b341458a-d998-4acb-947b-e1067b36b1a5" UUID_SUB="19c3895c-a62d-4fe5-ac0f-be0aa3865635" TYPE="btrfs"

关于btrfs filesystem在后面的Btrfs文件系统管理部分详细介绍,这里暂时只需要直到用btrfs filesystem show可以查看Btrfs文件系统的标识符即可,下面就来挂载mybtr文件系统:

 mount -t btrfs /dev/sdb /data/mybtr  #可以直接使用-t执行文件系统类型和btrfs文件系统包含的磁盘文件名就可以挂载,但注意不要重复使用多个btrfs文件系统包含的磁盘挂载btrfs文件系统

 mount | grep 'btrfs'  #查看挂载的btrfs文件系统信息,确认文件系统是否挂在成功

 /dev/sdb on /data/mybtr type btrfs (rw,relatime,seclabel,space_cache,subvolid=5,subvol=/)

 #同样也可以使用文件系统的UUID来挂在,或者使用sdc这个磁盘来挂载

 umount /data/mybtr; mount UUID="b341458a-d998-4acb-947b-e1067b36b1a5" /data/mybtr; mount | grep 'btrfs'  #使用唯一标识符挂载

 umount /data/mybtr; mount -t btrfs /dev/sdc /data/mybtr; mount | grep 'btrfs'  #使用sdc磁盘来挂载

 #使用lsblk查看块设备信息,你会看到只有sdb后面有挂载目录,这是因为文件系统的超级区块存放在sdb上,所以即便使用sdc挂载mybtr挂载的信息也是显示sdb

 lsblk  #打印信息:

 ...

 sdb               8:16   0   20G  0 disk /data/mybtr
 sdc               8:32   0   20G  0 disk

 cp /etc/grub2.cfg /data/mybtr  #拷贝一个文件到mybtr中测试

 ll /data/mybtr

 总用量 8
-rw-r--r--. 1 root root 4291 8月  25 05:20 grub2.cfg  #==>可以看到mybtr文件系统就可以开始使用了

在前面分析Btrfs文件系统特性的时候提到过,可以在挂载文件系统时通过参数compress来指明压缩算法,启动数据存储的透明压缩机制,如果要启动Btrfs文件系统的透明压缩机制就可以按照下面的命令模式来挂载文件系统:

 umount /data/btrfs

 mount -o compress=lzo -t btrfs /dev/sdb /data/mybtr  #btrfs支持lao和zlib两种压缩算法,这里我使用的是lzo,这个可以根据实际需求和环境而定

因为是透明的压缩机制,用户在做数据读写时是感知不到的,还是按照正常的数据读写即可,压缩和解压缩算法会自动对数据进行处理。

5.3管理Btrfs文件系统

在btrfs命令中有一个filesystem子命令是用于管理整个Btrfs文件系统的工具,这个工具中又包含一系列的子命令,可以通过 man btrfs-filesystem 的方式来查看这个管理管局的详细子命令文档:

 btrfs filesystem <subcommand> <args>

btrfs-filesystem子命令subcommand的简单介绍:

df: btrfs filesystem df [options] <path> :用于查看文件系统包含的磁盘设备信息,跟df命令功能一样,相关选项和参数的使用可以参考df命令;

defragment: btrfs filesystem defragement [options] <file>|<dir> [<file>|<dir>...] :用于整理文件系统的数据;

du: btrfs filesystem du [options] <path> [<path>...] :用于查看文件系统包含的磁盘容量使用情况,跟du命令功能一样,相关选项和参数的使用可以参考du命令;

label: btrfs filesystem label [<dev>|<mountpoint>] [<newlabel>] :用于显示或更新文件系统的标签;

resize: btrfs filesystem resize [<devid>:] [+/-]<size>[kKmMgGtTpPeE] | [<devid>:] max <path> :用于调整文件系统的容量大小;

show: btrfs filesystem show [options] [<path>|<uuid>|<device>|<label>] :用于查看文件系统的信息,可以指定查看文件系统的某个设备的信息;

sync: btrfs filesystem sync <path> :用于清空文件系统缓冲区,强制将文件系统的数据更改写入磁盘,跟sync命令的功能一样,相关选项和参数可以参考sync命令;

usage: btrfs filesystem usage [options] <path> [<path>...] :用于查看文件系统使用的详细信息;

defrag: btrfs filesystem defrag [options] dir :用于递归整理指定目录下的磁盘碎片;

调整文件系统容量

在调整文件系统大小之前,通过lsblk来查看我当前测试环境中用于构建mybtr文件系统的磁盘容量信息,以及使用df查看整个文件系统的容量:

 lsblk  #查看当前系统上用于构建Btrfs文件系统mybtr的磁盘容量

 ...

 sdb               8:16   0   20G  0 disk /data/mybtr
 sdc               8:32   0   20G  0 disk  #==>通过打印的信息可以看到当前构建文件系统的两个设备容量都是20G

 df -lh /data/mybtr  #查看文件系统的容量

 文件系统        容量  已用  可用 已用% 挂载点
 /dev/sdb         40G   18M   38G    1% /data/mybtr  #这里显示的整个文件系统容量就是40G没问题,因为文件系统挂载时只能显示一个磁盘,所以这里显示的设备就是文件系统超级区块所在的sdb磁盘,但其表示的文件系统容量会包含sdc的容量,所以如果要查看文件系统的容量就要使用df命令,而btrfs filesystem df命令只能查看文件系统的内部容量使用情况

 btrfs filesystem df -h /data/mybtr

 Data, RAID0: total=2.00GiB, used=776.00KiB  #==>这里可以看到文件系统数据采用的是RAID0的磁盘阵列模式,整体容量total和实际使用容量used在虚拟机上并不准确
 System, RAID1: total=8.00MiB, used=16.00KiB  #==>这里可以看到文件系统(超级区块)的相关数据采用的是RAID1的磁盘阵列模式,容量使用情况在虚拟机上不准确
 Metadata, RAID1: total=1.00GiB, used=112.00KiB  #==>这里可以看到文件系统元数据的相关数据采用的是RAID1的磁盘阵列模式,容量使用情况在虚拟机上不准确
 GlobalReserve, single: total=16.00MiB, used=0.00B

下面就来演示文件系统的容量调整:

 btrfs filesystem resize -10G /data/mybtr  #将当前文件系统的容量缩小10G,需要注意的是这里使用的是挂在路径,这也叫做联机管理模式

 df -lh /data/mybtr

 文件系统        容量  已用  可用 已用% 挂载点
 /dev/sdb         30G   18M   18G    1% /data/mybtr  #==>可以看到文件系统的容量已经减少到了30G

 btrfs filesystem resize +5G /data/mybtr  #将当前文件系统的容量扩大5G

 df -lh /data/mybtr  #打印信息:/dev/sdb         35G   18M   28G    1% /data/mybtr

 btrfs filesystem resize max /data/mybtr  #将当前文件系统的容量扩充到最大容量,即构成文件系统的所有物理磁盘的容量

 df -lh /data/mybtr  #打印信息:/dev/sdb         40G   18M   38G    1% /data/mybtr

以上是文件系统容量调整是在基于当前磁盘容量不变的情况下进行的,如果要扩充超出当前磁盘总容量的文件系统容量就需要先给文件系统添加磁盘,然后再扩充,这就需要使用到btrfs的device子命令来添加设备,再device子命令中又包含了一系列的子明来实现文件系统的设备增删等管理操作的子命令,下面先来看btrfs-device相关的语法及之命令解析:

 btrfs device <subcommand> <args>

btrfs-device的子命令subcommand简单介绍:

add: btrfs device add [-Kf] <dev> [<dev>...] <path> :用于给Btrfs文件系统添加磁盘;

remove: btrfs device remove <dev>|<devid> [<dev>|<devid>...] <path> :用于Btrfs文件系统删除磁盘;

delete: btrfs device delete <dev>|<devid> [<dev>|<devid>...] <path> :这个跟remove的作用是一样的,是用于删除操作向前兼容的别名;

ready: btrfs device ready <device> :内核模块扫描并注册多设备文件系统的所有设备,这个命令会等待扫描,将设备转为备用状态;

scan: btrfs device scan [(--all-devices|-d)|<device> [<device>...]] :扫描Btrfs文件系统的设备,并向内核模块注册它们;

stats: btrfs device [-zc] <path>|<device> :用于查看指定文件系统或标识的所有设备的设备IO错误统计信息;

usage: btrfs device [options] <path> [<path>...] :显示设备内部分配的详细信息;

下面就来演示Btrfs文件系统增删磁盘的相关操作:

 btrfs device add /dev/sdd /data/mybtr  #将磁盘sdd添加到mybtr文件系统上

 df -lh /data/mybtr  #查看文件系统的信息

 文件系统        容量  已用  可用 已用% 挂载点
 /dev/sdb         60G   18M   56G    1% /data/mybtr  #==>可以看到当前文件系统已经自动将sdd的容量扩充到文件系统中,并不需要再手动扩容

虽然磁盘文件系统容量已经自动扩充,但当前添加sdd磁盘上并没有去分摊存储文件系统的数据,这时候就需要将其他磁盘的数据移动到这个磁盘上,如果要均衡将原文件系统的数据分摊到新的磁盘上,就需要使用到btrfs的balance子命令,下面就来看看btrfs-balance的语法以及balance中用于分配数据的相关子命令和参数:

 btrfs balance <subcommand> <args>

btrfs-balance的子命令subcommand简单介绍:

cancel: btrfs balance cancel <path> :取消平衡操作,也就是将正在进行的数据均衡或暂停的数据均衡操作取消;

pause: btrfs balance pause <path> :暂停正在进行的平衡操作;

resume: btrfs balance resume <path> :恢复中断的平衡操作;

start: btrfs balance start [options] <path> :根据指定的筛选器启动平衡操作,没有筛选器将重写整个文件系统。可以通过-dms选项分别指定数据块、元数据、文件系统数据的平衡操作,还可以通过-v选项来生成日志和打印平衡过滤操作信息。可以通过-f来降低元数据的完整性,也就是将元数据的磁盘整列模式从RAID1调整为single模式然后在进行平衡操作。数据平衡操作可能会因为数据量大而需要非常长的时间来处理,所以还提供了--background|--bg选项可以将平衡操作放到后台;前面讲到可以使用-f选项来调整元数据的存储模式,同样在使用-dms对指定数据进行平衡操作使用,还可以修改其数据的存储模式,比如要将元数据的存储模式修改为raid5的命令 btrfs balance start -mconvert=raid5 <path>  ,同理指定数据块和文件系统数据的存储模式就是-dconvert=模式名称、-sconvert=模式名称;

status: btrfs balance status [-v] <path> :用于查看正在进行的或暂停的平衡操作信息;

下面就来演示将刚刚添加磁盘的mybtr文件系统进行数据平衡操作:

 btrfs balance start /data/mybtr  #执行数据平衡操作

以上是由文件系统扩容所产生的磁盘添加和数据平衡的相关操作,在前面演示过直接缩小文件系统的容量操作,关于缩小文件系统容量一般都是在删除磁盘的时候进行的操作,还记得在逻辑卷中删除磁盘需要先将数据迁移出去再做磁盘删除操作,而在btrfs文件系统中删除磁盘不需要手动执行数据迁移操作,而是在执行磁盘删除操作是文件系统内部会自动将数据迁移出去,也就是说可以直接使用 btrfs device remove|btrfs device delete 删除文件系统中的磁盘即可,下面就通过删除sdd这个磁盘来演示这个操作:

 btrfs device delete /dev/sdd /data/mybtr  #将文件系统中的sdd这个磁盘删除,原本sdd上的文件数据会自动迁移到其他磁盘上;

 df -lh /data/mybtr  #查看文件系统的信息

 文件系统        容量  已用  可用 已用% 挂载点
 /dev/sdb         40G   17M   40G    1% /data/mybtr  #==>删除磁盘以后文件系统的容量就会自动调整缩小,也不需要手动操作

在前面btrfs-balance的子命令解析中还讲到可以通过数据平衡来指定调整数据块、元数据、文件系统数据的存储模式,假设现在要将mybtr文件系统的元数据的存储模式修改为raid5,但需要注意对应的存储模式一定要符合该模式的设备数量,所以为了演示这个功能有需要重新将sdd这个磁盘添加进来,下面来看具体演示代码:

 btrfs device add /dev/sdd /data/mybtr  #添加磁盘到文件系统

 btrfs balance start -mconvert=raid5 /data/mybtr  #将文件系统的元数据调整为raid5的存储模式

 btrfs filesystem df -h /data/mybtr  #查看文件系统的内部信息数据:
 Data, RAID0: total=2.00GiB, used=776.00KiB
 System, RAID5: total=64.00MiB, used=16.00KiB  #文件系统数据也随着元数据一起被修改成了raid5模式
 Metadata, RAID5: total=1.00GiB, used=112.00KiB  #文件系统的元数据已经被修改成了raid5模式
 GlobalReserve, single: total=16.00MiB, used=0.00B

以上就是Btrfs文件系统常见的管理相关操作的命令解析及示例演示,重点包括透明压缩、文件系统容量调整的磁盘添加与删除、数据存储的磁盘阵列模式调整、以及相关操作中涉及到的数据迁移,可以从这些操作中看到Btrfs文件系统同时具备了文件系统、磁盘阵列、逻辑卷的功能,对于系统的数据管理来说Btrfs简直就是太方便了。但优势归优势,Btrfs文件系统的稳定性依然还是一个非常大的隐患,实际应用根据需求而定吧。Btrfs还具备子卷特性,类似LVM中的LV,下面就看看关于Btrfs子卷的相关命令及示例。

5.4Btrfs文件系统的子卷

在btrfs命令上有个子卷管理子命令subvolume可以实现创建、删除、以及管理子卷的相关操作。下面先来看subvolume这个子命令的语法:

 btrfs subvolume <subcommand> [<args>]

btrfs-subvolume的子命令subcommand简单介绍:

create: btrfs subvolume create [-i <qgroupid>] [<dest>/]<name> :表示在<dest>创建子卷<name>,如果未指定<dest>就在当前目录中创建子卷,-i选项表示将子卷添加到qgroupid中;

delete: btrfs subvolume delete [-cC] <subvolume> [<subvolume>...] :用于删除子卷,-c选项表示所有子卷删除操作结束后等待事务提交,-C表示删除每个子卷后等待提交事务;

find-new: btrfs subvolume find-new <subvolume> <last_gen> :在<last_gen> ID后列出最近修改的文件;

get-default: btrfs subvolume get-default <path> :获取文件系统的默认子卷;

list: btrfs subvolume [options] [-G [+|-]<value>] [-C [+|-]<value>] [--sort=rootid,gen,ogen,path] <path> :用于查看文件系统中的子卷;

set-default: btrfs subvolume set-default <id> <path> :将文件系统子卷设置为默认挂载卷;

show: btrfs subvolume show <path> :用于查看指定的子卷信息;

snapshot: btrfs subvolume snapshot [-r] <source> <dest>|[<dest>/]<name> :用于创建子卷的快照;

sync: btrfs subvolume sync <path> [subvolid...] :从文件系统中删除指定的子卷,直到所有指定的文件系统删除完成,如果没有指定子卷则删除当前文件系统的所有子卷。

下面来看创建Btrfs的子卷示例的相关操作演示:

 btrfs subvolume create /data/mybtr/logs  #在Btrfs文件系统mybtr上创建一个logs子卷(这里/data/mybtr/logs会创建一个目录logs,而且创建的子卷名称也是logs)

 btrfs subvolume list /data/mybtr  #查看Btrfs文件系统mybtr上的子卷列表信息:

 ID 263 gen 75 top level 5 path logs  #==>现在就可以看到mybtr上就有了logs这个子卷了,ID为263

这里创建的子卷会自动挂载到对应的目录上,也就是说子卷会随着父卷自动挂载,即便是多个子卷也都会随着父卷自动挂载。如果要单独挂载某个子卷就需要将父卷卸载,然后再单独挂载子卷,比如来看下面的演示:

 btrfs subvolume create /data/mybtr/cache  #再在mybtr上创建一个子卷cache,用于后面的测试对比

 umount /data/mybtr  #卸载mybtr

 mount -o subvol=logs /dev/sdb /mnt  #然后将子卷logs单独挂载到/mnt上,挂载子卷需要通过-o的subvol参数来指明挂载的子卷名称,也可以使用参数subvolid指明挂载的子卷ID来挂载子卷,比如来看下面的演示:

 umount /mnt; mount -o subvolid=263 /dev/sdb /mnt  #使用子卷的id基于-o的subvolid参数实现子卷的挂载操作

需要注意的是,即便子卷已经被默认跟随父卷挂载了,但在不卸载父卷的情况下也能单独挂载子卷,相反单独挂在了子卷也能再挂载父卷,这种重复挂载的问题并不会报错,而且可以通过子卷单独操作自己的数据,再在父卷的路径下可以查看到子卷的数据变化,下面通过一些演示示例来了解:

 cp /etc/grub2.cfg /mnt  #随便给mnt即子卷添加一些测试数据

 ll /mnt  #查看子卷中的文件

 -rw-r--r--. 1 root root 4291 8月  27 03:49 grub2.cfg

 mount -t btrfs /dev/sdb /data/mybtr  #重新挂载父卷

 ll /data/mybtr/logs  #通过父卷下默认的子卷挂载路径查看logs子卷的文件信息

 -rw-r--r--. 1 root root 4291 8月  27 03:49 grub2.cfg  #==>可以看到跟子卷挂载/mnt查看到的文件信息一摸一样

 cp /etc/asound.conf /data/mybtr/logs  #通过父卷下默认的子卷挂载路径向子卷中添加测试数据

 ll /mnt  #再来通过子卷的挂载路径来查看文件信息

 -rw-r--r--. 1 root root   55 8月  27 03:57 asound.conf  #==>可以看到刚刚通过父卷下的默认子卷挂载目录添加的数据也打印出来了
 -rw-r--r--. 1 root root 4291 8月  27 03:49 grub2.cfg

 #测试完以后这里先将子卷的独立挂载卸载了,以方便后面的测试演示

 umount /mnt

虽然这种重复挂载效果有些惊喜,但为了方便管理还是不建议这么做,这里仅仅只是展示这种效果而已。关于子卷还有一个Btrfs文件系统的重要特性就是快照功能,下面就来看基于Btrfs子卷的快照、数据恢复、子卷备份的相关操作:

 btrfs subvolume snapshot /data/mybtr/logs /data/mybtr/logs_snapshot  #给logs子卷创建一个快照为logs_logs_snapshot

 btrfs subvolume list /data/mybtr  #查看mybtr下的子卷列表

 ID 263 gen 83 top level 5 path logs
 ID 264 gen 78 top level 5 path cache
 ID 265 gen 83 top level 5 path logs_snapshot  #==>可以看到在当前父卷下就有了一个新的子卷,这个子卷就是logs的快照

在Btrfs文件系统创建子卷的快照与LVM的LV快照一样,快照必须与原卷必须在同一个卷组下,这里Btrfs就是必须在同一个父卷下。同样快照本身起始也是一个子卷,子不过它与原卷共享未发生变化的数据块而已,所以它也会被默认挂载。然后对原卷的数据做一些修改,再来对照原卷和快照的数据信息:

 ll /data/mybtr/logs_snapshot  #可以在快照中查看到原卷的数据:

 -rw-r--r--. 1 root root   55 8月  27 03:57 asound.conf
 -rw-r--r--. 1 root root 4291 8月  27 03:49 grub2.cfg

 vim /data/mybtr/logs/grub2.cfg  #在原卷中修改一下文件数据

 ...

 How are you, snapshot?  #==>在文件的最末尾添加这一行字符,然后保存退出编辑

 cat /data/mybtr/logs_snapshot/grub2.cfg  #然后来查看快照中的文件数据,是无法在快照中对应的文件末尾找到那一行字符,其原理与LVM的LV快照是一样的,这里就不赘述了

在Btrfs文件系统中除了可以对子卷进行创建快照,还可以对单个文件进行创建快照,来看下面的演示示例:

 cd /data/mybtr/logs  #进入到logs子卷下测试文件快照,当然不改变工作路径也可以测试,只需要保证创建的文件快照与原文件在同一个Btrfs文件系统就可以

 cp --reflink grub2.cfg grub2.cfg._snap  #使用复制工具的--reflink选项就可以实现创建文件快照,这跟cp在其他文件系统中执行的复制操作是由区别的

关于文件快照的测试验证就不做了,跟子卷的快照验证是一样的,最后演示一下删除子卷的操作:

 btrfs subvolume delete /data/mybtr/logs  #删除mybtr中的子卷logs

 btrfs subvolume list /data/mybtr  #查看mybtr中的子卷信息列表,从打印信息中可以看到losg子卷已经删除了

 ID 264 gen 78 top level 5 path cache
 ID 265 gen 87 top level 5 path logs_snapshot

 btrfs subvolume delete /data/mybtr/logs_snapshot  #删除子卷的快照与删除子卷的命令语法是一样的,后面查看子卷信息就不演示了

以上就是Btrfs简单的应用全部内容,关于Btrfs文件系统的应用还有很多细节,在后期找机会深入解析Btrfs文件系统原理再补充吧,这一片博客的内容已经多到不能再多了。最后一下关于Btrfs文件系统的碎片整理,这虽然是一个非常优秀的功能,但其操作存在非常大的风险,如果需要做碎片整理的话建议一定要做好数据备份,当然最后一步就是拆解卸载文件系统,直接看下面的示例命令吧:

 #首先演示从Btrfs中拆卸一个磁盘,因为磁盘阵列模式的缘故,拆卸磁盘之前一定要确保文件系统中的磁盘数能支持当前的磁盘整列模式

 #比如在我当前的示例中由于文件系统的元数据是采用raid5的模式,而文件系统是建立在三个磁盘上的,如果要拆卸磁盘的话,就需要调整文件系统的磁盘整列模式

 btrfs balance start -mconvert=raid1 /data/mybtr  #将文件系统的元数据磁盘整列模式由原来的raid5调整到raid1

 btrfs filesystem df -h /data/mybtr  #查看文件系统的信息:

 Data, RAID0: total=2.00GiB, used=1.01MiB
 System, RAID1: total=32.00MiB, used=16.00KiB
 Metadata, RAID1: total=1.00GiB, used=128.00KiB  #==>可以看到元数据的存储模式已经被调整为raid1了
 GlobalReserve, single: total=16.00MiB, used=0.00B

 btrfs device delete /dev/sdb /data/mybtr  #然后将sdb这个磁盘从文件系统中拆解出来

 btrfs filesystem show  #然后查看文件系统信息,通过下面的打印信息就可以看到文件系统中的sdb磁盘已经被拆除

 Label: 'mybtr'  uuid: b341458a-d998-4acb-947b-e1067b36b1a5
    Total devices 2 FS bytes used 920.00KiB
    devid    2 size 20.00GiB used 2.03GiB path /dev/sdc
    devid    3 size 20.00GiB used 2.03GiB path /dev/sdd

5.5将ext文件系统转换成Btrfs文件系统

关于ext文件系统转换成Btrfs文件系统使用到的工具是btrfs-convert,实际使用起始很简单,这里简单的用一个示例做一个演示:

 mke2fs -t ext4 /dev/sdb  #直接将sdb这个磁盘格式为一个ext4的文件系统

 mkdir /data/ext4_btrfs  #创建一个目录,用于文件系统挂载

 mount /dev/sdb /data/ext4_btrfs  #挂载文件系统

 cp /etc/fstab /data/ext4_btrfs  #给文件系统随意添加一些测试数据

 umount /data/ext4_btrfs  #在执行转换前一定要将文件系统卸载,不然再转换时又有用户操作文件系统的数据就会很危险

 fsck -f /dev/sdb  #为了确保文件系统转换的安全性,在转换前应该至少对文件系统进行检查修复,避免带着问题转换

 btrfs-convert /dev/sdb  #然后使用btrfs-convert工具执行文件系统转换操作,转换需要一些时间,需要等待一下

 btrfs filesystem show  #转换完成以后查看当前系统上所有Btrfs文件系统信息

 Label: 'mybtr'  uuid: b341458a-d998-4acb-947b-e1067b36b1a5
    Total devices 2 FS bytes used 920.00KiB
    devid    2 size 20.00GiB used 2.03GiB path /dev/sdc
    devid    3 size 20.00GiB used 2.03GiB path /dev/sdd

 Label: none  uuid: fbabf367-093b-460a-874f-df1dfd7be1c4
    Total devices 1 FS bytes used 494.20MiB
    devid    1 size 20.00GiB used 780.30MiB path /dev/sdb  #这里就可以看到sdb的ext4文件系统就转换成了Btrfs文件系统了

 mount -t btrfs /dev/sdb /data/ext4_btrfs  #然后再将转换好的文件系统挂载

 df -lh /data/ext4_btrfs  #查看文件系统信息:

 文件系统        容量  已用  可用 已用% 挂载点
 /dev/sdb         20G  511M   20G    3% /data/ext4_btrfs

 ll /data/ext4_btrfs  #查看文件系统中的文件

 drwxr-xr-x. 1 root root  10 8月  27 09:12 ext2_saved  #这里是记录原ext文件系统的相关数据,不要删除,如果再要转换回ext文件系统会用到
 -rw-r--r--. 1 root root 632 8月  27 09:05 fstab      #这是之前添加的测试数据
 drwx------. 1 root root   0 8月  27 09:01 lost+found

 #如果要再将sdb的btrfs文件系统再转换回ext文件系统,还是一样先卸载再转换

 umount /data/ext4_btrfs

 btrfs-convert -r /dev/sdb  #同样还是使用btrfs-convert工具,只是回滚到ext文件系统需要使用-r选项即可

 blkid /dev/sdb  #查看sdb的信息:

 /dev/sdb: UUID="dc722563-7718-48ec-be2b-452629d57677" TYPE="ext4"  #==>可以通过打印信息看到sdb又回滚到了ext4文件系统

 

posted @ 2022-08-27 09:32  他乡踏雪  阅读(234)  评论(0编辑  收藏  举报