Linux存储之LVM技术

本文主要介绍Linux存储技术中的LVM的概念和操作方法。

1. 概述

LVM全称是Logical Volume Manager,即逻辑卷管理器。它是Linux环境下对磁盘分区进行管理的一种机制;它可以将多个物理分区整合在一起,并且可以根据实际需要动态调整文件系统空间。

2. LVM的相关概念

(1) 物理卷(Physical Volume)

物理卷是组成LVM的最底层的元素,即Linux上的物理分区。

(2) 卷组(Volume Group)

将各个独立的PV组合起来形成的一个存储空间就称为VG,VG的大小就是整个LVM的大小。

(3) 逻辑卷(Logical Volume)

可以被用户格式化、挂载并提供数据存储的对象就是LV。

(4) 物理扩展块(Physical Extent)

PE相当于Linux分区中的block,它是LVM的最小存储单位,默认为4M。

做成lvm的优势:

可以灵活变动大小

可以自定义设备名(物理卷也可以改名,使用udev)

可以做线型(linear),条带(stripe),镜像(mirror)

可以做lvm快照

3. LVM基本操作

  • 创建PV
1
2
3
4
5
6
7
8
9
10
11
12
13
# pvcreate /dev/md0 
Physical volume "/dev/md0" successfully created
# pvcreate /dev/md1
Physical volume "/dev/md1" successfully created
# pvcreate /dev/md10
Physical volume "/dev/md10" successfully created

查看相关信息的命令 pvscan pvdisplay pvs
删除pv的命令 pvremove /dev/md10

# pv
pvchange pvcreate pvmove pvresize pvscan
pvck pvdisplay pvremove pvs pv.sh
  • 划分vg
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
# vgcreate vg01 /dev/md10
Volume group "vg01" successfully created
# vgextend vg01 /dev/md0
Volume group "vg01" successfully extended
# vgextend vg01 /dev/md1
Volume group "vg01" successfully extended

补充:vgcreate -s 指定PE的大小
查看相关信息的命令vgscan vgdisplay vgs

# vgs
VG #PV #LV #SN Attr VSize VFree
vg01 3 0 0 wz--n- 4.99G 4.99G

# vgreduce vg01 /dev/md0
Removed "/dev/md0" from volume group "vg01"

vgreduce跟vgextend是相反的,是在vg里移除pv
移除vg的命令是vgremove,它是和vgcreate相反
  • 把vg划分为逻辑卷(线性卷linear)
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
# lvcreate -L 1000M -n lv01 vg01	--L指定大小,n指定lv的名字
Logical volume "lv01" created

# lvcreate -l 250 -n lv02 vg01 --l指定PE的个数,n指定lv的名字
Logical volume "lv02" created

# lvcreate -L 1001M -n lv03 vg01 --指定为1001M,它会自动做成1004M,要是PE的倍数
Rounding up size to full physical extent 1004.00 MB
Logical volume "lv03" created

# ls /dev/vg01/ -l
lrwxrwxrwx 1 root root 21 May 7 14:14 lv01 -> /dev/mapper/vg01-lv01
lrwxrwxrwx 1 root root 21 May 7 14:15 lv02 -> /dev/mapper/vg01-lv02

# ls /dev/mapper/ -l
brw-rw---- 1 root disk 253, 0 May 7 14:14 vg01-lv01
brw-rw---- 1 root disk 253, 1 May 7 14:15 vg01-lv02

# mkfs.ext4 /dev/vg01/lv01
# mkfs.ext4 /dev/vg01/lv02

# mount /dev/vg01/lv01 /mnt/
# mount /dev/vg01/lv02 /media/

# df -h | tail -4
/dev/mapper/vg01-lv01
985M 18M 918M 2% /mnt
/dev/mapper/vg01-lv02
985M 18M 918M 2% /media

# echo '12345' > /mnt/1
# echo '678910' > /media/2

查看的相关参数为lvscan lvdisplay

