创建并使用lvm逻辑卷

安装lvm2软件包

1
$ yum install -y lvm2

创建物理卷PV

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# 查看所有可用磁盘
$ lsblk
NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT
vda 253:0 0 40G 0 disk
└─vda1 253:1 0 40G 0 part /
vdb 253:16 0 40G 0 disk
vdc 253:32 0 40G 0 disk
vdd 253:48 0 40G 0 disk

# 创建pv
$ pvcreate /dev/vdb /dev/vdc /dev/vdd

# 查看pv信息
$ pvdisplay
$ pvscan
$ pvs
$ lvmdiskscan

创建卷组VG

如果您需要添加多块物理卷,则可以添加多个物理卷名称,名称之间以空格间隔。卷组名由您自定义名称,假设为lvm_01。

1
2
3
4
5
6
7
# 创建vg
$ vgcreate lvm_01 /dev/vdb /dev/vdc /dev/vdd

# 查看vg信息
$ vgdisplay
$ vgscan
$ vgs

如果需要向现有卷组中添加物理卷,我们可以使用下面命令

1
$ vgextend lvm_01 /dev/vde

创建逻辑卷

1
2
3
4
5
6
7
# 创建一个60G的lvm
$ lvcreate -L 60G -n lv01 lvm_01

# 查看lv信息
$ lvdisplay
$ lvscan
$ lvs

如果创建条带化的逻辑卷用下面命令

  • 下面用到的lvextend的参数如下:
  • -i:此处写lv用到的pv的数量,不能超过所在vg的pv数量,一般设置与vg的pv个数相同
  • -I(大写i):条带单元大小,单位Kb
  • -L:lv的大小,默认为Mb,可带单位G,M,K
  • -l:小写L,分配给lv的LE个数,对应于VG中的PE,在上条vgdisplay的输出中可看到VG中一共有1533个PE。
  • -n:自定义lv的名字,默认从lvol0开始往下排。
1
[root@iZ8vbctex08c13fqf5ybyiZ /]# lvcreate -i 3 -I 64 -L 85G lvm_01

主机挂载lv逻辑卷

手动挂载lvm逻辑卷到/data目录下

1
2
3
$ mkdir  /data/
$ mkfs.ext4 /dev/mapper/lvm_01-lv01
$ mout /dev/mapper/lvm_01-lv01 /data/

配置lvm开机自动挂载

1
2
3
4
5
6
7
8
# 获取lv-01的UUID
$ blkid |grep lv01
/dev/mapper/lvm_01-lv01: UUID="e5919dc2-9afa-4f7f-aa3f-2976184dcba2" TYPE="ext4"

$ vim /etc/fstab
UUID=e5919dc2-9afa-4f7f-aa3f-2976184dcba2 /data ext4 defaults 0 0

$ mount -a

扩容lvm

注意:xfs_growf为扩容xfs挂载文件系统类型的卷,resize2fs为扩容ext4挂载文件系统类型的卷。

vg空间可用下扩容lv

将lv在原有大小上扩容10GB存储空间

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
# 查看原有lv大小
[root@iZ8vbctex08c13fqf5ybyiZ html]# lvscan
ACTIVE '/dev/lvm_01/lv01' [60.00 GiB] inherit

# 将lv扩容10GB
[root@iZ8vbctex08c13fqf5ybyiZ html]# lvextend -L +10GB /dev/lvm_01/lv01
# lvextend -l +100%FREE /dev/lvm_01/lv01 扩容100%

# 查看扩容后lv大小
[root@iZ8vbctex08c13fqf5ybyiZ html]# lvscan
ACTIVE '/dev/lvm_01/lv01' [70.00 GiB] inherit

# 查看挂载点文件系统大小
[root@iZ8vbctex08c13fqf5ybyiZ html]# df -h /data/
文件系统 容量 已用 可用 已用% 挂载点
/dev/mapper/lvm_01-lv01 59G 191M 56G 1% /data


