LVM(Logical Volume Manager)逻辑卷管理

本文实验部分,完全由本人亲自动手实践得来
文章中有部分的内容是我个人通过实验测试出来的,虽以目前本人的能力还没发现不通之处,但错误难免,所以若各位朋友发现什么错误,或有疑惑、更好的建议等,盼请各位能在评论区不吝留下宝贵笔迹。最后,希望各位能读有所获。
实验环境

[Allen@Centos7 ~]$ uname -r
3.10.0-693.el7.x86_64
[Allen@Centos7 ~]$ cat /etc/redhat-release 
CentOS Linux release 7.4.1708 (Core) 

1. LVM基本概念

  • LVM:Logical Volume Manager,Version 2
  • DM(device mapper):将一个或多个底层块设备组成一个逻辑设备的模块;
  • PV(physical volume):物理卷,它在逻辑卷管理系统最底层,可为整个物理硬盘或实际物理硬盘上的分区。
  • VG(volume group):卷组,它建立在物理卷上,一卷组中至少要包括一物理卷,卷组建立后可动态的添加卷到卷组中,一个逻辑卷管理系统工程中可有多个卷组。
  • LV(logical volume):逻辑卷,它建立在卷组基础上,卷组中未分配空间可用于建立新的逻辑卷,逻辑卷建立后可以动态扩展和缩小空间。
  • PE(physical extent):物理区域,它是物理卷中可用于分配的最小存储单元,物理区域大小在建立卷组时指定,一旦确定不能更改,同一卷组所有物理卷的物理区域大小需一致,新的pv加入到vg后,pe的大小自动更改为vg中定义的pe大小。
  • LE(logical extent):逻辑区域,它是逻辑卷中可用于分配的最小存储单元,逻辑区域的大小取决于逻辑卷所在卷组中的物理区域的大小。
  • 卷组描述区域:卷组描述区域,它存在于每个物理卷中,用于描述物理卷本身、物理卷所属卷组、卷组中逻辑卷、逻辑卷中物理区域的分配等所有信息,它是在使用pvcreate建立物理卷时建立的。

**Note:当多个物理卷组合成一个卷组后时,LVM会在所有的物理卷上做类似格式化的工作,将每个物理卷切成一块一块的空间,这一块一块的空间就称为PE(Physical Extent ),它的默认大小是4MB。
LVM1中每个VG中只能有65534个PE,所以指定PE的大小能改变每个VG的最大容量。但在LVM2中已经没有该限制了,而现在说的LVM一般都指LVM2,这也是默认的版本。
Physical Extent size must be a multiple of 128.00 KiB when not a power of 2. ##物理范围的大小必须是128.00 KiB的倍数,而不是2的幂。
**

VG将每一个PV(块设备)提供的存储空间,划分成统一大小的存储块PE(Physical Extent),PE的大小是在加入到VG之后进行的划分的,每一个VG划分的PE都可能不一样。
在VG的基础上创建LV(逻辑卷),这个LV可以随意格式化。
创建LV的过程,就是分配一些PE给LV。需要增加空间时就再分配一些PE。需要减少一些空间,就拿掉一些PE。而且增加和减少PE的过程不会损坏逻辑分区中现有的数据(理论上)。

Linux自动创建分区的时候,会这样:
创建一个boot分区,剩余其他空间创建成一个PV。然后把这个PV创建成一个VG,VG创建多个LV,一个LV做根分区、一个LV做SWAP分区、一个LV做USR。等等

缺点:
这种方式十分的灵活,非常的方便。但是唯一的缺点就是较为不安全,如果误删除数据了,不好恢复数据。
LV的缩减比较危险。如果某个PV存放了数据。就不能直接挪走了,需要现将PE挪走。

2. pv相关命令

pvcreate       ##创建物理卷
    一次可以创建n个物理卷
    -u              ##手动指定UUID
    -v              ##显示过程
    -f               ##强制创建(如果里面有数据,则强制覆盖,不管提示)

pvdisplay	     ##显示详细pv信息

pvmove	     ##将物理卷上的数据(PE)移动到其他物理卷上去。
pvremove     ##移除物理卷
pvck		     ##检测
pvs	             ##显示简要pv信息

