LVM ( Logical V olume Manager, 逻辑卷管理器) 是 Linux 环境下对硬盘分区进行管理的一种机制,开创这项技术的初衷是为了解决传统硬盘分区创建后不易更改其大小的弱点。对于传统硬盘分区进行强制扩容和缩小技术理论上虽然是可行的,但却有可能造成数据的丢失,LVM 逻辑卷管理器技术能够将多块硬盘进行卷组合并,让用户不必关心设备底层的架构和布局,拿来即用。

Linux 磁盘管理:LVM 逻辑卷管理器 - 图1

LVM 逻辑卷管理器是在磁盘分区和文件系统之间添加的逻辑层,它提供了一个抽象的卷组,可以使得多块硬盘进行卷组合并,让用户不必关心物理硬盘设备的底层结构,从而实现对分区的灵活动态调整。

LVM 逻辑卷管理器的技术结构如图2 所示,刘遄老师来举个吃货的例子帮助同学们理解吧,比如家里想吃馒头但面粉不够了,妈妈分别从隔壁老王家、老李家、老张家借来一些面粉,蒸出馒头后大家一起来吃,首先咱们需要将这些面粉(物理卷 PV,Physical Volume)合并成一个大面团(卷组 VG,Volume Group),然后把这一大团面再分割成一个个小馒头(逻辑卷 LV,Logical Volume),每个小馒头的重量必须是每勺面粉(基本单元 PE,Physical Extent)的倍数。物理卷是处于逻辑卷管理器中最底层的资源,可以理解成是物理硬盘、硬盘分区或者RAID磁盘阵列组都可以,而卷组是建立在物理卷之上的,一个卷组中可以包含多个物理卷,当然在卷组创建之后也可以继续向其中添加新的物理卷,而逻辑卷是建立于卷组之上的,将卷组中空闲的资源建立出新的逻辑卷,并且逻辑卷建立后可以动态的扩展或缩小空间,这也就是 LVM 逻辑卷管理器的核心理念。(第7章 使用RAID与LVM磁盘阵列技术。

Linux 磁盘管理:LVM 逻辑卷管理器 - 图2

常用命令

部署 LVM 逻辑卷管理器需要依次对对物理卷、卷组和逻辑卷的逐个配置,常见的命令分别包括有:

功能/命令 物理卷管理 卷组管理 逻辑卷管理
扫描 pvscan vgscan lvscan
建立 pvcreate vgcreate lvcreate
显示 pvdisplay vgdisplay lvdisplay
删除 pvremove vgremove lvremove
缩小 vgreduce lvreduce
缩小 vgreduce lvreduce

实战展示

阿里云 ECS 扩充 4T 磁盘,并挂载。

1. 首先,新增两个物理硬盘 vdb(2199.0 GB),vdc(2199.0 GB)。 为接下来 做LVM 做准备。

  1. [root@iZ88qg9l425Z ~]# fdisk -l
  2. Disk /dev/vda: 42.9 GB, 42949672960 bytes
  3. 255 heads, 63 sectors/track, 5221 cylinders
  4. Units = cylinders of 16065 * 512 = 8225280 bytes
  5. Sector size (logical/physical): 512 bytes / 512 bytes
  6. I/O size (minimum/optimal): 512 bytes / 512 bytes
  7. Disk identifier: 0x00078f9c
  8. Device Boot Start End Blocks Id System
  9. /dev/vda1 * 1 5222 41940992 83 Linux
  10. Disk /dev/vdb: 2199.0 GB, 2199023255552 bytes
  11. 16 heads, 63 sectors/track, 4260880 cylinders
  12. Units = cylinders of 1008 * 512 = 516096 bytes
  13. Sector size (logical/physical): 512 bytes / 512 bytes
  14. I/O size (minimum/optimal): 512 bytes / 512 bytes
  15. Disk identifier: 0x00000000
  16. Disk /dev/vdc: 2199.0 GB, 2199023255552 bytes
  17. 16 heads, 63 sectors/track, 4260880 cylinders
  18. Units = cylinders of 1008 * 512 = 516096 bytes
  19. Sector size (logical/physical): 512 bytes / 512 bytes
  20. I/O size (minimum/optimal): 512 bytes / 512 bytes
  21. Disk identifier: 0x00000000

2. 对添加的物理硬盘(/dev/vdc)进行分区。

  1. [root@iZ88qg9l425Z ~]# fdisk /dev/vdc
  2. Device contains neither a valid DOS partition table, nor Sun, SGI or OSF disklabel
  3. Building a new DOS disklabel with disk identifier 0x4613ad5e.
  4. Changes will remain in memory only, until you decide to write them.
  5. After that, of course, the previous content won't be recoverable.
  6. Warning: invalid flag 0x0000 of partition table 4 will be corrected by w(rite)
  7. WARNING: The size of this disk is 2.2 TB (2199023255552 bytes).
  8. DOS partition table format can not be used on drives for volumes
  9. larger than (2199023255040 bytes) for 512-byte sectors. Use parted(1) and GUID
  10. partition table format (GPT).
  11. WARNING: DOS-compatible mode is deprecated. It's strongly recommended to
  12. switch off the mode (command 'c') and change display units to
  13. sectors (command 'u').
  14. Command (m for help): p
  15. Disk /dev/vdc: 2199.0 GB, 2199023255552 bytes
  16. 16 heads, 63 sectors/track, 4260880 cylinders
  17. Units = cylinders of 1008 * 512 = 516096 bytes
  18. Sector size (logical/physical): 512 bytes / 512 bytes
  19. I/O size (minimum/optimal): 512 bytes / 512 bytes
  20. Disk identifier: 0x4613ad5e
  21. Device Boot Start End Blocks Id System
  22. Command (m for help): n # 创建新分区
  23. Command action
  24. e extended # e 为逻辑分区
  25. p primary partition (1-4) # p 为主分区
  26. Select (default p): p
  27. Partition number (1-4): 1 # 由于是新盘我们输入1来分第一个主分区,共可以分4个主分区
  28. First sector (1-4260880, default 1): # 选择该分区的起始磁盘数,如无特殊需求强烈建议选择默认,也就是1来分区(可直接按回车)
  29. Using default value 1
  30. Last cylinder, +cylinders or +size{K,M,G} (1-4260880, default 4260880): # 定义该分区的大小,如果按默认(按回车)即是使用全部可用存储额,如分一个 1G 的空间,输入 +1024m
  31. Using default value 4260880
  32. Command (m for help): t # 改变分区标识符
  33. Selected partition 1
  34. Hex code (type L to list codes): 8e
  35. Changed system type of partition 1 to 8e (Linux LVM)
  36. Command (m for help): p
  37. Disk /dev/vdc: 2199.0 GB, 2199023255552 bytes
  38. 16 heads, 63 sectors/track, 4260880 cylinders
  39. Units = cylinders of 1008 * 512 = 516096 bytes
  40. Sector size (logical/physical): 512 bytes / 512 bytes
  41. I/O size (minimum/optimal): 512 bytes / 512 bytes
  42. Disk identifier: 0x4613ad5e
  43. Device Boot Start End Blocks Id System
  44. /dev/vdc1 1 4260880 2147483488+ 8e Linux LVM
  45. Command (m for help): w # 写入分区
  46. The partition table has been altered!
  47. Calling ioctl() to re-read partition table.
  48. Syncing disks.
  49. [root@iZ88qg9l425Z ~]#

3. 在新建的分区上创建 PV。

  1. [root@iZ88qg9l425Z ~]# pvcreate /dev/vdc1
  2. Physical volume "/dev/vdc1" successfully created
  3. [root@iZ88qg9l425Z ~]# pvs
  4. PV VG Fmt Attr PSize PFree
  5. /dev/vdc1 lvm2 a-- 2.00t 2.00t
  6. [root@iZ88qg9l425Z ~]# pvdisplay
  7. "/dev/vdc1" is a new physical volume of "2.00 TiB"
  8. --- NEW Physical volume ---
  9. PV Name /dev/vdc1
  10. VG Name
  11. PV Size 2.00 TiB
  12. Allocatable NO
  13. PE Size 0
  14. Total PE 0
  15. Free PE 0
  16. Allocated PE 0
  17. PV UUID 83IQY3-Z7O0-kicK-xIbJ-ZmUW-AlOF-ENUAp6
  18. [root@iZ88qg9l425Z ~]# fdisk -l
  19. Disk /dev/vda: 42.9 GB, 42949672960 bytes
  20. 255 heads, 63 sectors/track, 5221 cylinders
  21. Units = cylinders of 16065 * 512 = 8225280 bytes
  22. Sector size (logical/physical): 512 bytes / 512 bytes
  23. I/O size (minimum/optimal): 512 bytes / 512 bytes
  24. Disk identifier: 0x00078f9c
  25. Device Boot Start End Blocks Id System
  26. /dev/vda1 * 1 5222 41940992 83 Linux
  27. Disk /dev/vdb: 2199.0 GB, 2199023255552 bytes
  28. 16 heads, 63 sectors/track, 4260880 cylinders
  29. Units = cylinders of 1008 * 512 = 516096 bytes
  30. Sector size (logical/physical): 512 bytes / 512 bytes
  31. I/O size (minimum/optimal): 512 bytes / 512 bytes
  32. Disk identifier: 0x00000000
  33. Disk /dev/vdc: 2199.0 GB, 2199023255552 bytes
  34. 16 heads, 63 sectors/track, 4260880 cylinders
  35. Units = cylinders of 1008 * 512 = 516096 bytes
  36. Sector size (logical/physical): 512 bytes / 512 bytes
  37. I/O size (minimum/optimal): 512 bytes / 512 bytes
  38. Disk identifier: 0x4613ad5e
  39. Device Boot Start End Blocks Id System
  40. /dev/vdc1 1 4260880 2147483488+ 8e Linux LVM
  41. [root@iZ88qg9l425Z ~]# pvdisplay
  42. "/dev/vdb1" is a new physical volume of "2.00 TiB"
  43. --- NEW Physical volume ---
  44. PV Name /dev/vdb1
  45. VG Name
  46. PV Size 2.00 TiB
  47. Allocatable NO
  48. PE Size 0
  49. Total PE 0
  50. Free PE 0
  51. Allocated PE 0
  52. PV UUID YMNnk1-sdi5-zyhj-coI5-hwBJ-Kofw-2BLE58
  53. "/dev/vdc1" is a new physical volume of "2.00 TiB"
  54. --- NEW Physical volume ---
  55. PV Name /dev/vdc1
  56. VG Name
  57. PV Size 2.00 TiB
  58. Allocatable NO
  59. PE Size 0
  60. Total PE 0
  61. Free PE 0
  62. Allocated PE 0
  63. PV UUID 83IQY3-Z7O0-kicK-xIbJ-ZmUW-AlOF-ENUAp6

4. 将所有的新建的 PV 加入 vgdate。

  1. [root@iZ88qg9l425Z ~]# vgcreate vgdata /dev/vdb1 /dev/vdc1
  2. Volume group "vgdata" successfully created
  3. [root@iZ88qg9l425Z ~]# vgs
  4. VG #PV #LV #SN Attr VSize VFree
  5. vgdata 2 0 0 wz--n- 4.00t 4.00t
  6. [root@iZ88qg9l425Z ~]# vgdisplay
  7. --- Volume group ---
  8. VG Name vgdata
  9. System ID
  10. Format lvm2
  11. Metadata Areas 2
  12. Metadata Sequence No 1
  13. VG Access read/write
  14. VG Status resizable
  15. MAX LV 0
  16. Cur LV 0
  17. Open LV 0
  18. Max PV 0
  19. Cur PV 2
  20. Act PV 2
  21. VG Size 4.00 TiB
  22. PE Size 4.00 MiB
  23. Total PE 1048574
  24. Alloc PE / Size 0 / 0
  25. Free PE / Size 1048574 / 4.00 TiB
  26. VG UUID QafGYd-s0HW-6Wrx-pr6v-1fnR-mvpB-zrZ0md
  27. [root@iZ88qg9l425Z ~]# lvcreate -l 1048574 -n lvdata vgdata
  28. Logical volume "lvdata" created

5. 格式化并挂载。

  1. [root@iZ88qg9l425Z ~]# mkfs.ext4 -c /dev/vgdata/lvdata # 对分区使用 ext4 格式化,-c 参数要先检测磁盘坏道
  2. mke2fs 1.41.12 (17-May-2010)
  3. Filesystem label=
  4. OS type: Linux
  5. Block size=4096 (log=2)
  6. Fragment size=4096 (log=2)
  7. Stride=0 blocks, Stripe width=0 blocks
  8. 268435456 inodes, 1073739776 blocks
  9. 53686988 blocks (5.00%) reserved for the super user
  10. First data block=0
  11. Maximum filesystem blocks=4294967296
  12. 32768 block groups
  13. 32768 blocks per group, 32768 fragments per group
  14. 8192 inodes per group
  15. Superblock backups stored on blocks:
  16. 32768, 98304, 163840, 229376, 294912, 819200, 884736, 1605632, 2654208,
  17. 4096000, 7962624, 11239424, 20480000, 23887872, 71663616, 78675968,
  18. 102400000, 214990848, 512000000, 550731776, 644972544
  19. Writing inode tables: done
  20. Creating journal (32768 blocks): done
  21. Writing superblocks and filesystem accounting information: done
  22. This filesystem will be automatically checked every 32 mounts or
  23. 180 days, whichever comes first. Use tune2fs -c or -i to override.
  24. [root@iZ88qg9l425Z ~]# mkdir /disk1
  25. [root@iZ88qg9l425Z ~]# mount /dev/vgdata/lvdata /disk1/
  26. [root@iZ88qg9l425Z ~]# df -Th
  27. Filesystem Type Size Used Avail Use% Mounted on
  28. /dev/vda1 ext4 40G 3.6G 34G 10% /
  29. tmpfs tmpfs 3.9G 0 3.9G 0% /dev/shm
  30. /dev/mapper/vgdata-lvdata
  31. ext4 4.0T 195M 3.8T 1% /disk1
  32. [root@iZ88qg9l425Z ~]#

参考资料