Loading... # Linux-LVM 磁盘管理 ## 1. LVM简介 LVM(Logical Volume Manager)逻辑卷管理器,是一种磁盘管理技术,它将一个或多个物理磁盘组合成一个逻辑卷,用户可以在逻辑卷上创建文件系统,就像在普通磁盘上创建文件系统一样。LVM的主要优点是可以在不停机的情况下对磁盘进行扩容,缩容,快照等操作。 简单来说,就是 LVM 可以很方便的对硬盘进行扩容,缩容操作。 ## 2. LVM的基本概念 LVM 有几个重要概念,从上到下依次为: - PV(Physical Volume) 物理卷,**可以是硬盘,也可以是分区**。 - VG(Volume Group) 卷组,由一个或多个物理卷组成,可以理解为硬盘池。 - LV(Logical Volume) 逻辑卷,由卷组分出来的逻辑磁盘,可以理解为虚拟硬盘。最终也是将它挂载到文件系统上。 - PE(Physical Extent) 物理区块,物理卷和逻辑卷的最小单位,一般为4M。 - LE(Logical Extent) 逻辑区块,逻辑卷的最小单位,一般为4M。 PV、VG、LV的关系如下图所示: ![](https://cdn.jun6.net/2023/12/18/657fb1701b662.png?fmt=webp) ## 3. LVM的基本操作 ### 3.1. 创建物理卷 PV 首先可以使用 `fdisk -l` 或者 `lsblk` 查看当前系统的磁盘信息,如下图所示 (lsblk): > `lsblk` 是 `List block devices` 的缩写。 ```bash ☁ ~ lsblk NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINTS sda 8:0 0 10G 0 disk sdb 8:16 0 40G 0 disk ├─sdb1 8:17 0 39G 0 part / ├─sdb2 8:18 0 1K 0 part └─sdb5 8:21 0 975M 0 part [SWAP] sr0 11:0 1 628M 0 rom ``` 可以看到当前系统有两块磁盘,sda 和 sdb,sda 为 10G,sdb 为 40G,sda 上没有分区,sdb1 为系统根目录,sdb5 为交换分区。 这里我们使用 sda 创建一个物理卷 PV,使用 `pvcreate` 命令,如下所示: ```bash ☁ ~ sudo pvcreate /dev/sda Physical volume "/dev/sda" successfully created. ``` 使用 `pvdisplay` 命令查看物理卷信息,如下所示: ```bash ☁ ~ pvdisplay "/dev/sda" is a new physical volume of "10.00 GiB" --- NEW Physical volume --- PV Name /dev/sda VG Name PV Size 10.00 GiB Allocatable NO PE Size 0 Total PE 0 Free PE 0 Allocated PE 0 PV UUID B6J2T7-qV44-6gJq-vMWB-Aev8-xsQP-psPd3u ``` 可以看到,sda 已经创建为物理卷 PV,但是还没有分配给任何卷组 VG。 > 除了可直接对设备创建 PV,还可以对分区,也就是说允许一个硬盘创建两个分区,其中一个进行 PV,一个不进行,甚至两个分区可所属不同的 PV。 ### 3.2. 创建卷组 VG 使用 `vgcreate` 命令创建卷组 VG,如下所示: ```bash ☁ ~ vgcreate vg1 /dev/sda Volume group "vg1" successfully created ``` 使用 `vgdisplay` 命令查看卷组信息,如下所示: ```bash ☁ ~ vgdisplay --- Volume group --- VG Name vg1 System ID Format lvm2 Metadata Areas 1 Metadata Sequence No 1 VG Access read/write VG Status resizable MAX LV 0 # 最大逻辑卷数量,0 为无限制 Cur LV 0 # 当前逻辑卷数量 Open LV 0 # 当前打开的逻辑卷数量 Max PV 0 # 最大物理卷数量,0 为无限制 Cur PV 1 # 当前物理卷数量 Act PV 1 # 活动物理卷数量 VG Size <10.00 GiB # 整个 VG 的容量大小 PE Size 4.00 MiB # 每个 PE 的大小 Total PE 2559 # 总共有多少个 PE Alloc PE / Size 0 / 0 # 已经分配的 PE / 大小 Free PE / Size 2559 / <10.00 GiB # 剩余可分配的 PE / 大小 VG UUID PpCCuU-slml-5fF0-YxJe-I6bk-3rS0-3ePNyq ``` 主要可以看到,卷组 VG 的名称为 vg1,卷组大小为 10G,PE 大小为 4M,总共有 2559 个 PE,当前没有分配给任何逻辑卷 LV。 再通过 `pvdisplay` 命令查看物理卷信息,如下所示: ```bash ☁ ~ pvdisplay --- Physical volume --- PV Name /dev/sda VG Name vg1 PV Size 10.00 GiB / not usable 4.00 MiB Allocatable yes PE Size 4.00 MiB Total PE 2559 Free PE 2559 Allocated PE 0 PV UUID B6J2T7-qV44-6gJq-vMWB-Aev8-xsQP-psPd3u ``` 这次可以看到,VG Name 已经显示为 vg1,说明物理卷已经分配给了卷组。 ### 3.3. 创建逻辑卷 LV 使用 `lvcreate` 命令创建逻辑卷 LV,如下所示: ```bash ☁ ~ lvcreate -L 5G -n lv1 vg1 Logical volume "lv1" created. ``` 其中 -L 为逻辑卷大小,-n 为逻辑卷名称,vg1 为逻辑卷所在的卷组。(也可以使用 -l 参数指定 PE 数量,如 -l 1280) 使用 `lvdisplay` 命令查看逻辑卷信息,如下所示: ```bash ☁ ~ lvdisplay --- Logical volume --- LV Path /dev/vg1/lv1 LV Name lv1 VG Name vg1 LV UUID sy8J15-Tzuw-1J8P-UCqc-0gbF-wdHl-L8Zmfu LV Write Access read/write LV Creation host, time debian, 2023-12-18 10:53:05 +0800 LV Status available # open 0 LV Size 5.00 GiB Current LE 1280 Segments 1 Allocation inherit Read ahead sectors auto - currently set to 256 Block device 254:0 ``` ### 3.4. 创建文件系统 使用 `mkfs.ext4` 命令创建文件系统,如下所示: ```bash ☁ ~ mkfs.ext4 /dev/vg1/lv1 mke2fs 1.47.0 (5-Feb-2023) Creating filesystem with 1310720 4k blocks and 327680 inodes Filesystem UUID: a52d69bd-1b39-41ee-a669-104e6dbec1ae Superblock backups stored on blocks: 32768, 98304, 163840, 229376, 294912, 819200, 884736 Allocating group tables: done Writing inode tables: done Creating journal (16384 blocks): done Writing superblocks and filesystem accounting information: done ``` ### 3.5. 挂载文件系统 在挂载文件系统前,需要创建一个挂载点,也就是一个空的目录,我这里使用 `/mnt` 作为挂载点,然后使用 `mount` 命令挂载文件系统,如下所示: ```bash mkdir /mnt mount /dev/vg1/lv1 /mnt ``` 然后通过 `df -h` 命令查看挂载情况,如下所示: ```bash ☁ ~ df -h 文件系统 大小 已用 可用 已用% 挂载点 udev 3.9G 0 3.9G 0% /dev tmpfs 791M 768K 790M 1% /run /dev/sdb1 39G 14G 23G 38% / tmpfs 3.9G 0 3.9G 0% /dev/shm tmpfs 5.0M 0 5.0M 0% /run/lock tmpfs 791M 0 791M 0% /run/user/0 /dev/mapper/vg1-lv1 4.9G 24K 4.6G 1% /mnt ``` 可以看到,逻辑卷已经挂载到了 `/mnt` 目录下。然后再通过 `lsblk` 命令查看磁盘信息,如下所示: ```bash ☁ ~ lsblk NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINTS sda 8:0 0 10G 0 disk └─vg1-lv1 254:0 0 5G 0 lvm /mnt sdb 8:16 0 40G 0 disk ├─sdb1 8:17 0 39G 0 part / ├─sdb2 8:18 0 1K 0 part └─sdb5 8:21 0 975M 0 part [SWAP] sr0 11:0 1 628M 0 rom ``` 如果现在是临时挂载,重启后会失效,如果要永久挂载,需要修改 `/etc/fstab` 文件,添加如下内容: ```bash /dev/vg1/lv1 /mnt ext4 defaults 0 0 ``` ### 3.6. 扩容逻辑卷 LV 我们的 `/dev/sda` 磁盘大小为 10G,但是我们只使用了 5G,还有 5G 的空间没有使用,这时候我们就可以对逻辑卷进行扩容,使用 `lvextend` 命令扩容逻辑卷,如下所示: ```bash ☁ ~ lvextend -r -L +1G /dev/vg1/lv1 Size of logical volume vg1/lv1 changed from 5.00 GiB (1280 extents) to 6.00 GiB (1536 extents). Logical volume vg1/lv1 successfully resized. ``` 其中 `-r` 为自动缩容文件系统,不需要手动执行 `resize2fs`, `-L +1G` 为扩容 `1G`,如果要扩容到 `10G`,可以使用 `-L 10G`。 然后再通过 `df -h` 命令查看挂载情况,如下所示: ```bash ☁ ~ df -h 文件系统 大小 已用 可用 已用% 挂载点 udev 3.9G 0 3.9G 0% /dev tmpfs 791M 768K 790M 1% /run /dev/sdb1 39G 14G 23G 38% / tmpfs 3.9G 0 3.9G 0% /dev/shm tmpfs 5.0M 0 5.0M 0% /run/lock tmpfs 791M 0 791M 0% /run/user/0 /dev/mapper/vg1-lv1 5.9G 24K 5.6G 1% /mnt ``` ### 3.7. 缩容逻辑卷 LV 缩容要复杂一些,步骤如下: 1. 卸载文件系统:`umount /mnt` 2. 检查文件系统:`e2fsck -f /dev/vg1/lv1`, `-f` 为强制进行检查 3. 缩小逻辑卷至 5G:`lvreduce -r -L 5G /dev/vg1/lv1`,其中 `-r` 为自动缩容文件系统,不需要手动执行 `resize2fs`。如果想要缩小到可用空间的最小值,可以使用 `-l -1` 参数,如 `lvreduce -r -l -1 /dev/vg1/lv1`。 4. 再次检查文件系统:`e2fsck -f /dev/vg1/lv1` 5. 挂载文件系统:`mount /dev/vg1/lv1 /mnt` 6. 检查文件系统大小:`df -h` > 其中使用 `lvreduce` 命令缩容逻辑卷时,有以下两种方式: > - `-L -1G` 缩容 1G,如原来为 6G,缩容后为 5G > - `-L 1G` 缩容至 1G,如原来为 6G,缩容后为 1G **如果想要缩容至可用空间的最小值**,可以先通过 `resize2fs -P /dev/vg1/lv1` 查看预估的最小值,如: ```bash ☁ ~ resize2fs -P /dev/vg1/lv1 resize2fs 1.47.0 (5-Feb-2023) Estimated minimum size of the filesystem: 573865 ``` 这里返回的 573865 的单位是块 (block),查看每个块的大小可通过命令:`tune2fs -l /dev/vg1/lv1 | grep "Block size"`,如: ```bash ~ tune2fs -l /dev/vg1/lv1 | grep "Block size" Block size: 4096 ``` 这里返回的 4096 的单位是字节,通过计算 $573865 * 4096 = 2350551040 / 1024 / 1024 / 1024$ 可得约 `2.18912G`。为了安全,向上取整,可缩容为 `2.19G` 或 `2.2G`。 ### 3.8. 扩容卷组 VG 如我们现在的空间不够了,新加了一块 10G 的硬盘, 通过 `lsblk` 命令查看到新加的硬盘为 `/dev/sdc`。 然后我们先将 `/dev/sdc` 创建为物理卷 PV,然后将这个物理卷添加到先前创建的卷组 vg1 中(也可以创建一个新的卷组),如下所示: ```bash pvcreate /dev/sdc vgextend vg1 /dev/sdc ``` 这样现在 vg1 的大小就变成了 20G。 ### 3.9. 缩容卷组 VG 如我们觉得硬盘/分区有太多空闲,想去掉一块硬盘/分区,或者想更换硬盘(去掉旧的 PV 再添加新的 PV),可以进行缩容,但为了保证数据不丢失,需要先让卷组中有足够的空间来把要删除的 PV 中的数据迁移出去,然后再移除 PV。 如我们想要从 `vg1` 中移除 `/dev/sda`,步骤如下: 1. 检查卷组是否有足够的剩余空间可用于迁移数据,如果没有则需要减少分配给 LV 的空间或者扩容当前 VG。 2. 执行 `pvmove vg1 /dev/sda` 来从 vg1 上移除 `/dev/sda`。如果未进行第一步的话,这里会提示 `Physical volume "/dev/sda" still in use` 3. 根据需要选择是否执行 `pvremove /dev/sda` 将它从 PV 中移除(如果不再使用,则需要执行这一步) 4. 使用 `vgdisplay` 检查 vg 大小是否变化 ### 3.10 删除 LV VG PV 删除 LV: ```bash lvremove /dev/vg1/lv1 ``` 删除 VG: ```bash vgremove vg1 ``` 删除 PV: ```bash pvremove /dev/sda ``` ## 4. LVM 快照 ### 4.1 简介 LVM 快照是一种特殊的逻辑卷,它是对原始逻辑卷的一个快照,刚创建快照时,其实快照卷中并没有存储原始逻辑卷的数据,只有当原始逻辑卷的数据发生变化时,才会复制原始逻辑卷被修改的原数据到快照中,这样原始逻辑卷被修改,但对应的快照卷记录了修改前的数据,这样就可以通过快照卷恢复到修改前的状态。 还需要注意的是快照卷的大小,建议快照卷的大小和原始逻辑卷的大小一样,如果快照卷的大小小于原始逻辑卷的大小,当原始逻辑卷的数据发生变化较多的时,可能没有空间来存储原始逻辑卷的原数据。大于原始逻辑卷的大小也是没有意义的,因为快照卷只记录原始逻辑卷的原数据,肯定永远都不会超过原始逻辑卷的大小。 ### 4.2 创建快照 创建快照的命令为: ```bash lvcreate -s [-L <size>] -n SNAP_VOLUME [ -p|--permission rw|r ] SOURCE_VOLUME_PATH ``` 其中 `-s` 表示为快照卷,`-L` 表示快照卷的大小,`-n` 表示快照卷的名称,`-p` 表示快照卷的权限,`r` 表示只读,`rw` 表示读写,`SOURCE_VOLUME_PATH` 表示原始逻辑卷的路径。 如: ```bash lvcreate -s -L 5G -n lv1_snap -p r /dev/vg1/lv1 ``` 下面是一个示例: ```bash ☁ ~ lvcreate -L 5g -n lv1 vg1 WARNING: ext4 signature detected on /dev/vg1/lv1 at offset 1080. Wipe it? [y/n]: y Wiping ext4 signature on /dev/vg1/lv1. Logical volume "lv1" created. ☁ ~ mkfs.ext4 /dev/vg1/lv1 mke2fs 1.47.0 (5-Feb-2023) Creating filesystem with 1310720 4k blocks and 327680 inodes Filesystem UUID: 8a413a29-644e-40dc-906a-dee174d81202 Superblock backups stored on blocks: 32768, 98304, 163840, 229376, 294912, 819200, 884736 Allocating group tables: done Writing inode tables: done Creating journal (16384 blocks): done Writing superblocks and filesystem accounting information: done ☁ ~ mount /dev/vg1/lv1 /mnt ☁ ~ echo "test" > /mnt/1.txt ☁ ~ lvcreate -L 5G -n lv1_snap -p r -s /dev/vg1/lv1 Logical volume "lv1_snap" created. ☁ ~ mount /dev/vg1/lv1_snap /mnt2 mount: /mnt2: WARNING: source write-protected, mounted read-only. ☁ ~ df -h 文件系统 大小 已用 可用 已用% 挂载点 udev 3.9G 0 3.9G 0% /dev tmpfs 791M 888K 790M 1% /run /dev/sdc1 39G 26G 11G 71% / tmpfs 3.9G 0 3.9G 0% /dev/shm tmpfs 5.0M 0 5.0M 0% /run/lock tmpfs 791M 0 791M 0% /run/user/0 /dev/mapper/vg1-lv1 4.9G 28K 4.6G 1% /mnt /dev/mapper/vg1-lv1_snap 4.9G 28K 4.6G 1% /mnt2 ☁ ~ echo "test123123123" > /mnt/1.txt ☁ ~ echo "test" > /mnt/2.txt ☁ ~ ls -l /mnt 总计 24 -rw-r--r-- 1 root root 14 12月21日 10:34 1.txt -rw-r--r-- 1 root root 5 12月21日 10:34 2.txt drwx------ 2 root root 16384 12月21日 10:32 lost+found ☁ ~ ls -l /mnt2 总计 20 -rw-r--r-- 1 root root 5 12月21日 10:33 1.txt drwx------ 2 root root 16384 12月21日 10:32 lost+found ☁ ~ cat /mnt/1.txt test123123123 ☁ ~ cat /mnt2/1.txt test ``` 可以看到,我们创建了一个逻辑卷 lv1,然后挂载到 /mnt 目录,并将文本内容 "test" 写入到了 /mnt/1.txt,然后创建了一个快照 lv1_snap,挂载到 /mnt2 目录,这时修改了 /mnt/1.txt 的内容为 "test123123123",然后再次查看 /mnt/1.txt 和 /mnt2/1.txt 的内容,可以看到 /mnt/1.txt 的内容已经发生了变化,而 /mnt2/1.txt 的内容还是 "test",这是因为快照卷记录了 /mnt/1.txt 的原数据,所以 /mnt2/1.txt 的内容还是 "test"。同时,我们还创建了一个 /mnt/2.txt 文件,这个文件只会出现在 /mnt 目录下,而不会出现在 /mnt2 目录下,因为快照卷只记录了原始逻辑卷的原数据,而不会记录原始逻辑卷新增的数据。 > 注意快照不能用于替代备份,因为快照卷只记录了原始逻辑卷修改后的原数据,当原始逻辑卷或所属卷组损坏时,快照卷也会损坏。 ### 4.3 还原快照 还原快照的命令为: ```bash lvconvert --merge SOURCE_SNAPSHOT_VOLUME_PATH ``` 其中 `SOURCE_SNAPSHOT_VOLUME_PATH` 为快照卷的路径。使用该命令后,**快照卷会被删除,原始逻辑卷会恢复到快照卷创建时的状态**。 ## 5. LVM 诊断 ### 5.1. 查看各个 PV 占用情况 使用 `pvdisplay -m` 命令查看各个 PV 占用情况,如下所示: ```bash ☁ ~ pvdisplay -m --- Physical volume --- PV Name /dev/sda VG Name vg1 PV Size 10.00 GiB / not usable 4.00 MiB Allocatable yes (but full) PE Size 4.00 MiB Total PE 2559 Free PE 0 Allocated PE 2559 PV UUID Ly2wh9-c8iU-h2Gn-4REY-ioZJ-ykJG-uysyAC --- Physical Segments --- Physical extent 0 to 2558: Logical volume /dev/vg1/lv1 Logical extents 0 to 2558 --- Physical volume --- PV Name /dev/sdc VG Name vg1 PV Size 10.00 GiB / not usable 4.00 MiB Allocatable yes PE Size 4.00 MiB Total PE 2559 Free PE 510 Allocated PE 2049 PV UUID yfRAu7-EX5S-nlQL-YcdH-N7N1-Layf-QJ2ivo --- Physical Segments --- Physical extent 0 to 2048: Logical volume /dev/vg1/lv1 Logical extents 2559 to 4607 Physical extent 2049 to 2558: FREE ``` 也可以使用 `pvscan` 命令查看,如下所示: ```bash ☁ ~ pvscan PV /dev/sda VG vg1 lvm2 [<10.00 GiB / 0 free] PV /dev/sdc VG vg1 lvm2 [<10.00 GiB / 1.99 GiB free] Total: 2 [19.99 GiB] / in use: 2 [19.99 GiB] / in no VG: 0 [0 ] ``` ### 5.2. 查看各个 VG/VL 占用情况 同 `pvdisplay -m` 命令一样,只是命令前的 `pv` 换成 `vg` 或 `lv`。 最后修改:2023 年 12 月 21 日 © 允许规范转载 打赏 赞赏作者 支付宝微信 赞 如果觉得我的文章对你有用,请我喝杯咖啡吧。