# 刷新lv文件系统挂载大小
## 先查看要扩容的文件系统是ext4还是xfs
[root@jenkins ~]# df -hT
文件系统 类型 容量 已用 可用 已用% 挂载点
/dev/mapper/centos-root xfs 36G 3.2G 32G 10% /
/dev/lvm_01/lv01 ext4 296G 2.3G 280G 1% /data
## ext4使用下面命令
[root@iZ8vbctex08c13fqf5ybyiZ html]# resize2fs /dev/lvm_01/lv01
## xfs使用下面命令
[root@iZ8vbctex08c13fqf5ybyiZ html]# xfs_growfs /dev/lvm_01/lv01

# 重新查看挂载点文件系统大小
[root@iZ8vbctex08c13fqf5ybyiZ html]# df -h /data/
文件系统 容量 已用 可用 已用% 挂载点
/dev/mapper/lvm_01-lv01 69G 191M 66G 1% /data

vg可用pv空间不足,扩容pv后扩容lv

0、虚拟机磁盘新添加或者扩容后,lsblk显示磁盘容量没变化就重新扫描 scsi 总线

1
2
3
4
5
# 手动一个个扫描磁盘
echo 1 > /sys/class/scsi_device/0\:0\:0\:0/device/rescan

# 可以使用下面脚本一键扫描全部磁盘
for i in `ls /sys/class/scsi_device`;do echo 1 > /sys/class/scsi_device/$i/device/rescan;done

1、新增磁盘并创建为pv后加入到vg组中进行扩容lv

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# 查看所有可用磁盘
$ lsblk
NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT
vda 253:0 0 40G 0 disk
└─vda1 253:1 0 40G 0 part /
vdb 253:16 0 40G 0 disk
vdc 253:32 0 40G 0 disk
vdd 253:48 0 40G 0 disk
vde 253:64 0 40G 0 disk

# 将新磁盘vde创建pv
$ pvcreate /dev/vde

# 将vde的pv加入到lvm_01的vg组
$ vgextend lvm_01 /dev/vde

#后面扩容lv的步骤后前面的vg空间可用下扩容lv步骤一致

2、直接扩容原来pv对应磁盘的大小后,重新刷新pv容量后扩容lv

直接扩容磁盘后刷新pv磁盘的容量pvresize(在线存储级直接增加磁盘大小然后pvresize刷新)

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
# 1、查看原磁盘大小,这里磁盘和分区挂载都是500G
$ lsblk
sdb 8:16 0 500G 0 disk
└─data-data_01 253:1 0 500G 0 lvm /data

# 2、修改虚拟机sdb对应磁盘的大小至510GB

# 3、重新识别磁盘大小
$ partprobe

# 4、重新查看磁盘大小,这里磁盘是510GB,分区是500G
$ lsblk
sdb 8:16 0 510G 0 disk
└─data-data_01 253:1 0 500G 0 lvm /data

# 查看sdb的pv大小
$ pvs
/dev/sdb data lvm2 a-- <500.00g 0

# 重新刷新sdb的pv大小
$ pvresize /dev/sdb
$ pvs
/dev/sdb data lvm2 a-- <510.00g 10.00g # 这里pv已经是510g了

# 查看vg大小,可以看到vg可用空间为10GB刚刚扩容的了。
$ vgs
data 1 1 0 wz--n- <510.00g 10.00g
#后面扩容lv的步骤按照前面的vg空间可用下扩容lv步骤一致操作。

注意:以上扩容步骤是根据做pv的时候不给磁盘划分partation ,直接用整个磁盘创建PV。然后一个lv挂载到单独的目录下,现在需要给这个目录扩容,恰巧这个lv所在的vg是由一个单独磁盘做的PV组成的。

上面这种整个磁盘不分区直接创建pv,有的工程师没看明白就直接fdisk了这个磁盘尝试创建partation,然后整个的pv vg lv信息都看不到了,下面根据这种误操作行为进行数据恢复

下面先查看磁盘信息,然后模拟在整个磁盘被pv后又为磁盘创建分区导致lvm卷信息丢失的恢复问题。

