# 逻辑滚动条管理员(Logical Volume Manager)
有一个场景:当初规划主机的时候,只给了 /home
目录 50G,后续不够用了,要怎么办?
很多人会这样做:加一块新硬盘,重新分区、格式化,将 /home
的数据完整复制过去,将原本的 partition 卸载重新挂载新的 partition。
万一第二次又分多了,导致容量浪费了,又要减掉一部分容量?是不是还需要重来一次?
有更简单的方法来解决这个问题,就是使用 LVM,它的重点在于「可以弹性的调整 filesystem 的容量,并非在于效能与数据保全上面。
LVM 可以整合多个实体 partition 在一起,让这些 partitions 看起来像是一个磁盘一样,而且可以在未来新增或移除其他的实体 partition 到这个 LVM 管理的磁盘中。
# 上面是 LVM:PV、PE、VG、LV 的意义
Logical Volume Manager 翻译为逻辑滚动条管理员,简称 LVM。LVM 将几个实体的 partitions(或 disk)通过软件组合成一块看起来是独立的大磁盘(VG),然后将这块大磁盘再经过分区成为可使用分区槽(LV),最终就能挂载使用了。
但是为什么这样的系统可以进行 filesystem 的扩充或缩小呢?它与一个称为 PE 的项目有关
# Physical Volume PV 实体滚动条
实际的 partition(或 DISK)需要调整系统标识符(system ID)成为 8e(LVM 的标识符),再经过 pvcreate 的指令将他转成 LVM 最底层的实体滚动条(LV),之后才可以将这些 PV 加以利用,调整 system ID 的方式是通过 gdisk
# Volume Group VG 滚动条组
LVM 大磁盘是将许多 PV 整合成这个 VG ,所以 VG 是 LVM 组合起来的打磁盘。在预设情况下,使用 32 位的 Linux 系统时,基本上 LV 最大仅能支持到 65534 个 PE ,若使用预设的 PE 为 4MB 的情况下,最大容量可以达到约 256Gb,而在 64 位的 Linux 上,LV 几乎没有什么容量限制了
# Physical Extent PE 实体范围区块
LVM 预设使用 4MB 的 PE 区块,LV 在 32 位系统上最多有 65534 个 PE(lvml 的格式),因此预设的 LVM 的 LV 有 4M*65534/1024M=256G.
PE 是整个 LVM 最小的存储块,我们写入的数据都是写入 PE 的,简单说,PE 类似系统里面的 block。
所以调整 PE 会影响到 LVM 的最大容量,不过在 CentOS 6.x 以后,直接使用 lvm2 的各项格式功能,以及系统变成了 64 位,因此整个限制以及不存在了
# Logical Volume LV 逻辑滚动条
最终的 VG 还会被被切成 LV,LV 是最后可以被格式化使用的类似分区槽的东西,由于 PE 是整个 LVM 的最小存储单位,那么 LV 的大小就与 LV 内的 PE 总数有关。为了方便用户利用 LVM 来管理其系统,因此 LV 的装置文件名通常指定为 /dev/vgname/lvname
的样式
LVM 可弹性的变更 filesystem 的容量是通过「交换 PE」来进行数据转换,将原本 LV 内的 PE 转移到其他装置中以降低 LV 容量,或将其他装置的 PE 加到此 LV 中以加大容量。VG、LV 与 PE 的关系类似下图:
如上图,VG 内的 PE 会分给虚线部分的 LV,如果未来这个 VG 要扩充的话,加上其他的 PV 即可。而最重要的 LV 如果要扩充的话,也是通过加入 VG 内没有使用到的 PE 来扩充的
# 实操流程
通过 PV、VG、LV 的规划之后,再利用 mkfs 将 LV 格式化为可以利用的文件系统,而这个文件系统的容量在未来还可以扩充或减少,而且里面的数据还不会被影响,整个流程由基础到最终的结果可以这样看:
当数据写入 LV 时,有两种机制写入到硬盘中:
线性模式(linear)
假如将
/dev/vda1、/dev/vdb1
这两个 parition 假如到 VG 中,并且整个 VG 只有一个 LV 时,那么线性模式就是:当/dev/vda1
的容量用完之后,/dev/vdb1
的硬盘才会被使用到,这也是我们建议的模式交错模式(triped)
就好理解了,一份数据分割在多个硬盘上,理论上读写效率会好点
基本上,LVM 最主要的用途是实现一个可以弹性调整容量的文件系统上,而不是建立一个有效率为主的磁盘;因为数据分割在多个硬盘上,只要坏掉一块硬盘,那么基本上会损失掉很多数据。不适合 LVM
# LVM 实验流程
LVM 必须核心有支持且需要安装 lvm2 软件,较新的 distribution 已经预设 LVM 相关软件安装了。
上一节实验 RAID 有 5 个分区,这里还是建议修改下 systemID 比较好,将 RAID 的 fd 改为 LVM 的 8e,实验流程如下:
- 使用 4 个 partition,每个 partition 容量为 1GB,且 system ID 需要为 8e
- 全部的 partition 整合为一个 VG,VG 名称设置为 vmrcode;且 PE 的大小为 16MB
- 建立一个名为 vmrcode 的 LV,容量大约 2G
- 最终这个 LV 格式化 xfs 的文件系统且挂载
/srv/lvm
中
- disk 阶段,实际的磁盘
这里需要准备把之前的 5 个分区删掉,重新格式化出来;有关分区相关操作请参考第 7 章的硬盘分区、格式化章节
# 最终分区出来的信息如下
Number Start (sector) End (sector) Size Code Name
1 2048 6143 2.0 MiB EF02
2 6144 2103295 1024.0 MiB 0700
3 2103296 65026047 30.0 GiB 8E00
4 65026048 67123199 1024.0 MiB 8E00 Linux LVM
5 67123200 69220351 1024.0 MiB 8E00 Linux LVM
6 69220352 71317503 1024.0 MiB 8E00 Linux LVM
7 71317504 73414655 1024.0 MiB 8E00 Linux LVM
8 73414656 75511807 1024.0 MiB 8E00 Linux LVM
# 前面说的 8e 就是这里的 Code 字段,是在建立分区的时候指定的 8E00,也就是 LVM 格式
2
3
4
5
6
7
8
9
10
11
12
PV 阶段
下面是与 PV 有关的指令
- pvcreate:将实体 partition 建立成为 PV
- pvscan:搜索目前系统里面任何具有 PV 的磁盘
- pvdisplay:显示目前系统上 PV 状态
- pvremove:将 PV 属性移除,让该 partition 不具有 PV 属性
# 检查有无 PV 在系统上 [root@study ~]# pvscan PV /dev/sda3 VG centos lvm2 [30.00 GiB / 14.00 GiB free] Total: 1 [30.00 GiB] / in use: 1 [30.00 GiB] / in no VG: 0 [0 ] # 在安装的时候就使用了 LVM 了, /dev/sda3 就是 # 将 /dev/sda{4-7} 建立成为 pv 格式 [root@study ~]# pvcreate /dev/sda{4,5,6,7} Physical volume "/dev/sda4" successfully created. Physical volume "/dev/sda5" successfully created. Physical volume "/dev/sda6" successfully created. Physical volume "/dev/sda7" successfully created. [root@study ~]# pvscan PV /dev/sda3 VG centos lvm2 [30.00 GiB / 14.00 GiB free] PV /dev/sda6 lvm2 [1.00 GiB] PV /dev/sda4 lvm2 [1.00 GiB] PV /dev/sda5 lvm2 [1.00 GiB] PV /dev/sda7 lvm2 [1.00 GiB] Total: 5 [34.00 GiB] / in use: 1 [30.00 GiB] / in no VG: 4 [4.00 GiB] # 最后一行显示整体 PV 的量 / 已经被使用到的 VG 的 PV 量 / 剩余 PV 量 # 更详细的列出系统上每个 PV 的个别信息 [root@study ~]# pvdisplay /dev/sda4 "/dev/sda4" is a new physical volume of "1.00 GiB" --- NEW Physical volume --- PV Name /dev/sda4 # 实际的 partition 装置名称 VG Name # 因为尚未分配出去,所以空白的 PV Size 1.00 GiB # 容量 Allocatable NO # 是否已被分配 PE Size 0 # 此 PV 内 PE 的大小 Total PE 0 # 共分区出几个 PE Free PE 0 # 没被 LV 用掉的 PE Allocated PE 0 # 可以被分配出去的 PE 数量 PV UUID ecfFVZ-Qesj-6xhF-3p0w-9GCO-ULGG-q9Kpg9 # 由于 PE 是建立 VG 时才给予的参数,所以这里看到的 PE 都会是 0 # 而且也没有多余的 PE 可共分配(allocatable)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36VG 阶段
与 VG 相关指令有:
- vgcreate:主要建立 VG 的指令,参数较多
- vgscan:搜索系统上的 VG
- vgdisplay:显示 VG 状态
- vgextend:在 VG 内增加额外的 PV
- vgreduce:在 VG 内移除 PV
- vgchange:设置 VG 是否启动(active)
- vgremove:删除一个 VG
PV 的名称其实就是 partition 的装置文件名,而 VG 的名称是自定义的。
vgcreate [-s N[mgt]] VG名称 PV名称 选项与参数: -s:后面接 PE 的大小 site,单位可以是 m、g、t 大小写均可
1
2
3
4# 将 /dev/sda4-6 建立为一个 VG,且指定 PE 为 16MB [root@study ~]# vgcreate -s 16M vmcrcodevg /dev/sda{4,5,6} Volume group "vmcrcodevg" successfully created [root@study ~]# pvscan PV /dev/sda4 VG vmcrcodevg lvm2 [1008.00 MiB / 1008.00 MiB free] PV /dev/sda5 VG vmcrcodevg lvm2 [1008.00 MiB / 1008.00 MiB free] PV /dev/sda6 VG vmcrcodevg lvm2 [1008.00 MiB / 1008.00 MiB free] PV /dev/sda3 VG centos lvm2 [30.00 GiB / 14.00 GiB free] PV /dev/sda7 lvm2 [1.00 GiB] Total: 5 [33.95 GiB] / in use: 4 [32.95 GiB] / in no VG: 1 [1.00 GiB] # 可以发现有 3 个 PV被分掉了 [root@study ~]# vgdisplay vmcrcodevg --- Volume group --- VG Name vmcrcodevg 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 2.95 GiB # 整体 VG 容量大小 PE Size 16.00 MiB # 内部每个 PE 的大小 Total PE 189 # 总共 PE 的数量 Alloc PE / Size 0 / 0 Free PE / Size 189 / 2.95 GiB # 可配置给 LV 的 PE 数量/ 总容量 VG UUID JQP2VZ-ilbN-MBuw-jccl-do84-tHu6-BInUXS # 剩余的 PV /dev/sda7 分配个 给 vmcrcodevg # 在 VG 内增加额外的 PV [root@study ~]# vgextend vmcrcodevg /dev/sda7 Volume group "vmcrcodevg" successfully extended [root@study ~]# vgdisplay vmcrcodevg --- Volume group --- VG Name vmcrcodevg System ID Format lvm2 Metadata Areas 4 Metadata Sequence No 2 VG Access read/write VG Status resizable MAX LV 0 Cur LV 0 Open LV 0 Max PV 0 Cur PV 4 Act PV 4 VG Size <3.94 GiB PE Size 16.00 MiB Total PE 252 # PE 变大了,可用容量也变大了 Alloc PE / Size 0 / 0 Free PE / Size 252 / <3.94 GiB VG UUID JQP2VZ-ilbN-MBuw-jccl-do84-tHu6-BInUXS
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60LV 阶段
有了 VG 这个大磁盘之后,就可以建立分区了。先了解与 LV 相关的指令:
- lvcreate:建立 LV
- lvscan:查询系统上的 LV
- lvdisplay:显示系统上面的 LV 状态
- lvextend:在 LV 里面增加容量
- lvreduce:在 LV 里面减少容量
- lvremove:删除一个 LV
- lvresize:对 LV 进行容量大小调整
lvcreate [-L N[mgt]] [-n lv名称] VG名称 lvcreate [-l n] [-n lv名称] VG名称 选项与参数: -L:后面接容量,要注意:最小单位为 PE,也就是必须的 PE 的倍数,如果不是,系统则自行计算最相近的容量 -l:后面接 PE 的个数,若要这么做,需要自行计算 PE 数 -n:后面接 LV 的名称
1
2
3
4
5
6
7# 将 vmcrcodevg 分 2GB 给 vmmrcodelv [root@study ~]# lvcreate -L 2G -n vmmrcodelv vmcrcodevg Logical volume "vmmrcodelv" created. [root@study ~]# lvscan ACTIVE '/dev/vmcrcodevg/vmmrcodelv' [2.00 GiB] inherit ACTIVE '/dev/centos/root' [10.00 GiB] inherit ACTIVE '/dev/centos/home' [5.00 GiB] inherit ACTIVE '/dev/centos/swap' [1.00 GiB] inherit # 由于本列中每个 PE 为 16M,如果要用 PE 的数量来处理的话,可以用下面的指令 # lvcreate -l 128 -n vmmrcodelv vmcrcodevg [root@study ~]# lvdisplay /dev/vmcrcodevg/vmmrcodelv --- Logical volume --- LV Path /dev/vmcrcodevg/vmmrcodelv # lv 全名 LV Name vmmrcodelv VG Name vmcrcodevg LV UUID V0WB3Y-SQr3-4hLb-D5IC-8fN6-6PEY-NPdJxz LV Write Access read/write LV Creation host, time study.centos.mrcode, 2020-03-01 22:03:40 +0800 LV Status available # open 0 LV Size 2.00 GiB # 容量 Current LE 128 Segments 3 Allocation inherit Read ahead sectors auto - currently set to 8192 Block device 253:3
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29文件系统阶段
[root@study ~]# mkfs.xfs /dev/vmcrcodevg/vmmrcodelv meta-data=/dev/vmcrcodevg/vmmrcodelv isize=512 agcount=4, agsize=131072 blks = sectsz=512 attr=2, projid32bit=1 = crc=1 finobt=0, sparse=0 data = bsize=4096 blocks=524288, imaxpct=25 = sunit=0 swidth=0 blks naming =version 2 bsize=4096 ascii-ci=0 ftype=1 log =internal log bsize=4096 blocks=2560, version=2 = sectsz=512 sunit=0 blks, lazy-count=1 realtime =none extsz=4096 blocks=0, rtextents=0 [root@study ~]# mount /dev/vmcrcodevg/vmmrcodelv /srv/lvm/ [root@study ~]# df -Th /srv/lvm/ 文件系统 类型 容量 已用 可用 已用% 挂载点 /dev/mapper/vmcrcodevg-vmmrcodelv xfs 2.0G 33M 2.0G 2% /srv/lvm
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15这就建立好一个 LV 了,可以使用 /srv/lvm 了
# 放大 LV 容量
LVM 最大的特色是弹性调整磁盘容量,前面说到,放大 LV 需要有下面这些流程:
VG 阶段需要有剩余的容量
如果 VG 阶段没有多余的容量,那么就增加硬盘等手段创建 PV,然后增加到 VG 中,可利用 pvcreate 和 vgextedn 来操作
LV 阶段产生更多可用容量
有了足够的 VG,那么可以使用 lvresize 指令将剩余容量加入到 LV 中
文件系统阶段放大
Linux 实际使用的其实不是 LV,而是 LV 这个装置内的文件系统,所以一切最终还是以文件系统为依归。目前在 Linux 下,作者测试过可以放大的文件系统有 XFS 和 EXT 家族,至于缩小则只有 EXT 家族,目前 XFS 文件系统不支持文件系统的容量缩小
xfs 放大可以通过 xfs_growfs 指令
最后一个步骤最重要,在第 7 章中知道,整个文件系统在最初格式化的时候就建立了 inode、block、superblock 等信息,要改变这些信息很难,不过因为文件系统格式化的时候建立的是多个 block group,因此可以通过在文件系统中增加 block group 的方式来增减文件系统的量,而增加 block group 就是利用 xfs_growfs 指令
另外,严格说起来,放大文件系统并不是没有进行格式化,格式化的位置在于该装置后来新增的部分,装置的前面已经存在的文件系统没有任何变化。新增的格式化过的数据,再反馈回原本的 supberblock 。
这里针对 /srv/lvm
增加 500MB 容量
# 检查 VG
[root@study ~]# vgdisplay vmcrcodevg
--- Volume group ---
VG Name vmcrcodevg
System ID
Format lvm2
Metadata Areas 4
Metadata Sequence No 3
VG Access read/write
VG Status resizable
MAX LV 0
Cur LV 1
Open LV 1
Max PV 0
Cur PV 4
Act PV 4
VG Size <3.94 GiB
PE Size 16.00 MiB
Total PE 252
Alloc PE / Size 128 / 2.00 GiB
Free PE / Size 124 / <1.94 GiB # 这里还有剩余的 PE 未使用
VG UUID JQP2VZ-ilbN-MBuw-jccl-do84-tHu6-BInUXS
# 直接放大 LV
[root@study ~]# lvresize -L +500 /dev/vmcrcodevg/vmmrcodelv
Rounding size to boundary between physical extents: 512.00 MiB.
Size of logical volume vmcrcodevg/vmmrcodelv changed from 2.00 GiB (128 extents) to 2.50 GiB (160 extents).
Logical volume vmcrcodevg/vmmrcodelv successfully resized.
[root@study ~]# lvscan
ACTIVE '/dev/vmcrcodevg/vmmrcodelv' [2.50 GiB] inherit
ACTIVE '/dev/centos/root' [10.00 GiB] inherit
ACTIVE '/dev/centos/home' [5.00 GiB] inherit
ACTIVE '/dev/centos/swap' [1.00 GiB] inherit
# 可以看到 lv 变大了
[root@study ~]# df -Th /srv/lvm/
Filesystem Type Size Used Avail Use% Mounted on
/dev/mapper/vmcrcodevg-vmmrcodelv xfs 2.0G 33M 2.0G 2% /srv/lvm
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
可以看到 LV 增加到了 2.5G,但是文件系统还未增加。下面继续处理文件系统的扩容
# 查看原文件系统内的 superblock 记录
[root@study ~]# xfs_info /srv/lvm/
meta-data=/dev/mapper/vmcrcodevg-vmmrcodelv isize=512 agcount=4, agsize=131072 blks
= sectsz=512 attr=2, projid32bit=1
= crc=1 finobt=0 spinodes=0
data = bsize=4096 blocks=524288, imaxpct=25
= sunit=0 swidth=0 blks
naming =version 2 bsize=4096 ascii-ci=0 ftype=1
log =internal bsize=4096 blocks=2560, version=2
= sectsz=512 sunit=0 blks, lazy-count=1
realtime =none extsz=4096 blocks=0, rtextents=0
# agcount=4,blocks=524288
# 很关键的一步来了
[root@study ~]# xfs_growfs /srv/lvm/
meta-data=/dev/mapper/vmcrcodevg-vmmrcodelv isize=512 agcount=4, agsize=131072 blks
= sectsz=512 attr=2, projid32bit=1
= crc=1 finobt=0 spinodes=0
data = bsize=4096 blocks=524288, imaxpct=25
= sunit=0 swidth=0 blks
naming =version 2 bsize=4096 ascii-ci=0 ftype=1
log =internal bsize=4096 blocks=2560, version=2
= sectsz=512 sunit=0 blks, lazy-count=1
realtime =none extsz=4096 blocks=0, rtextents=0
data blocks changed from 524288 to 655360
# 这里的 blocks 改变到 655360 了
[root@study ~]# xfs_info /srv/lvm/
meta-data=/dev/mapper/vmcrcodevg-vmmrcodelv isize=512 agcount=5, agsize=131072 blks
= sectsz=512 attr=2, projid32bit=1
= crc=1 finobt=0 spinodes=0
data = bsize=4096 blocks=655360, imaxpct=25
= sunit=0 swidth=0 blks
naming =version 2 bsize=4096 ascii-ci=0 ftype=1
log =internal bsize=4096 blocks=2560, version=2
= sectsz=512 sunit=0 blks, lazy-count=1
realtime =none extsz=4096 blocks=0, rtextents=0
# 现在 agcount=5,blocks=655360 了
[root@study ~]# df -Th /srv/lvm/
Filesystem Type Size Used Avail Use% Mounted on
/dev/mapper/vmcrcodevg-vmmrcodelv xfs 2.5G 33M 2.5G 2% /srv/lvm
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
如上展示了,在不停机的情况下可以进行扩容,很棒的特性;
最后注意,目前的 XFS 文件系统中,没有缩小文件系统容量的设计。只有 EXT 家族可以
# 使用 LVM thin Volume 让 LVM 动态自动调整磁盘使用率
考虑这样一个场景:有个目录未来会使用到大约 5T 的容量,但是目前你的磁盘只有 3T,但接下来的两个月你的系统都不会超过 3T 的容量,但是你要让用户知道,他最最多有 5T 的空间可以使用,而且在一个月内你确实可以将系统提升到 5T 以上的容量,又不想在提升容量后才放大到 5T,怎么办?
这个时候可以考虑:实际用多少才分配多少容量给 LV 的 LVM Thin Volume 功能
再考虑一个环境:你需要 3 个 10GB 的硬盘进行某些测试,但是你的环境只有 5Gb 的剩余容量,在传统的 LVM 环境下,LV 的容量是一开始就分配好的,因此你没有办法在这样的环境中产生出 3 个 10GB 的装置,而且 10GB 的装置其实每个实际使用率都没有超过 10%,也就是总用量目前只用到 3GB,你实际有 5GB的容量,那么久可以使用 LVM Thin Volume 做出 3 个只用 1GB 的 10GB 装置
LVM thin Volume 的概念是:先建立一个可以实支实付、用多少容量才分配实际写入多少容量的磁盘容量存储池(thin pool),然后再由这个 thin pool 去产生一个「指定要固定容量大小的 LV 装置」,但是这个 LV 在声明上,他的容量可能有 10GB,但实际上,该装置用到多少容量时,才会从 thin pool 去实际取得所需的容量』
thin pool 只有 1GB 的实际容量,但是可以分配一个 10GB 的 LV 装置,该装置实际用到 500M 时,thin pool 也就只有 500M 分配给他,但是由 thin pool 分配出来的 LV 总实际使用量绝对不能超过 thin pool 的最大实际容量
简单可以理解为:实际上你只有 1G 物理容量,但是你分配一个 10G 的 lv,只是这个 10G 的 lv 最大实际容量也就只有 1G
下面使用剩余的容量,来实践练习:
- 由 vmcrcodevg 的剩余容量取出 1GB 来做出一个名为 vmrcodetpool 的 thin pool LV 装置,这就是所谓的磁盘容量存储池 thin pool
- 由 vmcrcodevg 内的 vmrcodetpool 产生一个名为 vmrcodethin1 的 10GB LV 装置
- 将此装置实际格式化为 XFS 文件系统,并且挂载到
/srv/thin
目录内
# 创建 thin pool
[root@study ~]# lvcreate -L 1G -T vmcrcodevg/vmrcodetpool
Thin pool volume with chunk size 64.00 KiB can address at most 15.81 TiB of data.
Logical volume "vmrcodetpool" created.
[root@study ~]# lvdisplay /dev/vmcrcodevg/vmrcodetpool
--- Logical volume ---
LV Name vmrcodetpool
VG Name vmcrcodevg
LV UUID 163HRB-1gOB-6SOS-Dion-g29K-uOZr-deGTyl
LV Write Access read/write
LV Creation host, time study.centos.mrcode, 2020-03-01 22:40:42 +0800
LV Pool metadata vmrcodetpool_tmeta
LV Pool data vmrcodetpool_tdata
LV Status available
# open 0
LV Size 1.00 GiB # 总共可分配出去容量
Allocated pool data 0.00% # 以分配的容量百分比
Allocated metadata 10.23% # 以分配的数据百分比
Current LE 64
Segments 1
Allocation inherit
Read ahead sectors auto
- currently set to 8192
Block device 253:6
# 语法为 lvs VGname
[root@study ~]# lvs vmcrcodevg
LV VG Attr LSize Pool Origin Data% Meta% Move Log Cpy%Sync Convert
vmmrcodelv vmcrcodevg -wi-ao---- 2.50g
vmrcodetpool vmcrcodevg twi-a-tz-- 1.00g 0.00 10.23
# 开始建立 10GB 的装置
[root@study ~]# lvcreate -V 10G -T vmcrcodevg/vmrcodetpool -n vmrcrodethin1
WARNING: Sum of all thin volume sizes (10.00 GiB) exceeds the size of thin pool vmcrcodevg/vmrcodetpool and the size of whole volume group (<3.94 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 "vmrcrodethin1" created.
[root@study ~]# lvs vmcrcodevg
LV VG Attr LSize Pool Origin Data% Meta% Move Log Cpy%Sync Convert
vmmrcodelv vmcrcodevg -wi-ao---- 2.50g
vmrcodetpool vmcrcodevg twi-aotz-- 1.00g 0.00 10.25
vmrcrodethin1 vmcrcodevg Vwi-a-tz-- 10.00g vmrcodetpool 0.00
# 多了一个 vmrcrodethin1 还使用了 Pool,并且是 10Gb 的
# 创建文件系统
[root@study ~]# mkfs.xfs /dev/vmcrcodevg/vmrcrodethin1
meta-data=/dev/vmcrcodevg/vmrcrodethin1 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
[root@study ~]# mkdir /srv/thin
[root@study ~]# mount /dev/vmcrcodevg/vmrcrodethin1 /srv/thin/
[root@study ~]# df -Th /srv/thin/
Filesystem Type Size Used Avail Use% Mounted on
/dev/mapper/vmcrcodevg-vmrcrodethin1 xfs 10G 33M 10G 1% /srv/thin
# 可以看到文件系统中显示有 10GB 的容量
# 测试下容量的使用,建立 500MB 的文件
[root@study ~]# dd if=/dev/zero of=/srv/thin/test.img bs=1M count=500
500+0 records in
500+0 records out
524288000 bytes (524 MB) copied, 2.17685 s, 241 MB/s
[root@study ~]# df -Th /srv/thin/
Filesystem Type Size Used Avail Use% Mounted on
/dev/mapper/vmcrcodevg-vmrcrodethin1 xfs 10G 533M 9.5G 6% /srv/thin
[root@study ~]# lvs vmcrcodevg
LV VG Attr LSize Pool Origin Data% Meta% Move Log Cpy%Sync Convert
vmmrcodelv vmcrcodevg -wi-ao---- 2.50g
vmrcodetpool vmcrcodevg twi-aotz-- 1.00g 49.92 11.82
vmrcrodethin1 vmcrcodevg Vwi-aotz-- 10.00g vmrcodetpool 4.99
# 这时已经分配出去 49.92 的容量了,而 vmrcrodethin1 却只看到用掉了 4.99% 而已
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
所以 thin pool 非常好用,但是在管理上,要特别的留意
基本上 thin pool ,可以用来骗人,一个磁盘可以仿真出很多容量来,实际可用容量只有物理磁盘的容量,如果超过该容量,这个 thin pool 中的资料会损坏
# LVM 的 LV 磁盘快照
LVM 还有一个重要的能力,就是磁盘快照:将当时的系统信息记录下来,就好像照相记录一般,未来若有任何资料变动了,则原始资料会被搬移到快照区,没有被变动的区域则由快照区与文件系统共享。
上图很形象了,建立 LVM 会预留一个区域(左图的三个 PE 块)作为快照数据的存放。
由于快照区与原本的 LV 共享很多 PE 区块,因此 快照区与被快照的 LV 必须要在同一个 VG 上
另外,不建议使用 thin pool 来制作快照,限制太多了;
下面针对传统的 LV 磁盘进行快照的配置,大致流程为:
- 预计被拿来备份的原始 LV 为
/dev/vmcrcodevg/vmmrcodelv
- 使用传统方式快照建立,原始磁盘为
/dev/vmcrcodevg/vmmrcodelv
,快照名称为 vmrcodesnap1,容量为 vmcrcodevg 的所有剩余容量
# 传统快照区的建立
# 观察 VG 剩余容量
[root@study vmcrcodevg]# vgdisplay vmcrcodevg
--- Volume group ---
VG Name vmcrcodevg
System ID
Format lvm2
Metadata Areas 4
Metadata Sequence No 9
VG Access read/write
VG Status resizable
MAX LV 0
Cur LV 3
Open LV 0
Max PV 0
Cur PV 4
Act PV 4
VG Size <3.94 GiB
PE Size 16.00 MiB
Total PE 252
Alloc PE / Size 226 / 3.53 GiB
Free PE / Size 26 / 416.00 MiB # 还有 26 个PE
VG UUID JQP2VZ-ilbN-MBuw-jccl-do84-tHu6-BInUXS
# 创建快照区
# 注意:-n 后面是给快照区取名,笔者这里看错了,用了 vg 的名称
# 本应该与书上的 vmrcodesnap1 作为快照名称的
[root@study vmcrcodevg]# lvcreate -s -l 26 -n vmcrcodevg /dev/vmcrcodevg/vmmrcodelv
WARNING: Sum of all thin volume sizes (10.00 GiB) exceeds the size of thin pools and the size of whole volume group (<3.94 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 "vmcrcodevg" created.
# -s 表示 snapshot 功能, -n 后面则是快照区名称,再后面是在哪个 lv 上创建快照
# -l 后面则表示使用多少个 PE 来作为整个快照区使用
# 不过还好,使用了 vg
[root@study vmcrcodevg]# lvdisplay /dev/vmcrcodevg/vmcrcodevg
--- Logical volume ---
LV Path /dev/vmcrcodevg/vmcrcodevg
LV Name vmcrcodevg
VG Name vmcrcodevg
LV UUID gprMsU-6fXb-mAhu-xehC-jksk-rj4M-0na11O
LV Write Access read/write
LV Creation host, time study.centos.mrcode, 2020-03-02 22:26:19 +0800
LV snapshot status active destination for vmmrcodelv
LV Status available
# open 0
LV Size 2.50 GiB # 原始碟 lv 的容量
Current LE 160
COW-table size 416.00 MiB # 这个快照能够记录的最大容量
COW-table LE 26
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:11
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
快照区被建立起来了,仔细看他的 VG Name 与原本的 LV 所在 VG 相同。
下面来挂载这个快照区,挂载之后,你会发现里面的数据与原来的 LV 的数据是一样的
[root@study vmcrcodevg]# mkdir /srv/snapshot1
[root@study vmcrcodevg]# mount -o nouuid /dev/vmcrcodevg/vmcrcodevg /srv/snapshot1/
[root@study vmcrcodevg]# df -Th /srv/lvm/ /srv/snapshot1/
Filesystem Type Size Used Avail Use% Mounted on
/dev/mapper/vmcrcodevg-vmmrcodelv xfs 2.5G 33M 2.5G 2% /srv/lvm
/dev/mapper/vmcrcodevg-vmcrcodevg xfs 2.5G 33M 2.5G 2% /srv/snapshot1
# 可以看到数据是一模一样的,我们都没有动过该数据
# 快照区会主动记录员 lv 的内容
# nouui 参数:XFS 不允许相同的 UUID 文件系统挂载,所以需要加上让它忽略相同的 UUID 所造成的问题
# 因为快照出来的文件系统是一模一样的
2
3
4
5
6
7
8
9
10
11
# 利用快照区复原系统
需要注意的是:要复原的数据量不能高于快照区所能负载的实际容量。否则快照区肯定装不下,就会失效
# 1. 增加一些内容到 lvm ,查看两个区块的变化
[root@study vmcrcodevg]# df -Th /srv/lvm/ /srv/snapshot1/
Filesystem Type Size Used Avail Use% Mounted on
/dev/mapper/vmcrcodevg-vmmrcodelv xfs 2.5G 33M 2.5G 2% /srv/lvm
/dev/mapper/vmcrcodevg-vmcrcodevg xfs 2.5G 33M 2.5G 2% /srv/snapshot1
# 由于之前我忘记拷贝一些数据到 lvm 下了,看目录下面是空的内容
# 这里直接 copy 数据到该目录下
[root@study vmcrcodevg]# cp -a /etc/ /srv/lvm/
[root@study vmcrcodevg]# df -Th /srv/lvm/ /srv/snapshot1/
Filesystem Type Size Used Avail Use% Mounted on
/dev/mapper/vmcrcodevg-vmmrcodelv xfs 2.5G 92M 2.5G 4% /srv/lvm
/dev/mapper/vmcrcodevg-vmcrcodevg xfs 2.5G 33M 2.5G 2% /srv/snapshot1
[root@study vmcrcodevg]# ll /srv/lvm /srv/snapshot1/
/srv/lvm:
total 12
drwxr-xr-x. 143 root root 8192 Mar 1 17:29 etc
/srv/snapshot1/:
total 0
# 现在两个目录不一样了,检测一下快照 LV
[root@study vmcrcodevg]# lvdisplay /dev/vmcrcodevg/vmcrcodevg
--- Logical volume ---
LV Path /dev/vmcrcodevg/vmcrcodevg
LV Name vmcrcodevg
VG Name vmcrcodevg
LV UUID gprMsU-6fXb-mAhu-xehC-jksk-rj4M-0na11O
LV Write Access read/write
LV Creation host, time study.centos.mrcode, 2020-03-02 22:26:19 +0800
LV snapshot status active destination for vmmrcodelv
LV Status available
# open 1
LV Size 2.50 GiB
Current LE 160
COW-table size 416.00 MiB
COW-table LE 26
Allocated to snapshot 11.05% # 目前被使用掉的容量
Snapshot chunk size 4.00 KiB
Segments 1
Allocation inherit
Read ahead sectors auto
- currently set to 8192
Block device 253:11
# 2. 利用快照区将原本的 filesystem 备份,使用 xfsdump 来处理
[root@study vmcrcodevg]# xfsdump -l 0 -L lvm1 -M lvm1 -f /home/lvm.dump /srv/snapshot1
xfsdump: using file dump (drive_simple) strategy
xfsdump: version 3.1.7 (dump format 3.0) - type ^C for status and control
xfsdump: level 0 dump of study.centos.mrcode:/srv/snapshot1
xfsdump: dump date: Mon Mar 2 22:48:52 2020
xfsdump: session id: cf94cc10-3823-4138-b016-cc7e4c3b8964
xfsdump: session label: "lvm1"
xfsdump: ino map phase 1: constructing initial dump list
xfsdump: ino map phase 2: skipping (no pruning necessary)
xfsdump: ino map phase 3: skipping (only one dump stream)
xfsdump: ino map construction complete
xfsdump: estimated dump size: 20800 bytes
xfsdump: creating dump session media file 0 (media 0, file 0)
xfsdump: dumping ino map
xfsdump: dumping directories
xfsdump: dumping non-directory files
xfsdump: ending media file
xfsdump: media file size 21016 bytes
xfsdump: dump size (non-dir files) : 0 bytes
xfsdump: dump complete: 0 seconds elapsed
xfsdump: Dump Summary:
xfsdump: stream 0 /home/lvm.dump OK (success)
xfsdump: Dump Status: SUCCESS
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
为什么要备份?为什么不直接格式化?前面说到过,快照只会存储变化的数据,如果格式化,那么所有数据都会存到快照区的。快照区那么小,一般都不够存储的
# 3. 将 /srv/snapshot1 卸载并移除(因为里面的内容以及备份起来了)
[root@study vmcrcodevg]# umount /srv/snapshot1/
[root@study vmcrcodevg]# lvremove /dev/vmcrcodevg/vmcrcodevg
Do you really want to remove active logical volume vmcrcodevg/vmcrcodevg? [y/n]: y
Logical volume "vmcrcodevg" successfully removed
# 把快照功能卸除之后,把原始盘格式化
[root@study vmcrcodevg]# mkfs.xfs -f /dev/vmcrcodevg/vmmrcodelv
meta-data=/dev/vmcrcodevg/vmmrcodelv isize=512 agcount=4, agsize=163840 blks
= sectsz=512 attr=2, projid32bit=1
= crc=1 finobt=0, sparse=0
data = bsize=4096 blocks=655360, imaxpct=25
= sunit=0 swidth=0 blks
naming =version 2 bsize=4096 ascii-ci=0 ftype=1
log =internal log bsize=4096 blocks=2560, version=2
= sectsz=512 sunit=0 blks, lazy-count=1
realtime =none extsz=4096 blocks=0, rtextents=0
# 重新挂载,相当于已经没有数据了,
[root@study vmcrcodevg]# mount /dev/vmcrcodevg/vmmrcodelv /srv/lvm/
# 这里从备份的快照里面把数据恢复回去
[root@study vmcrcodevg]# xfsrestore -f /home/lvm.dump -L lvm1 /srv/lvm/
xfsrestore: using file dump (drive_simple) strategy
xfsrestore: version 3.1.7 (dump format 3.0) - type ^C for status and control
xfsrestore: using online session inventory
xfsrestore: searching media for directory dump
xfsrestore: examining media file 0
xfsrestore: reading directories
xfsrestore: 1 directories and 0 entries processed
xfsrestore: directory post-processing
xfsrestore: restore complete: 0 seconds elapsed
xfsrestore: Restore Summary:
xfsrestore: stream 0 /home/lvm.dump OK (success)
xfsrestore: Restore Status: SUCCESS
[root@study vmcrcodevg]# ll /srv/lvm
total 0
# 这里变成了 0,从这里我大概明白了这个快照的流程了
# 1. 创建快照的时候,可能是把当时那一刻的所有数据都放到了快照区,由于实际数据小于快照区,所以可以放下
# 2. 对原始盘修改的时候,只要不创建快照,数据就不会被同步过去
# 3. 这里备份快照区,再从快照区恢复创建快照时的数据
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
利用快照区进行各项练习与测试的任务,再以原系统还原快照:大概意思就是说,将原始数据当成备份,快照出来的快照区进行测试(当成真正的目录一样使用),要还原的时候就直接删掉快照区,再创建一个快照即可。
这里的思路和我上面自己理解的貌似类似,但是下面这张图貌似就说不通了
因为上面我们快照了数据,会发现快照和原始数据是一样的,在修改原始数据后,快照区数据并诶呦变化,然后我们备份了快照区的数据,并删除了快照区;然后再格式化了原始碟,那么这里公用的 PE 是不是貌似就说不通了? 或则换个说法来说,快照区备份实际上是把创建快照那一刻的所有数据都备份了(就是说是所有的原始数据,因为在创建快照哪一个点的所有数据),但其实如果不用备份的话,是没法恢复快照的,因为这里公用了 PE 的问题;快照会区分变化的文件,备份的时候回排除掉变化的文件。
上面的解释貌似可以通了
# LVM 相关指令汇总与 LVM 的关闭
任务 | PV 阶段 | VG 阶段 | LV 阶段 | filesystem-xfs | filesystem-ext4 |
---|---|---|---|---|---|
搜索scan | pvscan | vgscan | lvscan | lsblk、blkid | lsblk、blkid |
创建create | pvcreate | vgcreate | lvcreate | mkfs.xfs | mkfs.ext4 |
列出display | pvdisplay | vgdisplay | lvdisplay | df、mount | df、mount |
增加extend | vgextend | lvextend(lvresize) | xfs_growfs | resize2fs | |
减少reduce | vgreduce | lvreduce(lvresize) | 不支持 | resize2fs | |
删除remove | pvremove | vgremove | lvremove | umount、重新格式化 | umount、重新格式化 |
改变容量resize | lvresize | xfs_grows | resize2fs | ||
改变属性attribute | pvchange | vgchange | lvchange | /etc/fstab、remount | /etc/fstab、remount |
文件系统阶段的格式化处理,需要以 xfs_growfs 来修正文件系统实际的大小。
会规划 LVM 还不行,还需要会移除 LVM,流程如下:
- 先卸载系统上面的 LVM 文件系统(包括快照与所有 LV)
- 使用 lvremove 移除 LV
- 使用
vgchange -a n VGname
让 VGname 这个 VG 不具有 Active 标志 - 使用 vgremove 移除 VG
- 使用 pvremove 移除 PV
- 使用 fsidk 修改 ID,改回来
下面进行卸载练习
[root@study ~]# umount /srv/lvm/ /srv/thin/ /srv/snapshot1/
[root@study ~]# lvs vmcrcodevg
LV VG Attr LSize Pool Origin Data% Meta% Move Log Cpy%Sync Convert
vmmrcodelv vmcrcodevg -wi-a----- 2.50g
vmrcodetpool vmcrcodevg twi-aotz-- 1.00g 49.92 11.82
vmrcrodethin1 vmcrcodevg Vwi-a-tz-- 10.00g vmrcodetpool 4.99
# 注意,删除顺序是:vmrcrodethin1 > vmrcrodethin1 > vmmrcodelv
[root@study ~]# lvremove /dev/vmcrcodevg/vmrcrodethin1 /dev/vmcrcodevg/vmrcodetpool
Removing pool "vmrcodetpool" will remove 1 dependent volume(s). Proceed? [y/n]: y
Do you really want to remove active logical volume vmcrcodevg/vmrcrodethin1? [y/n]: y
Logical volume "vmrcrodethin1" successfully removed
Do you really want to remove active logical volume vmcrcodevg/vmrcodetpool? [y/n]: y
Logical volume "vmrcodetpool" successfully removed
[root@study ~]# lvremove /dev/vmcrcodevg/vmmrcodelv
Do you really want to remove active logical volume vmcrcodevg/vmmrcodelv? [y/n]: y
Logical volume "vmmrcodelv" successfully removed
[root@study ~]# vgchange -a n vmcrcodevg
0 logical volume(s) in volume group "vmcrcodevg" now active
[root@study ~]# vgremove vmcrcodevg
Volume group "vmcrcodevg" successfully removed
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
最后再使用 gdisk 将磁盘的 ID 给改回来 83 就可以了
gdisk /dev/sda
Command (? for help): p
Number Start (sector) End (sector) Size Code Name
1 2048 6143 2.0 MiB EF02
2 6144 2103295 1024.0 MiB 0700
3 2103296 65026047 30.0 GiB 8E00
4 65026048 67123199 1024.0 MiB 8E00 Linux LVM
5 67123200 69220351 1024.0 MiB 8E00 Linux LVM
6 69220352 71317503 1024.0 MiB 8E00 Linux LVM
7 71317504 73414655 1024.0 MiB 8E00 Linux LVM
8 73414656 75511807 1024.0 MiB 8E00 Linux LVM
# 修改 ID 也就是这里的 Code,可以看到这几个分区还是 8E00
2
3
4
5
6
7
8
9
10
11
12