3. vg相关命令

OPTIONS

vgdisplay      ##显示详细vg信息
vgs		     ##显示简要vg信息
vgcreate       ##创建卷组
    vgcreate [OPTION] vgname pvname
    -s	             ##指定PE大小,单位可以使bBsSkKmMgG....(不指定PE的话,默认为4.00 MiB),创建了vg之后,他的PE,大小就固定了,只能删除再重新创建时更改
vgmove	     ##移动		##参考实例2
vgremove     ##移除		##参考实例2
vgextend      ##扩展		##参考实例1
vgeduce	     ##缩减
vgsplit	     ##切割
vgchange     ##修改vg属性
    -a             ##设置vg的状态active还是inactive		##参考实例3

EXAMPLE

实例1
##为这个vg添加pv
[Allen@Centos7 ~]$ sudo vgextend myvg /dev/sda15
  Volume group "myvg" successfully extended

实例2
##为这个vg移除pv,移除之前需要先进行move(将有数据的PE移动到其他PV中)
[Allen@Centos7 ~]$ sudo pvmove /dev/sda15
  No data to move for myvg
[Allen@Centos7 ~]$ sudo vgreduce myvg /dev/sda15
Removed "/dev/sda15" from volume group "myvg"

实例3
将firstvg设置为活动状态(active yes)。
shell> vgchange -a y firstvg

将firstvg设置为非激活状态(active no)。
shell> vgchange -a n firstvg

4. lv相关命令

OPTIONS

lvs		     ##显示简要lv信息
lvdisplay	     ##显示详细lv信息
lvcreate        ##创建逻辑卷
    -L, --size		##指定逻辑卷大小[mG]		##参考实例1
    -n				##lv的名字				##参考实例1
    -l | --extents [+]Number[PERCENT]		##分配的逻辑盘区的数量,也可以指定占据某个vg的百分比,
-VolumeGroup	        ##指定在哪个卷组中创建
-s,--snapshot	##快照卷
-p,--permission [r|rw]		##设置访问权限
  

lvreduce
    lvreduce -L [-]#[mMgGtT] /dev/VG_NAME/LV_NAME	##不加减号就是缩小到多少。

lvremove    ##移除逻辑卷
lvresize	  ##改变大小
lvconf	  ##修改lv的配置文件

lvextend    ##扩展逻辑卷
    -L [+]#[mMgGtT] /dev/VG_NAME/LV_NAME		##参考实例2
        指定加号,表示增加多少。
        不指定加号,表示希望这个LV能有到多大空间,如果不足就自动加上到满足
    -l	[+][number]		增加指定数量的PE或让PE达到指定数量

lvconvert    ##Change logical volume layout			##参考实例3
	--merge		合并快照

EXAMPLE

实例1
在myvg这个卷组山创建LV,指定空间为1.99G,名称为mylv。
[root@Centos7 ~]# lvcreate -L 1.99G -n mylv myvg
  Rounding up size to full physical extent 1.99 GiB
  Logical volume "mylv" created.

实例2
[root@Centos7 lvm]# lvextend -L 2.5G /dev/myvg/mylv		##将mylv扩张到2.5G 
  Size of logical volume myvg/mylv changed from 1.99 GiB (510 extents) to 2.50 GiB (640 extents).
  Logical volume myvg/mylv successfully resized.
[root@Centos7 ~]# lvextend -l +10 /dev/mapper/testvg-testlv		##通过增加指定数量的PE来实现
  Size of logical volume testvg/testlv changed from 2.00 GiB (128 extents) to <2.16 GiB (138 extents).
  Logical volume testvg/testlv successfully resized.

实例3
lvconvert --merge /dev/mapper/myvg-mylv-snap

5. resize2fs命令:调整ext文件系统大小

NAME

resize2fs - ext2/ext3/ext4 file system resizer

SYNOPSIS

resize2fs [ -fFpPM ] [ -d debug-flags ] [ -S RAID-stride ] device [ size ]

EXAMPLE

实例1
[root@Centos7 lvm]# lvextend -L 2.5G /dev/myvg/mylv 
  Size of logical volume myvg/mylv changed from 1.99 GiB (510 extents) to 2.50 GiB (640 extents).
  Logical volume myvg/mylv successfully resized.