1
2
3
$ lsblk
sdc 8:32 0 15G 0 disk
└─lvm_test-lvm_test 253:2 0 9G 0 lvm /test

磁盘被重新创建分区后查看磁盘信息

1
2
3
4
5
$ lsblk
NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT
sdc 8:32 0 15G 0 disk
├─sdc1 8:33 0 15G 0 part #这个是创建的分区
└─lvm_test-lvm_test 253:2 0 9G 0 lvm /test

上面这段操作就是我在sdc上创建了一个LVM格式的partation,成功的把原来的PVvgLV信息搞没了,现在就需要来研究一下怎么恢复回来。

首先,需要抽根烟冷静一下。

要确认上面的操作其实只是修改了磁盘上的磁盘头文件,真正的数据目前看还是都可以正常访问的,所以最重要的首先是要进行数据备份。

备份完成以后,先把刚才创建的partation删掉

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
$ fdisk /dev/sdc
欢迎使用 fdisk (util-linux 2.23.2)。

更改将停留在内存中,直到您决定将更改写入磁盘。
使用写入命令前请三思。

# 显示磁盘分区信息
命令(输入 m 获取帮助):p

磁盘 /dev/sdc:16.1 GB, 16106127360 字节,31457280 个扇区
Units = 扇区 of 1 * 512 = 512 bytes
扇区大小(逻辑/物理):512 字节 / 512 字节
I/O 大小(最小/最佳):512 字节 / 512 字节
磁盘标签类型:dos
磁盘标识符:0x9b43e2d3

设备 Boot Start End Blocks Id System
/dev/sdc1 2048 31457279 15727616 8e Linux LVM

# 删除被误创建的分区
命令(输入 m 获取帮助):d
已选择分区 1
分区 1 已删除

# 保存并退出
命令(输入 m 获取帮助):w
The partition table has been altered!
Calling ioctl() to re-read partition table.
正在同步磁盘。

重新查看磁盘信息

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
$ lsblk
sdc 8:32 0 15G 0 disk
└─lvm_test-lvm_test 253:2 0 9G 0 lvm /test

$ pvs
PV VG Fmt Attr PSize PFree
/dev/sda2 centos lvm2 a-- <59.00g 0
/dev/sdb data lvm2 a-- <510.00g 10.00g

$ vgs
VG #PV #LV #SN Attr VSize VFree
centos 1 1 0 wz--n- <59.00g 0
data 1 1 0 wz--n- <510.00g 10.00g

$ lvs
LV VG Attr LSize Pool Origin Data% Meta% Move Log Cpy%Sync Convert
root centos -wi-ao---- <59.00g
data_01 data -wi-ao---- <500.00g

可以看到刚创建的partation删除掉了,但是原来的pv信息还是不在。继续尝试修复lvm。

/etc/lvm/archive/etc/lvm/backup目录下其实是有每次pv、vg、lv的操作记录,通过这些记录尝试修复vg

1
2
3
$ cd /etc/lvm/archive/
$ ls
centos_00000-667784096.vg data_00000-587830447.vg data_00001-469151981.vg data_00002-1208158856.vg lvm_test_00000-279904950.vg lvm_test_00001-365045724.vg

使用 vgcfgrestore --list lvm_test查看每个操作文件中记录的步骤。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
$ vgcfgrestore --list lvm_test

File: /etc/lvm/archive/lvm_test_00000-279904950.vg
Couldn't find device with uuid tFAyZ6-KNsp-Oo0m-G7Wv-Anpx-1BJW-lOgH4H.
VG name: lvm_test
Description: Created *before* executing 'vgcreate lvm_test /dev/sdc'
Backup Time: Tue May 24 10:31:29 2022


File: /etc/lvm/archive/lvm_test_00001-365045724.vg
VG name: lvm_test
Description: Created *before* executing 'lvcreate -L 9G -n lvm_test lvm_test'
Backup Time: Tue May 24 10:34:32 2022