# lvscan
ACTIVE '/dev/vg01/lv01' [1000.00 MB] inherit
ACTIVE '/dev/vg01/lv02' [1000.00 MB] inherit

移除lv使用lvremove
完全删除lvm,就要先lvremove,再vgremove,最后pvremove

# vgs
VG #PV #LV #SN Attr VSize VFree
vg01 3 2 0 wz--n- 4.99G 3.04G

# lvcreate -l 50%VG -n lv03 vg01 --创建lv03,大小为vg01的一半
# lvcreate -l 100%FREE -n lv04 vg01 --把剩下的所有空间都分配给新创建的lv04

# lvs --使用lvs验证
LV VG Attr LSize Origin Snap% Move Log Copy% Convert
lv01 vg01 -wi-ao 1000.00M
lv02 vg01 -wi-ao 1000.00M
lv03 vg01 -wi-a- 2.49G
lv04 vg01 -wi-a- 556.00M

使用lvremove把上面的四个卷给移除,再来创建条状卷
# lvremove vg01 --移除四个卷
Do you really want to remove active logical volume lv01? [y/n]: y
Logical volume "lv01" successfully removed
Do you really want to remove active logical volume lv02? [y/n]: y
Logical volume "lv02" successfully removed
Do you really want to remove active logical volume lv03? [y/n]: y
Logical volume "lv03" successfully removed
Do you really want to remove active logical volume lv04? [y/n]: y
Logical volume "lv04" successfully removed
Volume group "lv01" not found

当您创建条状逻辑卷时,请使用 lvcreate 命令的 -i 参数指定条带的数目。这取决于逻辑卷要进行条带
化的物理卷数目。条带的数目不能超过卷组中物理卷的数目(除非使用 --alloc anywhere 参数)

如果构成逻辑卷的基本物理设备的大小不同,条状卷的最大容量由最小的基本设备决定。例如,在有两
个分支条状卷中,其容量最大为较小设备的两倍。在有三个分支的条状卷中,其容量是最小设备的三倍

条带卷的大小由最小的PV和创建命令的-i参数(条带数)来决定
以这个为例
PV VG Fmt Attr PSize PFree
/dev/md0 vg01 lvm2 a-- 2.00g 2.00g
/dev/md1 vg01 lvm2 a-- 1020.00m 1020.00m
/dev/md10 vg01 lvm2 a-- 2.00g 2.00g
因为有三个PV,所以用-i 3实现三个条带;那么最大大小为1020*3=3060M
  • 创建条带卷
1
2
3
4
# lvcreate -L 3060M -i3  -n stripe_lv_01 vg01
Logical volume "stripe_lv_01" created

可以对其格式化,再用dd和iostat来做测试(但测试的结果比较复杂,因为我是几种不同的raid做的条带卷)
  • 镜像卷

当您创建一个镜像卷时,您可使用 lvcreate 命令的 -m 参数来指定数据的备份数目。指定 -m1 生成一个镜像,也就是生成两个文件系统副本:一个线性逻辑卷加上一个副本。同样的,指定 -m2 会生成两个镜像,也就是生成三个文件系统副本。

镜像卷的大小由最小的PV和副本数(也就是-m后接的数字)来决定

以这个为例

PV VG Fmt Attr PSize PFree

/dev/md0 vg01 lvm2 a– 2.00g 2.00g

/dev/md1 vg01 lvm2 a– 1020.00m 1020.00m

/dev/md10 vg01 lvm2 a– 2.00g 2.00g

如果-m 1,那么他会选md0和md10这两个来做镜像,所以最大大小为2G

如果-m 2,那么他会选这三个一起来做,最大大小为1020M

不能-m 3或者更大;因为我这里只有三个PV

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
以下面的为例
# pvs
PV VG Fmt Attr PSize PFree
/dev/sdb13 vg01 lvm2 a- 964.00M 964.00M
/dev/sdb14 vg01 lvm2 a- 964.00M 964.00M
/dev/sdb15 vg01 lvm2 a- 964.00M 964.00M

