LVM(Logical Volume Manager,逻辑卷管理器) 的重点在于可以弹性的调整文件系统的容量,而并非在于性能与数据安全上面。LVM 可以整合多个物理分区,让这些分区看起来就像是一个磁盘一样,而且,未来还可以在这个 LVM 管理的磁盘中新增或删除其他物理分区,如此一来,整个磁盘空间的使用上,就可以弹性分配
1、LVM简介
LVM 的作法是将几个物理分区或硬盘通过软件组合成为一块看起来是独立的大磁盘 (VG) ,然后将这块大磁盘再经过分区成为可使用分区 (LV),最终就能够挂载使用了
1.1、物理卷(Physical Volume,PV )
我们实际的分区或硬盘需要调整系统标识符 (system ID)成为 8e(LVM 的标识符),然后再经过 pvcreate 的命令将其转成 LVM 最底层的物理卷 (PV) ,之后才能够将这些 PV 加以利用。调整 system ID 的方是就是通过 gdisk 实现
1.2、卷组(Volume Group, VG)
所谓的 LVM 大磁盘就是将许多 PV 整合成这个 VG,所以 VG 就是 LVM 组合起来的大磁盘,VG 支持的最大容量和PE 以及 LVM 的格式版本有关,默认情况下,使用 32 位的 Linux 系统时,基本上 LV 最大仅能支持到 65534 个 PE,若使用默认的 PE 为 4MB 的情况下, 则最大容量仅能达到约 256GB,不过,这个问题在 64 位的 Linux 系统上面已经不存在了,LV 几乎没有啥容量限制了
1.3、物理扩展快(Physical Extent, PE)
LVM 默认使用 4MB 的 PE 数据块,而 LVM 的 LV 在 32 位系统上最多仅能含有 65534 个 PE(LVM1 的格式),因此默认的 LVM 的 LV 会有 4M * 65534 /(1024M / G)= 256G
PE 是整个 LVM 最小的储存数据单位,也就是说,其实我们的文件数据都是借由写入 PE 来完成的。PE 就有点像文件系统里面的 block 大小,因此调整 PE 会影响到 LVM 的最大容量,不过,在 CentOS 6.x 以后,由于直接使用 LVM2 的各项格式功能,以及系统转为 64 位,因此这个限制已经不存在了
1.4、逻辑卷(Logical Volume, LV)
最终的 VG 还会被切成 LV,这个 LV 就是最后可以被格式化使用的类似分区的东西,PE 是整个 LVM 的最小储存单位,LV 的大小与在此 LV 内的 PE 总数有关,为了方便用户利用 LVM 来管理其系统,LV 的设备文件名通常为 /dev/vgname/lvname 的样式
前面说使用 LVM 可以弹性的管理文件系统空间,其实就是通过调整 LV 中的 PE 数量实现的,要扩大容量,就加入 PE,要缩小文件系统空间就减少 PE 数量
1.5、LVM操作流程简介
通过 PV,VG,LV 的规划之后,再利用 mkfs 就可以将 LV 格式化成为可以利用的文件系统了,这个文件系统的容量在未来还能够进行扩充或减少,而且里面的数据还不会被影响,整个操作流程如下:
1.6、数据写入LV的方式
-
线性模式 (linear):假如将 /dev/sda1, /dev/sdb1 这两块硬盘加入到 VG 当中,并且整个 VG 只有一个 LV 时,那么所谓的线性模式就是:当 /dev/sda1 的容量用完之后,/dev/sdb1 的硬盘才会被使用,建议使用该模式
-
交错模式 (triped):就是将数据拆成两部分,分别写入 /dev/sda1 与 /dev/sdb1(与RAID0相似,如此,一份数据用两块硬盘来写入,理论上,读写的性能相对较好,但是如果有任何一块硬盘损坏,那么整个数据也就不保了
LVM 最主要的用处是在实现一个可以弹性调整容量的文件系统上,而不是在建立一个性能为主的磁盘上,所以,我们应该利用的是 LVM 可以弹性管理整个分区大小的用途上,而不是着眼在性能上的,因此,LVM 默认的读写模式就是线性模式
2、LVM实践操作
2.1、物理硬盘操作
-
物理硬盘分区
此处以操作一块硬盘为例,其他硬盘操作相同
[root@localhost ~]# gdisk /dev/sdb GPT fdisk (gdisk) version 0.8.10 Command (? for help): n Partition number (1-128, default 1): First sector (34-20971486, default = 2048) or {+-}size{KMGTP}: Last sector (2048-20971486, default = 20971486) or {+-}size{KMGTP}: Current type is 'Linux filesystem' # 此处code填8e00 Hex code or GUID (L to show codes, Enter = 8300): 8e00 Changed type of partition to 'Linux LVM' Command (? for help): w Do you want to proceed? (Y/N): y OK; writing new GUID partition table (GPT) to /dev/sdb. The operation has completed successfully.
-
查看硬盘分区格式
[root@localhost ~]# gdisk -l /dev/sdb Number Start (sector) End (sector) Size Code Name 1 2048 20971486 10.0 GiB 8E00 Linux LVM [root@localhost ~]# gdisk -l /dev/sdc Number Start (sector) End (sector) Size Code Name 1 2048 20971486 10.0 GiB 8E00 Linux LVM [root@localhost ~]# gdisk -l /dev/sdd Number Start (sector) End (sector) Size Code Name 1 2048 20971486 10.0 GiB 8E00 Linux LVM
2.2、PV操作
2.2.1、相关命令
- pvcreate :将物理分区建立成为 PV
- pvscan :查看目前系统里面所有具有 PV 的磁盘
- pvdisplay :查看目前系统上 PV 的状态
- pvremove :将 PV 属性删除
2.2.2、操作示例
-
查看系统上有没有PV
[root@localhost ~]# pvscan PV /dev/sda2 VG centos lvm2 [<39.00 GiB / 4.00 MiB free] Total: 1 [<39.00 GiB] / in use: 1 [<39.00 GiB] / in no VG: 0 [0 ]
-
创建PV
[root@localhost ~]# pvcreate /dev/sd{b,c,d}1 Physical volume "/dev/sdb1" successfully created. Physical volume "/dev/sdc1" successfully created. Physical volume "/dev/sdd1" successfully created. # 再次查看PV [root@localhost ~]# pvscan PV /dev/sda2 VG centos lvm2 [<39.00 GiB / 4.00 MiB free] PV /dev/sdb1 lvm2 [<10.00 GiB] PV /dev/sdc1 lvm2 [<10.00 GiB] PV /dev/sdd1 lvm2 [<10.00 GiB] ## 此处显示:整体PV的量 / 已使用VG的PV量 / 剩余的PV量 Total: 4 [68.99 GiB] / in use: 1 [<39.00 GiB] / in no VG: 3 [<30.00 GiB]
-
显示详细PV信息
[root@localhost ~]# pvdisplay /dev/sdb1 "/dev/sdb1" is a new physical volume of "<10.00 GiB" --- NEW Physical volume --- PV Name /dev/sdb1 # 实际的分区设备名称 VG Name # 没有分配,所以空白 PV Size <10.00 GiB # 该PV容量 Allocatable NO # 是否被分配 PE Size 0 # 此PV内PE的大小 Total PE 0 # 一共有多少个PE Free PE 0 # 未被LV使用的PE数量 Allocated PE 0 # 可以被分配的PE数量 PV UUID bHfJ2R-fVr6-c8WH-WLBz-Mxhl-2KBg-nRSetM ## 说明:由于PE是在建立VG时才分配的参数,因此在这里看到的PV里PE都是0,而且也没有分配的PE
2.3、VG操作
2.3.1、相关命令
-
vgcreate :创建VG
-
vgscan :查看系统上是否存在 VG
-
vgdisplay :显示目前系统上的 VG 状态
-
vgextend :在 VG 内增加 PV
-
vgreduce :在 VG 内删除 PV
-
vgchange :设置 VG 是否启动 (active)
-
vgremove :删除一个 VG
2.3.2、操作示例
-
创建VG
# 语法 vgcreate [-s N[mgt]] VG 名称 PV 名称 ## -s参数指定PE的大小,单位可以是:m、g、t(不区分大小写) # 将 /dev/sdb1、/dev/scd1 建立成为一个VG,且指定PE为16MB [root@localhost ~]# vgcreate -s 16m VG_1 /dev/sd{b,c}1 Volume group "VG_1" successfully created
-
查看系统现有VG
# 查看现有VG信息 [root@localhost ~]# vgscan Reading volume groups from cache. ## 刚才创建的 Found volume group "VG_1" using metadata type lvm2 ## 系统原有的 Found volume group "centos" using metadata type lvm2 # 查看PV信息 ## 两个PV已经加入VG_1,/dev/sdd1未加入 [root@localhost ~]# pvscan PV /dev/sda2 VG centos lvm2 [<39.00 GiB / 4.00 MiB free] PV /dev/sdb1 VG VG_1 lvm2 [9.98 GiB / 9.98 GiB free] PV /dev/sdc1 VG VG_1 lvm2 [9.98 GiB / 9.98 GiB free] PV /dev/sdd1 lvm2 [<10.00 GiB] Total: 4 [68.96 GiB] / in use: 3 [58.96 GiB] / in no VG: 1 [<10.00 GiB] # 查看VG详细信息 [root@localhost ~]# vgdisplay VG_1 --- Volume group --- VG Name VG_1 System ID Format lvm2 Metadata Areas 2 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 2 Act PV 2 ## 当前VG的总大小 VG Size <19.97 GiB ## 当前VG内每个PE的大小 PE Size 16.00 MiB ## 当前VG内PE的总数量 Total PE 1278 Alloc PE / Size 0 / 0 ## 可分配给LV的PE数量/总空间大小 Free PE / Size 1278 / <19.97 GiB VG UUID R5k1VZ-sw2K-DSbR-nOfO-9F8F-eXq2-ROTLeN
-
扩展VG
# 扩容VG [root@localhost ~]# vgextend VG_1 /dev/sdd1 Volume group "VG_1" successfully extended # 查看VG详细信息 [root@localhost ~]# vgdisplay VG_1 --- Volume group --- VG Name VG_1 VG Size 29.95 GiB PE Size 16.00 MiB Total PE 1917 Alloc PE / Size 0 / 0 Free PE / Size 1917 / 29.95 GiB VG UUID R5k1VZ-sw2K-DSbR-nOfO-9F8F-eXq2-ROTLeN ## VG的总空间大小与PE数量都增加了
2.4、LV操作
2.4.1、相关命令
-
lvcreate:创建 LV
-
lvscan :查看当前系统上的 LV
-
lvdisplay :显示当前系统上 LV 的状态
-
lvextend :LV 增加容量
-
lvreduce :LV 缩小容量
-
lvremove :删除 LV
-
lvresize :对 LV 进行容量大小的调整
2.4.2、操作示例
-
创建LV
# 语法 lvcreate [-L N[mgt]] [-n LV名称] VG名称 选项与参数: -L :后面接容量,单位可以是:M、G、T等(容量必须是PE大小的倍数,若不相符,系统会自动计算最相近的容量) -n :LV名称 # 创建一个2GB的LV [root@localhost ~]# lvcreate -L 2G -n LV_1 VG_1 Logical volume "LV_1" created.
-
查看现有LV
# 查看现有LV [root@localhost ~]# lvscan # 刚创建的GB的LV ACTIVE '/dev/VG_1/LV_1' [2.00 GiB] inherit ACTIVE '/dev/centos/swap' [2.00 GiB] inherit ACTIVE '/dev/centos/root' [36.99 GiB] inherit # 查看LV状态 [root@localhost ~]# lvdisplay /dev/VG_1/LV_1 --- Logical volume --- LV Path /dev/VG_1/LV_1 LV Name LV_1 VG Name VG_1 LV UUID 09LkZb-H0H4-z13N-k8ee-G8hS-Ucmj-oBa51d LV Write Access read/write LV Creation host, time localhost.localdomain, 2022-09-02 21:08:36 +0800 LV Status available # open 0 ## 当前LV大小 LV Size 2.00 GiB Current LE 128 Segments 1 Allocation inherit Read ahead sectors auto - currently set to 8192 Block device 253:2
2.5、LV的使用
[root@localhost ~]# mkfs.xfs /dev/VG_1/LV_1
[root@localhost ~]# mount /dev/VG_1/LV_1 /mnt/
[root@localhost ~]# df -lh
文件系统 容量 已用 可用 已用% 挂载点
/dev/mapper/VG_1-LV_1 2.0G 33M 2.0G 2% /mnt
3、LV扩容
3.1、LV扩容的流程
-
VG 阶段需要有剩余的容量:因为需要扩容文件系统,所以需要对 LV 扩容,但是如果没有多的 VG 容量, 那么 LV 与文件系统就无法扩容
-
LV 阶段产生更多的可用容量:如果 VG 的剩余容量足够,此时就可以利用
lvresize
命令将剩余容量加入到所需扩容的 LV 中 -
文件系统阶段的扩容:我们最终目的是对 LV 这个设备内的文件系统进行扩容
由于整个文件系统在格式化的时候就建立了inode、block、superblock 等信息,这些信息是无法改变的,不过因为文件系统格式化的时候创建的是多个区块组,因此我们可以通过在文件系统当中增加区块组的方式来扩容文件系统的容量
3.2、LV 扩容示例
-
查看VG剩余容量
[root@localhost ~]# vgdisplay VG_1 --- Volume group --- VG Size 29.95 GiB PE Size 16.00 MiB Total PE 1917 Alloc PE / Size 128 / 2.00 GiB Free PE / Size 1789 / 27.95 GiB VG UUID R5k1VZ-sw2K-DSbR-nOfO-9F8F-eXq2-ROTLeN
-
扩容LV
从上面的信息中可以看出,还有充足的空间可以使用
[root@localhost ~]# lvresize -L +500M /dev/VG_1/LV_1 Rounding size to boundary between physical extents: 512.00 MiB. Size of logical volume VG_1/LV_1 changed from 2.00 GiB (128 extents) to 2.50 GiB (160 extents). Logical volume VG_1/LV_1 successfully resized. # 确认扩容效果 [root@localhost ~]# lvscan ACTIVE '/dev/VG_1/LV_1' [2.50 GiB] inherit
-
扩容文件系统
# 查看原本的文件系统内的superblock记录 [root@localhost ~]# xfs_info /mnt meta-data=/dev/mapper/VG_1-LV_1 isize=512 agcount=4, agsize=131072 blks data = bsize=4096 blocks=524288, imaxpct=25 = sunit=0 swidth=0 blks # 扩容文件系统 [root@localhost ~]# xfs_growfs /mnt # 再次查看文件系统内的superblock记录 [root@localhost ~]# xfs_info /mnt meta-data=/dev/mapper/VG_1-LV_1 isize=512 agcount=5, agsize=131072 blks data = bsize=4096 blocks=655360, imaxpct=25 = sunit=0 swidth=0 blks # 查看文件系统大小 [root@localhost ~]# df -lh /mnt 文件系统 容量 已用 可用 已用% 挂载点 /dev/mapper/VG_1-LV_1 2.5G 33M 2.5G 2% /mnt
从两次 xfs_info 的结果来看,整个区块组 (agcount) 的数量增加 1 个,新增的 block group 就是纪录新的设备容量文件系统所在;整体的 block 数量增加了,这样整个文件系统就扩容成功了
4、LVM动态分配空间
在传统的空间分配上,我们是一次性将所有的空间一次性分配完毕,比如我们创建一个 5GB 的分区,那么系统就一次性从硬盘上划 5GB 空间出来,但实际我们可能最多只使用了 500M,那么剩下的 4.5GB 也就浪费了
LVM thin Volume 提供了一种动态分配空间的技术,即用多少,分配多少。还是以分配 5GB 空间为例,LVM thin Volume 会预分配一个最大空间限制为 5GB 的存储池,然后再由 thin pool 去产生一个指定大小的 LV 设备,此时 thin pool 并不会把 5GB 空间全部分配给 LV,而是按需分配,假如此时 LV 只是用了 500M 的空间,那么 thin pool 就只给 LV 分配 500M 的空间,但是 LV 的最大使用空间不能超过 5GB
-
使用lvcreate创建一个thin pool设备
[root@localhost ~]# lvcreate -L 1G -T VG_1/test_pool Thin pool volume with chunk size 64.00 KiB can address at most 15.81 TiB of data. Logical volume "test_pool" created.
-
查看创建的设备
[root@localhost ~]# lvdisplay /dev/VG_1/test_pool --- Logical volume --- LV Name test_pool VG Name VG_1 LV UUID olQfSe-FT11-aZEz-OMff-F3FI-6xmG-bvT3aB LV Write Access read/write LV Creation host, time localhost.localdomain, 2022-09-02 22:15:39 +0800 LV Pool metadata test_pool_tmeta LV Pool data test_pool_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:5 # 也可以使用lvs VGname的方式查看简要信息 [root@localhost ~]# lvs VG_1 LV VG Attr LSize Pool Origin Data% Meta% Move Log Cpy%Sync Convert LV_1 VG_1 -wi-ao---- 2.50g test_pool VG_1 twi-a-tz-- 1.00g 0.00 10.23
-
创建thin Volume
# 语法 lvcreate -V [容量] -T thin_pool_NAME -n thin_Volume_NAME # 创建一个5GB的 thin Volume ## 这里只是做一个示例,实际情况下,为了安全起见,不建议创建超过最大允许空间的分区 [root@localhost ~]# lvcreate -V 5G -T VG_1/test_pool -n tplv1 Logical volume "tplv1" created. ## 1GB的test_pool可以创建出5GB的tplv1 ## 这其实是假象,因为空间实际没有全部分配,实际最大使用空间不能超出1GB
-
查看创建的tplv1
[root@localhost ~]# lvs VG_1 LV VG Attr LSize Pool Origin Data% Meta% Move Log Cpy%Sync Convert LV_1 VG_1 -wi-ao---- 2.50g test_pool VG_1 twi-aotz-- 1.00g 0.00 10.25 tplv1 VG_1 Vwi-a-tz-- 5.00g test_pool 0.00
-
使用tplv1
[root@localhost ~]# mkfs.xfs /dev/VG_1/tplv [root@localhost ~]# mount /dev/VG_1/tplv1 /mnt [root@localhost ~]# df -Th /mnt 文件系统 类型 容量 已用 可用 已用% 挂载点 /dev/mapper/VG_1-tplv1 xfs 5.0G 33M 5.0G 1% /mnt
5、LVM拆除流程
-
卸载系统上的 LVM 文件系统(包括快照与所有 LV)
-
使用 lvremove 移除 LV
-
使用
vgchange -a n VG名称
移除 VG 的 Active 的标志 -
使用 vgremove 移除 VG
-
使用 pvremove 移除 PV
-
使用 fdisk 修改 ID
6、重要说明
在 LVM 中,虽然可以缩减 PV、VG、LV,但是在缩减后可能会导致数据丢失,所以一般不建议对 LVM 进行缩减操作
-
删除 PV 将删除当前受操作 PV 中的所有数据,如果确实需要减少 PV,在确保数据安全的情况下,建议从最后一个 PV 开始删除 (前提是 LV 采用线性模式写入)
-
删除 VG 将会删除该 VG 中的所有数据,且不可恢复
-
LV 建议只是用扩容, 不建议做缩减操作