File: /etc/lvm/backup/lvm_test # 这里找到了
VG name: lvm_test
Description: Created *after* executing 'lvcreate -L 9G -n lvm_test lvm_test'
Backup Time: Tue May 24 10:34:32 2022

可以看到最后一次lv操作记录的日志是在/etc/lvm/backup/lvm_test文件

首先查看备份文件中pvUUID,重建PV(这步骤如果不做,操作系统每次重启一下LV都是非激活状态)

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
$ more /etc/lvm/backup/lvm_test
contents = "Text Format Volume Group"
version = 1

description = "Created *after* executing 'lvcreate -L 9G -n lvm_test lvm_test'"

creation_host = "k8s-node22" # Linux k8s-node22 3.10.0-1160.el7.x86_64 #1 SMP Mon Oct 19 16:18:59 UTC 2020 x86_64
creation_time = 1653359672 # Tue May 24 10:34:32 2022

lvm_test {
id = "efOQDc-IBIc-Yys1-mCk0-mfOa-DWoG-hBSTCE"
seqno = 2
format = "lvm2" # informational
status = ["RESIZEABLE", "READ", "WRITE"]
flags = []
extent_size = 8192 # 4 Megabytes
max_lv = 0
max_pv = 0
metadata_copies = 0

physical_volumes {

pv0 {
id = "tFAyZ6-KNsp-Oo0m-G7Wv-Anpx-1BJW-lOgH4H" # 就是这个id
device = "/dev/sdc" # Hint only

执行第一次恢复VG的命令(这次命令主要是把sdc的配置找回来)

1
2
3
4
5
6
$ vgcfgrestore -f /etc/lvm/backup/lvm_test lvm_test
Volume group lvm_test has active volume: lvm_test.
WARNING: Found 1 active volume(s) in volume group "lvm_test".
Restoring VG with active LVs, may cause mismatch with its metadata.
Do you really want to proceed with restore of volume group "lvm_test", while 1 volume(s) are active? [y/n]: y
Restored volume group lvm_test

执行重建pv命令

1
2
3
4
5
6
7
8
9
10
11
12
13
$ pvcreate -ff --uuid tFAyZ6-KNsp-Oo0m-G7Wv-Anpx-1BJW-lOgH4H --restorefile /etc/lvm/backup/lvm_test /dev/sdc
Really INITIALIZE physical volume "/dev/sdc" of volume group "lvm_test" [y/n]? y
WARNING: Forcing physical volume creation on /dev/sdc of volume group "lvm_test"
Can't open /dev/sdc exclusively. Mounted filesystem?
Can't open /dev/sdc exclusively. Mounted filesystem?

$ lvchange -an lvm_test

$ pvcreate -ff --uuid tFAyZ6-KNsp-Oo0m-G7Wv-Anpx-1BJW-lOgH4H --restorefile /etc/lvm/backup/lvm_test /dev/sdc
Really INITIALIZE physical volume "/dev/sdc" of volume group "lvm_test" [y/n]? y
WARNING: Forcing physical volume creation on /dev/sdc of volume group "lvm_test"
Wiping dos signature on /dev/sdc.
Physical volume "/dev/sdc" successfully created.

第一次执行重建pv的时候报错了,因为当时的vg在执行恢复以后是active状态,需要先给他设置成not active,然后就可以执行成功。

第二次执行VG修复命令

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
$ vgcfgrestore -f /etc/lvm/backup/lvm_test lvm_test
Restored volume group lvm_test

$ lvs
LV VG Attr LSize Pool Origin Data% Meta% Move Log Cpy%Sync Convert
root centos -wi-ao---- <59.00g
data_01 data -wi-ao---- <500.00g
lvm_test lvm_test -wi------- 9.00g

$ vgs
VG #PV #LV #SN Attr VSize VFree
centos 1 1 0 wz--n- <59.00g 0
data 1 1 0 wz--n- <510.00g 10.00g
lvm_test 1 1 0 wz--n- <10.00g 1020.00m

$ pvs
PV VG Fmt Attr PSize PFree
/dev/sda2 centos lvm2 a-- <59.00g 0
/dev/sdb data lvm2 a-- <510.00g 10.00g
/dev/sdc lvm_test lvm2 a-- <10.00g 1020.00m

$ lvchange -ay lvm_test

可以看到原来的vg信息已经恢复成功。LV激活后,后面扩容就按照上个章节的步骤扩就可以了

跨节点转移vg磁盘

ServerA上面有三块磁盘第一块是系统盘,采用的是默认lvm分区;第二块分成一个区做成lvm,第三块没有分区直接做成lvm,现在要将这两块盘,放到serverB上,但是由于现场操作原因将两块盘,没有按照原顺序插入serverB上,现在想要恢复之前的状态。

源服务器操作

在serverA源服务器上将lv取消挂载,导出vg后按顺序拔出硬盘。

源机器取消lv挂载

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
# 查看可用的lv
[root@iZ8vbcmookvg1w8qssyurfZ /]# lvscan
ACTIVE '/dev/lvm_01/lv01' [85.00 GiB] inherit

# 取消lv挂载,这里如果提示目标忙,通过lsof查看哪些服务在占用,然后关闭服务即可
[root@iZ8vbcmookvg1w8qssyurfZ /]# umount /dev/lvm_01/lv01
umount: /data:目标忙。
(有些情况下通过 lsof(8) 或 fuser(1) 可以
找到有关使用该设备的进程的有用信息)

# lsof查询哪些服务占用/data
[root@iZ8vbcmookvg1w8qssyurfZ /]# lsof |grep '/data/' |awk '{print $1}' | uniq
mysqld

# 停止mysql服务
[root@iZ8vbcmookvg1w8qssyurfZ /]# systemctl stop mysqld

# 重新取消挂载lv
[root@iZ8vbcmookvg1w8qssyurfZ /]# umount /dev/lvm_01/lv01

将源vg标记为不活动状态

1
2
[root@iZ8vbcmookvg1w8qssyurfZ /]# vgchange -an lvm_01
0 logical volume(s) in volume group "lvm_01" now active

导出源vg卷组

1
2
[root@iZ8vbcmookvg1w8qssyurfZ /]# vgexport lvm_01
Volume group "lvm_01" successfully exported

最后在源服务器按顺序拔出硬盘

目标服务器操作

在目标服务器ServerB主机上按顺序插入硬盘

查询目标服务器硬盘是否挂载

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# 物理机使用不重启刷新硬盘接口(阿里云服务器跳过) :for i in /sys/class/scsi_host/*; do echo "- - -" > $i/scan; done
[root@iZ8vbctex08c13fqf5ybyiZ /]# lsblk
NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT
vda 253:0 0 40G 0 disk
└─vda1 253:1 0 40G 0 part /
vdb 253:16 0 40G 0 disk
vdc 253:32 0 40G 0 disk
vdd 253:48 0 40G 0 disk

# 查看pv情况
[root@iZ8vbctex08c13fqf5ybyiZ /]# pvscan
PV /dev/vdb is in exported VG lvm_01 [<40.00 GiB / 0 free]
PV /dev/vdc is in exported VG lvm_01 [<40.00 GiB / 0 free]
PV /dev/vdd is in exported VG lvm_01 [<40.00 GiB / <34.99 GiB free]
Total: 3 [<119.99 GiB] / in use: 3 [<119.99 GiB] / in no VG: 0 [0 ]

导入vg卷组

1
2
[root@iZ8vbctex08c13fqf5ybyiZ /]# vgimport lvm_01
Volume group "lvm_01" successfully imported

将vg卷组标记为活动状态

1
2
[root@iZ8vbctex08c13fqf5ybyiZ /]# vgchange -ay lvm_01
1 logical volume(s) in volume group "lvm_01" now active

新主机重新挂载lv,查看数据是否存在

查看条带lv的宽度和大小

1
[root@iZ8vbctex08c13fqf5ybyiZ /]# lvs -v --segments