[root@Centos7 lvm]# df -lh  | grep /dev/mapper/myvg-mylv 
/dev/mapper/myvg-mylv    2.0G  3.1M  1.9G   1% /mnt/lvm
为什么空间还是2G,这是因为原来的LV是2G大小,文件系统也就是2G大小,现在LV扩大了,但是文件系统还是没有扩大,这时候需要将新增部分指定文件系统
xfs文件系统,则使用xfs_growfs
不指定大小就是将文件系统填充所有PV
[root@Centos7 lvm]# resize2fs /dev/mapper/myvg-mylv
resize2fs 1.42.9 (28-Dec-2013)
Filesystem at /dev/mapper/myvg-mylv is mounted on /mnt/lvm; on-line resizing required
old_desc_blocks = 16, new_desc_blocks = 20
The filesystem on /dev/mapper/myvg-mylv is now 2621440 blocks long.

6. LVM实验

6.1 创建lv逻辑卷

1、前提:使用fdisk创建分区,将创建分区,并将分区类型配置成8e

2、将sda14创建为pv
物理卷(Physical Volumes)简称PV,是在磁盘的物理分区或与磁盘分区具有同样功能的设备(如RAID)上创建而来。它只是在物理分区中划出了一个特殊的区域,用于记载与LVM相关的管理参数。
[Allen@Centos7 ~]$ sudo pvcreate /dev/sda14
  Physical volume "/dev/sda14" successfully created.

3、创建名字叫myvg的卷组,将sda14(需要提前创建成pv)加入到myvg
卷组(Volume Group)简称VG,它是一个或者多个物理卷的组合。卷组将多个物理卷组合在一起,形成一个可管理的单元,它类似于非LVM系统中的物理硬盘。
[Allen@Centos7 ~]$ sudo vgcreate myvg /dev/sda14 
  Volume group "myvg" successfully created
为这个vg添加pv
[root@Centos7 ~]# pvcreate /dev/sda15
  Physical volume "/dev/sda15" successfully created.
[Allen@Centos7 ~]$ sudo vgextend myvg /dev/sda15
  Volume group "myvg" successfully extended

4、在myvg这个卷组上创建LV,指定空间为1.99G,名称为mylv。
逻辑卷(Logical Volumes)简称LV,是在卷组中划分的一个逻辑区域,类似于非LVM系统中的硬盘分区。
[root@Centos7 ~]# lvcreate -L 1.99G -n mylv myvg
  Rounding up size to full physical extent 1.99 GiB
  Logical volume "mylv" created.

5、将这个分区格式化为ext4
[root@Centos7 ~]# mkfs.ext4 -b 1024 -l MYLV /dev/myvg/mylv

6、执行挂载
[root@Centos7 ~]# mkdir /mnt/lvm
[root@Centos7 ~]# mount /dev/myvg/mylv /mnt/lvm/

##可以看出来,不管在挂在的时候使用的是什么路径,显示的时候,都是/dev/mapper/xxxx
[root@Centos7 ~]# blkid | grep MYLV
/dev/mapper/myvg-mylv: LABEL="MYLV" UUID="7fc94efc-098c-40ff-aef8-44efc5e189a4" TYPE="ext4"
[root@Centos7 ~]# mount | grep mnt/lvm
/dev/mapper/myvg-mylv on /mnt/lvm type ext4 (rw,relatime,seclabel,stripe=4,data=ordered)



Note:推荐第一种方式
创建好LV之后,有两种路径名称都可以访问到这个LV。分别是以下两种格式
/dev/mapper/VG_NAME-LV_NAME
[root@Centos7 ~]# ls -l /dev/mapper/myvg-mylv 
lrwxrwxrwx. 1 root root 7 Aug 27 17:01 /dev/mapper/myvg-mylv -> ../dm-2

/dev/VG_NAME/LV_NAME
[root@Centos7 ~]# ls -l /dev/myvg/mylv 
lrwxrwxrwx. 1 root root 7 Aug 27 17:01 /dev/myvg/mylv -> ../dm-2

6.2 扩展逻辑卷