# vgs
VG #PV #LV #SN Attr VSize VFree
vg01 3 0 0 wz--n- 2.82G 2.82G

再次创建镜像卷,成功创建
# lvcreate -n lv_mirror -L 300M -m 1 vg01
Logical volume "lv_mirror" created

# ls /dev/mapper/
control vg01-lv_mirror_mimage_0 vg01-lv_mirror_mlog
vg01-lv_mirror vg01-lv_mirror_mimage_1

格式化这个镜像卷,并挂载
# mkfs.ext3 /dev/mapper/vg01-lv_mirror
# mount /dev/mapper/vg01-lv_mirror /media/

# df -h
/dev/mapper/vg01-lv_mirror
291M 11M 266M 4% /media

测试镜像卷可用性
# echo 123 > /media/123
# cat /media/123
123
破坏其中一个物理卷。
# dd if=/dev/zero of=/dev/sdb13
或者
# mkfs.ext3 /dev/sdb13

pvs 检测出有物理卷被损坏,找不到uuid

但数据仍然可以正常访问
# cat /media/123
123

可以对其格式化,再用dd和iostat来做测试(但测试的结果比较复杂,因为我是几种不同的raid做的条带卷)
  • 关于三种卷之间的转换:
1
2
3
4
5
6
7
8
把线性卷转化成镜像卷
# lvconvert -m 1 vg01/lv_linear --速度较慢
把镜像卷转化成线性卷
# lvconvert -m 0 vg01/lv_mirror --速度较快

实现总结:
(1) 如果物理做了raid10,那么就可以不做条带和镜像卷了,只有线性卷就可以了
(2) 如果物理没做raid,那么你希望提高IO性能或高可用,则可以使用条带或镜像卷

4. LVM扩容

先考虑vg是否还有空间去扩容,如果没有,那么要先扩容vg,使用vgextend

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
# lvextend -L 1.5g /dev/vg01/lv01 
Extending logical volume lv01 to 1.50 GB
Logical volume lv01 successfully resized


下面两种写法也可以
# lvextend -L +500M /dev/vg01/lv01
# lvextend -l +125 /dev/vg01/lv01

# df -h
/dev/mapper/vg01-lv01
985M 18M 918M 2% /mnt 查看已经挂载的大小,没有变化

# resize2fs /dev/vg01/lv01 再使用这个命令去在线同步
resize2fs 1.39 (29-May-2006)
Filesystem at /dev/vg01/lv01 is mounted on /mnt; on-line resizing required
Performing an on-line resize of /dev/vg01/lv01 to 393216 (4k) blocks.
The filesystem on /dev/vg01/lv01 is now 393216 blocks long.

# df -h
/dev/mapper/vg01-lv01
1.5G 18M 1.4G 2% /mnt 再次查看,已经挂载的lv扩大了,并且数据没有影响

5. LVM缩小

做缩小操作之前,都要去验证查看一下数据的大小,缩小时不要缩到比已经存在的数据量还要小(数据库内的表空间缩小也是一样要先查看已有数据大小)

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
# resize2fs /dev/vg01/lv01 1g	--这样去缩小的话,报错已经mount了
resize2fs 1.39 (29-May-2006)
Filesystem at /dev/vg01/lv01 is mounted on /mnt; on-line resizing required
On-line shrinking from 393216 to 262144 not supported.

# umount /mnt/

# resize2fs /dev/vg01/lv01 1g --umount后再使用resize2fs命令,要求先去e2fsck检测
resize2fs 1.39 (29-May-2006)
Please run 'e2fsck -f /dev/vg01/lv01' first.

# e2fsck -f /dev/vg01/lv01
e2fsck 1.39 (29-May-2006)
Pass 1: Checking inodes, blocks, and sizes
Pass 2: Checking directory structure
Pass 3: Checking directory connectivity
Pass 4: Checking reference counts
Pass 5: Checking group summary information
/dev/vg01/lv01: 12/192000 files (8.3% non-contiguous), 10517/393216 blocks

