LVM是一个device mapper框架,用来支持在多个磁盘或分区上建立逻辑分区。当前的实现是LVM2
logical volumes有下列好处
Flexible capacity
Resizeable storage pools
disk striping
mirroring volumes
volume snapshots
LVM包括3个部分
physical volume (PV)
volume group (VG)
logical volume (LV)
LVM logical volume components如下图所示:
PV是LVM的底层物理存储单元。PV可以创建在整个磁盘上,也可以创建在一个分区上。
每个PV都包含了LVM Label,通常存储在第二个sector。
LVM Label包含了 PV UUID等信息。
PV设备还包含了LVM metadata。存储LVM volume groups的详细配置信息。LVM medtadata很小,存储为ASCII可读字符串形式。
使用pvcreate命令创建PV。会写入LVM label等数据到磁盘。
# pvcreate /dev/loop22
查看内容
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23  | # hexdump -C /dev/loop2200000000  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|*00000200  4c 41 42 45 4c 4f 4e 45  01 00 00 00 00 00 00 00  |LABELONE........|00000210  c7 63 a2 d9 20 00 00 00  4c 56 4d 32 20 30 30 31  |.c.. ...LVM2 001|00000220  4f 41 58 6d 57 52 78 63  77 59 6a 64 58 65 62 6a  |OAXmWRxcwYjdXebj|00000230  64 4d 43 71 6d 72 63 39  58 31 5a 46 4c 75 37 6f  |dMCqmrc9X1ZFLu7o|00000240  00 00 00 08 00 00 00 00  00 00 10 00 00 00 00 00  |................|00000250  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|00000260  00 00 00 00 00 00 00 00  00 10 00 00 00 00 00 00  |................|00000270  00 f0 0f 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|00000280  00 00 00 00 00 00 00 00  02 00 00 00 00 00 00 00  |................|00000290  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|*00000800  ff ff ff ff ff ff ff ff  ff ff ff ff ff ff ff ff  |................|*00001000  16 d6 8e db 20 4c 56 4d  32 20 78 5b 35 41 25 72  |.... LVM2 x[5A%r|00001010  30 4e 2a 3e 01 00 00 00  00 10 00 00 00 00 00 00  |0N*>............|00001020  00 f0 0f 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|00001030  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|*00002000  ff ff ff ff ff ff ff ff  ff ff ff ff ff ff ff ff  |................|* | 
查看sector size,大小一般都为512
# blockdev --getss /dev/loop22
512
可以看到在第1个sector,和第8个sector写入了信息。
扫描block devices,lvmdiskscan
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  | # lvmdiskscan  /dev/loop1  [    <505.09 MiB]  /dev/sda1   [     512.00 MiB]  /dev/loop2  [      55.66 MiB]  /dev/sda2   [    <599.50 GiB]  /dev/loop3  [     <63.95 MiB]  /dev/loop4  [     <63.95 MiB]  /dev/loop5  [     104.19 MiB]  /dev/loop6  [      55.66 MiB]  /dev/loop7  [      74.27 MiB]  /dev/loop8  [     103.99 MiB]  /dev/loop9  [     218.39 MiB]  /dev/loop10 [     504.15 MiB]  /dev/loop11 [     349.69 MiB]  /dev/loop12 [      74.27 MiB]  /dev/loop13 [    <349.70 MiB]  /dev/loop14 [      38.73 MiB]  /dev/loop15 [      81.26 MiB]  /dev/loop16 [     <38.83 MiB]  /dev/loop17 [     218.39 MiB]  /dev/sdb1   [    <256.00 GiB]  /dev/loop18 [      12.32 MiB]  /dev/loop19 [     <91.69 MiB]  /dev/loop20 [     <12.93 MiB]  /dev/loop21 [      74.27 MiB]  /dev/loop22 [     128.00 MiB] LVM physical volume  /dev/loop23 [     128.00 MiB]  0 disks  25 partitions  0 LVM physical volume whole disks  1 LVM physical volume | 
有3个命令:pvs,pvdisplay,pvscan。
pvs提供很好的自定义输出和格式控制,很适合脚本使用。
pvdisplay提供多行显示。
pvscan扫描所有PV的块设备。pvscan支持配置文件lvm.conf。可以不扫描特定block,扫描结果保存到配置等。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19  | # pvs  PV          VG Fmt  Attr PSize   PFree  /dev/loop22    lvm2 ---  128.00m 128.00mroot@yuan-vm:/work/lvm# pvdisplay  "/dev/loop22" is a new physical volume of "128.00 MiB"  --- NEW Physical volume ---  PV Name               /dev/loop22  VG Name  PV Size               128.00 MiB  Allocatable           NO  PE Size               0  Total PE              0  Free PE               0  Allocated PE          0  PV UUID               OAXmWR-xcwY-jdXe-bjdM-Cqmr-c9X1-ZFLu7oroot@yuan-vm:/work/lvm# pvscan  PV /dev/loop22                      lvm2 [128.00 MiB]  Total: 1 [128.00 MiB] / in use: 0 [0   ] / in no VG: 1 [128.00 MiB] | 
如果磁盘坏了,或者要移除一个PV,可以设置这个PV禁止分配physical extents。
使用pvchange命令,注意:这个PV需要先加入到VG才可以设置。
1 2 3 4  | # pvchange -x n /dev/loop22  Allocatability not supported by orphan lvm2 format PV /dev/loop22  Physical volume /dev/loop22 not changed  0 physical volumes changed / 1 physical volume not changed | 
使用pvresize命令
使用pvremove,擦除LVM label、清空LVM metadata。恢复到正常的磁盘状态。是pvcreate的反向操作。
# pvremove /dev/loop22
Labels on physical volume "/dev/loop22" successfully wiped.
多个PV组成虚拟的VG。在VG内部,最小存储单元叫做extents,叫做logical extens (LE)。
对应到PV,叫做physical extents(PE)。LE等于PE。VG维护LE到PE的映射关系。
使用vgcreate命令创建vg。
# vgcreate vg1 /dev/loop22 /dev/loop23
Volume group "vg1" successfully created
创建vg后,会写入vg信息,且两个pv上的这个信息相同。
hexdump查看多了:
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 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85  | # hexdump -C /dev/loop2200000000  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|*00000200  4c 41 42 45 4c 4f 4e 45  01 00 00 00 00 00 00 00  |LABELONE........|00000210  00 ff 79 40 20 00 00 00  4c 56 4d 32 20 30 30 31  |..y@ ...LVM2 001|00000220  65 68 32 45 64 66 39 7a  61 54 49 6c 6d 67 6d 67  |eh2Edf9zaTIlmgmg|00000230  76 65 53 74 56 32 44 4e  72 6c 44 53 61 5a 63 76  |veStV2DNrlDSaZcv|00000240  00 00 00 08 00 00 00 00  00 00 10 00 00 00 00 00  |................|00000250  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|00000260  00 00 00 00 00 00 00 00  00 10 00 00 00 00 00 00  |................|00000270  00 f0 0f 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|00000280  00 00 00 00 00 00 00 00  02 00 00 00 01 00 00 00  |................|00000290  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|*00000800  ff ff ff ff ff ff ff ff  ff ff ff ff ff ff ff ff  |................|*00001000  ea 2d 64 14 20 4c 56 4d  32 20 78 5b 35 41 25 72  |.-d. LVM2 x[5A%r|00001010  30 4e 2a 3e 01 00 00 00  00 10 00 00 00 00 00 00  |0N*>............|00001020  00 f0 0f 00 00 00 00 00  00 02 00 00 00 00 00 00  |................|00001030  93 03 00 00 00 00 00 00  8a 46 06 16 00 00 00 00  |.........F......|00001040  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|*00001200  76 67 31 20 7b 0a 69 64  20 3d 20 22 6a 62 53 46  |vg1 {.id = "jbSF|00001210  49 70 2d 55 4a 70 54 2d  4f 78 45 77 2d 6a 67 64  |Ip-UJpT-OxEw-jgd|00001220  42 2d 31 64 56 4b 2d 73  6b 41 6a 2d 72 6c 79 4d  |B-1dVK-skAj-rlyM|00001230  72 32 22 0a 73 65 71 6e  6f 20 3d 20 31 0a 66 6f  |r2".seqno = 1.fo|00001240  72 6d 61 74 20 3d 20 22  6c 76 6d 32 22 0a 73 74  |rmat = "lvm2".st|00001250  61 74 75 73 20 3d 20 5b  22 52 45 53 49 5a 45 41  |atus = ["RESIZEA|00001260  42 4c 45 22 2c 20 22 52  45 41 44 22 2c 20 22 57  |BLE", "READ", "W|00001270  52 49 54 45 22 5d 0a 66  6c 61 67 73 20 3d 20 5b  |RITE"].flags = [|00001280  5d 0a 65 78 74 65 6e 74  5f 73 69 7a 65 20 3d 20  |].extent_size = |00001290  38 31 39 32 0a 6d 61 78  5f 6c 76 20 3d 20 30 0a  |8192.max_lv = 0.|000012a0  6d 61 78 5f 70 76 20 3d  20 30 0a 6d 65 74 61 64  |max_pv = 0.metad|000012b0  61 74 61 5f 63 6f 70 69  65 73 20 3d 20 30 0a 0a  |ata_copies = 0..|000012c0  70 68 79 73 69 63 61 6c  5f 76 6f 6c 75 6d 65 73  |physical_volumes|000012d0  20 7b 0a 0a 70 76 30 20  7b 0a 69 64 20 3d 20 22  | {..pv0 {.id = "|000012e0  65 68 32 45 64 66 2d 39  7a 61 54 2d 49 6c 6d 67  |eh2Edf-9zaT-Ilmg|000012f0  2d 6d 67 76 65 2d 53 74  56 32 2d 44 4e 72 6c 2d  |-mgve-StV2-DNrl-|00001300  44 53 61 5a 63 76 22 0a  64 65 76 69 63 65 20 3d  |DSaZcv".device =|00001310  20 22 2f 64 65 76 2f 6c  6f 6f 70 32 32 22 0a 0a  | "/dev/loop22"..|00001320  73 74 61 74 75 73 20 3d  20 5b 22 41 4c 4c 4f 43  |status = ["ALLOC|00001330  41 54 41 42 4c 45 22 5d  0a 66 6c 61 67 73 20 3d  |ATABLE"].flags =|00001340  20 5b 5d 0a 64 65 76 5f  73 69 7a 65 20 3d 20 32  | [].dev_size = 2|00001350  36 32 31 34 34 0a 70 65  5f 73 74 61 72 74 20 3d  |62144.pe_start =|00001360  20 32 30 34 38 0a 70 65  5f 63 6f 75 6e 74 20 3d  | 2048.pe_count =|00001370  20 33 31 0a 7d 0a 0a 70  76 31 20 7b 0a 69 64 20  | 31.}..pv1 {.id |00001380  3d 20 22 72 47 75 42 63  57 2d 72 6c 5a 6a 2d 45  |= "rGuBcW-rlZj-E|00001390  77 53 6b 2d 4d 4b 4e 30  2d 4b 67 6c 61 2d 50 57  |wSk-MKN0-Kgla-PW|000013a0  52 7a 2d 7a 61 75 58 4f  63 22 0a 64 65 76 69 63  |Rz-zauXOc".devic|000013b0  65 20 3d 20 22 2f 64 65  76 2f 6c 6f 6f 70 32 33  |e = "/dev/loop23|000013c0  22 0a 0a 73 74 61 74 75  73 20 3d 20 5b 22 41 4c  |"..status = ["AL|000013d0  4c 4f 43 41 54 41 42 4c  45 22 5d 0a 66 6c 61 67  |LOCATABLE"].flag|000013e0  73 20 3d 20 5b 5d 0a 64  65 76 5f 73 69 7a 65 20  |s = [].dev_size |000013f0  3d 20 32 36 32 31 34 34  0a 70 65 5f 73 74 61 72  |= 262144.pe_star|00001400  74 20 3d 20 32 30 34 38  0a 70 65 5f 63 6f 75 6e  |t = 2048.pe_coun|00001410  74 20 3d 20 33 31 0a 7d  0a 7d 0a 0a 0a 7d 0a 23  |t = 31.}.}...}.#|00001420  20 47 65 6e 65 72 61 74  65 64 20 62 79 20 4c 56  | Generated by LV|00001430  4d 32 20 76 65 72 73 69  6f 6e 20 32 2e 30 33 2e  |M2 version 2.03.|00001440  30 37 28 32 29 20 28 32  30 31 39 2d 31 31 2d 33  |07(2) (2019-11-3|00001450  30 29 3a 20 57 65 64 20  53 65 70 20 31 31 20 31  |0): Wed Sep 11 1|00001460  30 3a 33 39 3a 30 38 20  32 30 32 34 0a 0a 63 6f  |0:39:08 2024..co|00001470  6e 74 65 6e 74 73 20 3d  20 22 54 65 78 74 20 46  |ntents = "Text F|00001480  6f 72 6d 61 74 20 56 6f  6c 75 6d 65 20 47 72 6f  |ormat Volume Gro|00001490  75 70 22 0a 76 65 72 73  69 6f 6e 20 3d 20 31 0a  |up".version = 1.|000014a0  0a 64 65 73 63 72 69 70  74 69 6f 6e 20 3d 20 22  |.description = "|000014b0  57 72 69 74 65 20 66 72  6f 6d 20 76 67 63 72 65  |Write from vgcre|000014c0  61 74 65 20 76 67 31 20  2f 64 65 76 2f 6c 6f 6f  |ate vg1 /dev/loo|000014d0  70 32 32 20 2f 64 65 76  2f 6c 6f 6f 70 32 33 2e  |p22 /dev/loop23.|000014e0  22 0a 0a 63 72 65 61 74  69 6f 6e 5f 68 6f 73 74  |"..creation_host|000014f0  20 3d 20 22 79 75 61 6e  2d 76 6d 22 09 23 20 4c  | = "yuan-vm".# L|00001500  69 6e 75 78 20 79 75 61  6e 2d 76 6d 20 35 2e 31  |inux yuan-vm 5.1|00001510  35 2e 30 2d 31 31 39 2d  67 65 6e 65 72 69 63 20  |5.0-119-generic |00001520  23 31 32 39 7e 32 30 2e  30 34 2e 31 2d 55 62 75  |#129~20.04.1-Ubu|00001530  6e 74 75 20 53 4d 50 20  57 65 64 20 41 75 67 20  |ntu SMP Wed Aug |00001540  37 20 31 33 3a 30 37 3a  31 33 20 55 54 43 20 32  |7 13:07:13 UTC 2|00001550  30 32 34 20 78 38 36 5f  36 34 0a 63 72 65 61 74  |024 x86_64.creat|00001560  69 6f 6e 5f 74 69 6d 65  20 3d 20 31 37 32 36 30  |ion_time = 17260|00001570  32 32 33 34 38 09 23 20  57 65 64 20 53 65 70 20  |22348.# Wed Sep |00001580  31 31 20 31 30 3a 33 39  3a 30 38 20 32 30 32 34  |11 10:39:08 2024|00001590  0a 0a 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|000015a0  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|*00002000  ff ff ff ff ff ff ff ff  ff ff ff ff ff ff ff ff  |................|*08000000 | 
创建vg后,pv上的磁盘空间会分成4MB的extents。当然也可以使用-s选项,指定extent大小。
使用 --alloc 可以指定extent在不同PV上的分配策略。
使用vgextend命令,可以添加一个新的pv到vg
# vgextend vg1 /dev/loop24
Volume group "vg1" successfully extended
和现实pv类似,有3个命令:vgs,vgdisplay,vgscan。
vgs适合脚本。vgdisplay是多行显示。
vgscan会扫描所有的磁盘,然后更新LVM cache file:/etc/lvm/.cache。
系统启动的时候,通常会自动调用vgscan,当插入新的磁盘后,可能需要手动调用vgscan
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  | # vgs  VG  #PV #LV #SN Attr   VSize   VFree  vg1   3   0   0 wz--n- 276.00m 276.00m# vgdisplay  --- Volume group ---  VG Name               vg1  System ID  Format                lvm2  Metadata Areas        3  Metadata Sequence No  4  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               276.00 MiB  PE Size               4.00 MiB  Total PE              69  Alloc PE / Size       0 / 0  Free  PE / Size       69 / 276.00 MiB  VG UUID               jbSFIp-UJpT-OxEw-jgdB-1dVK-skAj-rlyMr2# vgscan  Found volume group "vg1" using metadata type lvm2 | 
使用vgreduce命令,可以移除一个pv。
# vgreduce vg1 /dev/loop24
Removed "/dev/loop24" from volume group "vg1"
使用vgchange命令,改变vg的属性。
比如限制lv的个数为128
# vgchange -l 128 vg1
Volume group "vg1" successfully changed
deactive一个vg
# vgchange -a n vg1
0 logical volume(s) in volume group "vg1" now active
移除一个不包含logical volumes的vg,使用vgremove命令。
# vgremove vg1
Volume group "vg1" successfully removed
使用hexdump查看磁盘内容,之前的vg操作记录还在。应该LVM会循环写入vg操作记录。
使用vgsplit命令,将pv从它的旧vg中,已到一个新vg,要求是这个PV上,没有任何LV的内容。
# vgsplit vg1 vg2 /dev/loop24
New volume group "vg2" successfully split from "vg1"
使用vgmerge命令,合并vg。
# vgmerge vg1 vg2
Volume group "vg2" successfully merged into "vg1"
使用vgrename命令,重命名一个vg
# vgrename vg1 vg2
Volume group "vg1" successfully renamed to "vg2"
想要把一个vg从当前系统,移到另外一个系统,需要:
1 umount所有LVs
2 使用vgchange -a n,设置vg为inactive状态
3 使用vgexport导出vg。这将阻止对vg的继续访问
4 将磁盘拔下插入到新电脑
5 使用vgimport命令导入
6 使用vgchange -a y激活vg
7 mount文件系统