当卷组中没有足够的空间用于扩展逻辑卷的大小时,就需要增加卷组的容量,而增加卷组容量的惟一办法就是向卷组中添加新的物理卷。
首先是增加一块新硬盘,并对其完成分区、创建物理卷等工作。接下来是利用vgextend命令将新的物理卷(/dev/sda16)加入到卷组中。
完成卷组的扩容后,使用lvextend命令增加空间给lv,实现分区的动态调整。
[root@Centos7 lvm]# lvextend -L 2.5G /dev/myvg/mylv 
  Size of logical volume myvg/mylv changed from 1.99 GiB (510 extents) to 2.50 GiB (640 extents).
  Logical volume myvg/mylv successfully resized.

此步骤不算在扩展逻辑卷中,只作为实例
[root@Centos7 ~]# lvextend -l +10 /dev/mapper/testvg-testlv		##也可以通过增加指定数量的PE来实现(需要加多找个PE,需要自己算)  
Size of logical volume testvg/testlv changed from 2.00 GiB (128 extents) to <2.16 GiB (138 extents).
  Logical volume testvg/testlv successfully resized.

[root@Centos7 lvm]# df -lh  | grep /dev/mapper/myvg-mylv 
/dev/mapper/myvg-mylv    2.0G  3.1M  1.9G   1% /mnt/lvm
为什么空间还是2G,这是因为原来的LV是2G大小,文件系统也就是2G大小,现在LV扩大了,但是文件系统还是没有扩大,这时候需要将新增部分指定文件系统

##不指定大小就是将文件系统填充所有PV
[root@Centos7 lvm]# resize2fs /dev/mapper/myvg-mylv
resize2fs 1.42.9 (28-Dec-2013)
Filesystem at /dev/mapper/myvg-mylv is mounted on /mnt/lvm; on-line resizing required
old_desc_blocks = 16, new_desc_blocks = 20
The filesystem on /dev/mapper/myvg-mylv is now 2621440 blocks long.

6.3 缩减逻辑卷(危险,不建议)

xfs文件系统,则使用xfs_growfs

  • umount /dev/VG_NAME/LV_NAME
  • e2fsck -f /dev/VG_NAME/LV_NAME ##文件系统的强制检测和修复
  • resize2fs /dev/VG_NAME/LV_NAME n# ##缩减到多大,将逻辑边界缩小(要确保缩减后的空间,可以容纳现有数据)
  • lvreduce -L [-]#[mMgGtT] /dev/VG_NAME/LV_NAME 不加减号就是缩小到多少。
1、卸载挂载点
[root@Centos7 ~]# umount /mnt/lvm/

2、强制执行检测与修复(检查是否修改后的大小会影响数据)
[root@Centos7 ~]# e2fsck -f /dev/myvg/mylv 
e2fsck 1.42.9 (28-Dec-2013)
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
MYLV: 13/163840 files (0.0% non-contiguous), 77665/2621440 blocks

3、缩小文件系统,原来是2.5G,现在指定成2G(我指定过1.8但是报错了,没有成功)
[root@Centos7 ~]# resize2fs /dev/myvg/mylv 2G
resize2fs 1.42.9 (28-Dec-2013)
Resizing the filesystem on /dev/myvg/mylv to 2097152 (1k) blocks.
The filesystem on /dev/myvg/mylv is now 2097152 blocks long.

4、缩小lv,可以直接使用"-L"指定收缩容量,也可以使用"-l"指定收缩的PE数量。
发现有警告:可能会损毁你的数据。如果在该lv下存储的实际数据大于收缩后的容量,那么肯定会损毁一部分数据,但是如果存储的数据小于收缩后的容量,那么就不会损毁任何数据,这是lvm无损修改分区大小的优点。此处由于在lv下完全没有存储数据,所以无需担心会损毁,直接y确定reduce。
[root@Centos7 ~]# lvreduce -L 2G /dev/myvg/mylv 
  WARNING: Reducing active logical volume to 2.00 GiB.
  THIS MAY DESTROY YOUR DATA (filesystem etc.)
