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/loop22 00000000 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.00m root@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-ZFLu7o root@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/loop22 00000000 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文件系统