# resize2fs /dev/vg01/lv01 1g 检测后再使用resize2fs命令缩小,并挂载查看大小是否缩小
resize2fs 1.39 (29-May-2006)
Resizing the filesystem on /dev/vg01/lv01 to 262144 (4k) blocks.
The filesystem on /dev/vg01/lv01 is now 262144 blocks long.

# lvscan
ACTIVE '/dev/vg01/lv01' [1.50 GB] inherit 但这里查看的还是1.5g
ACTIVE '/dev/vg01/lv02' [1000.00 MB] inherit

# lvreduce -L 1g /dev/vg01/lv01 所以lvreduce也要做
WARNING: Reducing active logical volume to 1.00 GB
THIS MAY DESTROY YOUR DATA (filesystem etc.)
Do you really want to reduce lv01? [y/n]: y
Reducing logical volume lv01 to 1.00 GB
Logical volume lv01 successfully resized

# lvscan
ACTIVE '/dev/vg01/lv01' [1.00 GB] inherit --OK
ACTIVE '/dev/vg01/lv02' [1000.00 MB] inherit

# mount /dev/vg01/lv01 /mnt/
# df -h
/dev/mapper/vg01-lv02
985M 18M 918M 2% /media 缩小了

6. lvm 快照功能

(1) 快照创建的速度非常快,不需要停止生产环境

(2) 快照的大小是存储差异数据,或是快照时间点的状态,不需要和lv同大小

(3) 它可以用于一些特殊的情况,比如数据库备份,或者批量复制虚拟机(不关闭虚拟机的情况下,克隆是需要关闭或暂停虚拟机的),虚拟机做快照等

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
# dd if=/dev/zero of=/media/10m bs=1M count=10

# dd if=/dev/zero of=/media/20m bs=1M count=20

# dd if=/dev/zero of=/media/30m bs=1M count=30

# ls /media/ -l
total 61532
-rw-r--r-- 1 root root 10485760 May 7 15:18 10m
-rw-r--r-- 1 root root 20971520 May 7 15:18 20m
-rw-r--r-- 1 root root 31457280 May 7 15:18 30m
drwx------ 2 root root 16384 May 7 14:17 lost+found

# lvcreate -s -L 100m -n snap01 /dev/vg01/lv02 --L参数指定的大小不是快照大小,它类似于一个快照存活的时间(由源的改变来定义存活时间的长短。源增加多少,这个100M‘时间‘就会被使用多少,源删除,这个100M时间只会被增加一点点,因为删除只记录它的一个innode失效。但注意,快照的内容不会跟着改变。
Logical volume "snap01" created

# ls /dev/vg01/snap01
/dev/vg01/snap01

# mkdir /snap
# mount /dev/vg01/snap01 /snap/

# ls /snap/ --快照的内容
10m 20m 30m lost+found

# dd if=/dev/zero of=/media/50m bs=1M count=50
--在源目录加一个50M的文件

# ls /snap/ --快照的内容不会跟着变
10m 20m 30m lost+found

# lvs
LV VG Attr LSize Origin Snap% Move Log Copy% Convert
lv01 vg01 -wi-ao 1.00G
lv02 vg01 owi-ao 1000.00M
snap01 vg01 swi-ao 100.00M lv02 50.48 --但是这个snap%会发现由几乎为0变化到50%

下面再可以继续做试验:
1,在源删除一个文件,再使用lvs查看 %snap只会增加一点点
2,当%snap用完了100%,则快照失效。umount和mount快照都会出问题
3, 快照的内容不会跟着源改变

# lvremove /dev/vg01/snap01 --快照的移除
Do you really want to remove active logical volume snap01? [y/n]: y
Logical volume "snap01" successfully removed
---------------- The End ----------------