Do you really want to reduce myvg/mylv? [y/n]: y
  Size of logical volume myvg/mylv changed from 2.50 GiB (640 extents) to 2.00 GiB (512 extents).
  Logical volume myvg/mylv successfully resized.



##如果仅仅为了缩小LV的空间,那么已经结束,可以直接执行第8步操作。如果想要把一块硬盘将vg中移除,继续第五步。



5、pvmove移动PE
首先确定好想要移除哪块硬盘。
然后确定经过缩减之后,缩减掉的空间,大于想移除的那块硬盘的空间。
因为不确定缩减掉空间,是来源于那块硬盘的,所以查看每块硬盘的pe使用情况(通过pvdisplay与pvscan)
如果指定硬盘的PE被占用,则不可以从vg中移除,需要执行pvmove命令,将该硬盘上的PE移动到其他硬盘上才可以。
例如:想要移除/dev/sda15,但是/dev/sda15上还有数据,则将/dev/sda15的数据移动到/dev/sda17(其实不用将全部PE移动,可以通过pvdisplay -m /dev/sda#查看哪些PE在使用,只把正在使用的PE移动过即可)
[root@Centos7 ~]# pvmove /dev/sda15:0-254 /dev/sda17
  /dev/sda15: Moved: 0.00%
  /dev/sda15: Moved: 56.86%
  /dev/sda15: Moved: 100.00%


6、从vg中移除pv
使用pvdisplay -m /dev/sda#	查看是否还有PE被占用,如果没有则执行移除
例如:
[root@Centos7 ~]# vgreduce myvg /dev/sda15
  Removed "/dev/sda15" from volume group "myvg"

7、移除该pv
[root@Centos7 ~]# pvremove /dev/sda15
  Labels on physical volume "/dev/sda15" successfully wiped.

8、重新执行mount
[root@Centos7 ~]# mount /dev/myvg/mylv /mnt/lvm/

7. Snapshot

7.1 基本概念

  • 序列化:把本来有形状的,有组织格式的数据,转换成能够流式化传输的机制。
  • 快照首先要快,否则可能会造成各部分数据不匹配(先扫描的旧,后扫描的新。导致数据组合不起来)

下面这部分LVM快照原理与图片部分,摘自Linux公社的文章:基于LVM的快照实现原理分析

LVM快照原理
LVM对LV提供的快照功能,只对LVM有效。
当一个snapshot创建的时候,仅拷贝原始卷里数据的元数据(meta-data)。创建的时候,并不会有数据的物理拷贝,因此snapshot的创建几乎是实时的,当原始卷上有写操作执行时,snapshot跟踪原始卷块的改变,这个时候原始卷上将要改变的数据在改变之前被拷贝到snapshot预留的空间里,因此这个原理的实现叫做写时复制(copy-on-write)。
在写操作写入块之前,将原始数据移动到 snapshot空间里,这样就保证了所有的数据在snapshot创建时保持一致。而对于snapshot的读操作,如果是读取数据块是没有修改过的,那么会将读操作直接重定向到原始卷上,如果是要读取已经修改过的块,那么就读取拷贝到snapshot中的块。
创建snapshot的大小并不需要和原始卷一样大,其大小仅仅只需要考虑两个方面:从shapshot创建到释放这段时间内,估计块的改变量有多大;数据更新的频率。一旦 snapshot的空间记录满了原始卷块变换的信息,那么这个snapshot立刻被释放,从而无法使用,从而导致这个snapshot无效。

创建快照
在快照创建的时候,仅拷贝原始卷里数据的元数据(meta-data),并生成位图记录原始卷的块数据变化。

读写原始卷
在创建完快照后,对原始卷的读写请求处理流程如下。

  • 写原始卷 在原始卷的写入数据

    • 检查Chunk位图中要写入数据所在的Chunk所对应的bitmap是否被置位;
    • 如果已被置位,直接写入该Chunk;如果未被置位,将拷贝该Chunk的数据到快照备份卷;
    • 将Chunk位图中对应的bitmap置位。
    • 将数据写入原始卷。
  • 读原始卷

    • 直接从原始卷对应的Chunk中读取数据。
  • 读写快照

    • 读快照
      • 在处理快照的读请求时,检查Chunk位图是否置位,如果置位从快照读取数据;如果未置位,则从原始卷读取数据。如下图所示:
  • 写快照
    在处理快照的写请求时,

    • 检查Chunk位图是否置位,如果置位直接写快照;
    • 如果未置位,则从原始卷读取该Chunk的数据,拷贝到快照卷;
    • 将Chunk位图中对应的位图置位;
    • 将数据写入快照卷;

7.2 创建快照

创建快照的命令格式

lvcreate –L #[mMgGtT] –p r –s –n snapshot_lv_name  original_lv_name
Note:快照卷通常是只读的,所以分配-r即可。

[Allen@Centos7 ~]$ sudo lvcreate -s -L 512M -n mylv-snap -p r /dev/myvg/mylv
  Using default stripesize 64.00 KiB.
  Logical volume "mylv-snap" created.
[Allen@Centos7 ~]$ sudo mkdir /mnt/snap ; sudo mount /dev/myvg/mylv-snap /mnt/snap
mount: /dev/mapper/myvg-mylv--snap is write-protected, mounting read-only
复制一个新文件到原卷,快照卷不会发生变化,因为快照卷只复制发生变化的文件。

7.3 恢复快照

7.3.1 方法一

[root@Centos7 ~]# lvdisplay /dev/mapper/testvg-testlv 			##查看逻辑卷状态
  --- Logical volume ---
  LV Path                /dev/testvg/testlv
  LV Name                testlv
  VG Name                testvg
  LV UUID                iPAbi5-foGP-0zqc-zvpb-4eLo-3aeu-fYhV3z
  LV Write Access        read/write
  LV Creation host, time Centos7.4, 2018-08-28 10:35:03 +0800
  LV snapshot status     source of
                         testlv-snap [active]
  LV Status              available
  # open                 1
  LV Size                2.00 GiB
  Current LE             128
  Segments               3
  Allocation             inherit
  Read ahead sectors     auto
  - currently set to     256
  Block device           253:2
[root@Centos7 ~]# umount /dev/myvg/mylv-snap		##卸载快照的挂载点
[root@Centos7 ~]# umount /dev/myvg/mylv				##卸载原卷的挂载点
[root@Centos7 ~]# lvconvert --merge /dev/myvg/mylv-snap		##执行快照恢复
  Merging of volume myvg/mylv-snap started.
  testlv: Merged: 96.38%
  testlv: Merged: 100.00%
查看文件,发现所有文件的状态和内容都回复到做快照的那个时间点了。而且快照文件没有了
[root@Centos7 ~]# lvdisplay /dev/mapper/testvg-testlv 			##查看逻辑卷状态
  --- Logical volume ---
  LV Path                /dev/testvg/testlv
  LV Name                testlv
  VG Name                testvg
  LV UUID                iPAbi5-foGP-0zqc-zvpb-4eLo-3aeu-fYhV3z
  LV Write Access        read/write
  LV Creation host, time Centos7.4, 2018-08-28 10:35:03 +0800
  LV Status              available
  # open                 1
  LV Size                2.00 GiB
  Current LE             128
  Segments               3
  Allocation             inherit
  Read ahead sectors     auto
  - currently set to     256
  Block device           253:2

7.3.2 方法二

这种方式我只做过一次,环境及方法如下
1、做一个镜像
dd if=/dev/vg_image/lv_image_snap of=/data/recover.img
##确保/data拥有足够的空间,这个相当于做了原卷的镜像。因为snapshot只是原卷数据的另一个通路。访问没有发生变化的数据会指向原卷,访问原卷上发现变化的数据会指向snapshot本身(在发生变化的时候,会先拷贝一份数据到snapshot卷),所以这个dd是对快照时间点的所有原卷做了镜像。

2、删除snapshot
umount XXX
lvremove /dev/vg_image/lv_image_snap

3、卸载原卷挂载点
umount XXX

4、执行恢复
dd if=/data/recover.img of=/dev/vg_new/lv_new

5、重新挂载原卷
已恢复之前挂载的状态了(只是简单地查看一些文件内容和时间戳)

7.4 移除快照

lvremove /dev/myvg/mylv-snap
原文地址:https://www.cnblogs.com/jzbgltb/p/9548991.html