LVM2 逻辑卷的简单应用

简单介绍

  英文全称为 Logical Volume Manager,Version:2。顾名思义:逻辑卷管理器,版本为2。==利用内核中的dm模块(device mapper,设备映射模块)==,用纯软件的方式将底层的一个或多个的块设备组成一个逻辑设备来使用,逻辑卷的核心其实就是dm模块。

基础概念

  1. PE:物理盘区(Phsical Extent),它在逻辑卷架构中比较微观,每一块PE的大小是你将A-PV加入B-VG时自动分割的(当然也可以手动指定大小)。所以,在A-PV还未加入B-VG前,它的大小是不确定的。具体大小要看VG的要求,因为每一个VG对于PE大小的定义可能是各不相同的,默认会将PV分割没块大小为4MB的PE。
  2. PV:物理卷(Phsical Volume)
  3. VG:卷组(Volume Group),它可以包含多个物理卷,可用空间就是被包含进这个卷组的全部物理卷所提供的存储空间之和。如果某个时刻,这个卷组空间不够用了,我们就可以向这个卷组中新加入物理卷。
  4. LV:逻辑卷(Logical Volume),需要在VG的空间上划分,每一个LV都是一个独立的存储空间,都可以被格式化后挂载至任意指定位置,可用空间是本卷组的任意可用大小。
  5. LE:当PE逐层向上管理,如果被分配给某个LV使用,它就叫做LE(Logic Extent)。

我自己理解的LVM架构图

  • 小总结:正是因为逻辑卷把磁盘空间分割成小PE,才让它可以动态伸缩,而不危害到里面的数据。它不像基本的磁盘分区,一旦空间满了就需要挪动数据或重新分区。安装Centos 7系统时,如果你选择自动划分区,它就会把文件系统构建在逻辑卷之上。每一个逻辑卷到底能扩展到多大取决于你的VG中还有多少空闲空间,不够用了就可以加入PV、VG,所以这样对于企业级不可预测的增长速度来说,这的确是一个很好的解决方案,但它也有一个缺点,就是lvm毕竟是在利用纯软件的方式在一个较高的层次上组织数据,所以一旦发生损坏,修复比较困难,毕竟它不是将数据直接存储在硬件上的。

如果想从LVM中拆掉某个PV,那么必须保证剩余的PV能够完全承载现有数据。并且,如果预拆PV中如果有数据,还必须先使用命令,先将这个预拆PV上面的数据挪动走才行。

设备文件路径:

  1. ==真正的设备文件路径:/dev/dm-#(块设备文件)==
  2. 方便引用的路径:
- /dev/mapper/VG_NAME-LV_NAME (链接文件)
- /dev/VG_NAME/LV_NAME (链接文件)

命令

PV管理的相关命令:

 1. pvcreate [option] [device]:创建物理卷。
option:
-v:显示过程
-u:手动指明uuid
-f:强制创建
2. pvdisplay [device]:显示物理卷详细信息,输出的信息重点关注。
- Allocatable:是否可分配
- Allocated pe:以分配pe数

3. pvremove [DEVICE]:删除物理卷。
4. pvmove [DEVICE]:将物理卷的数据挪动到其他pv上。
5. pvscan:扫描物理卷。
6. pvcheck:pv检测。
7. pvs [device]:简要信息显示。

VG管理的相关命令

1. vgcreate VG_NAME [option] [device]:创建vg。
option:
-s #[kKmMgG]:手动指明pe大小,pe大小在创建vg完成之后就已经确定了,除非重新创建;
2. vgextend VG_NAME DEVICE:vg扩展。
3. vgreduce VG_NAME [DEVICE]:vg缩减,缩减之前记得先对需要拆掉的分区做pvmove。
4. vgrename OLD_NAME NEW_NAME:vg重命名。
5. vgdisplay [device]:详细信息。
6. vgs [device]:简要信息。
7. vgsplit:vg切割。

LV管理的相关命令

1. lvcreate [option] VG_NAME:创建lv
option:
-L #[mMgGtT]:逻辑卷大小;
-n <name>:逻辑卷名;
-l:指明分配的逻辑盘区的数量。
-s:创建快照;
2. lvs:简要显示lv的信息。
3. lvdiplay:详细显示lv信息。
4. lvextend -L [+]#[mMgGtT] /dev/VG_NAME/LV_NAME
5. lvreduce [option] /dev/VG_NAME/LV_NAME
option:
-L #:缩减至#
6. lvremove /dev/VG_NAME/LV_name:删除逻辑卷;
7. lvresize:
8. lvconf:设置lv配置文件。

LV创建的注意事项:

  1. 创建pv指定空间大小时,一定确保vg中有足够的空间可以被划分。
  2. 如果使用你指明创建1个10MB大小的lv,它的空间大小不一定精确10MB,这取决于你底层每块pe的大小。如pe=4mb,你的要求10mb,它只能给你2或3个,故不可能精确。

lv的扩展与缩减:

  1. lv的扩展:创建完成的lv,它不能直接使用,需要将lv提供的空间格式化为符合要求的文件系统才可以挂在使用。我们称lv提供的空间为物理边界或物理空间,文件系统称为逻辑空间或逻辑边界。所以逻辑空间无论如何扩容,它也不能超过物理空间,因为需要物理空间支撑。使用lvextend命令完成扩容后,也仅仅是拉大了物理空间的边界,还需要手动拉大逻辑边界,才能真正使用到新增的存储空间。
  2. lv的缩减:使用lvreduce命令,首先要评估下,缩减后的空间大小能不能承载现有的所有数据,然后卸载目标lv并强制做文件系统检测,接着缩减它的逻辑边界,最后在缩减物理边界。
  3. 重新加载逻辑边界大小的命令:
ext系列:resize2fs [/dev/VG_NAME/LV_NAME] [# mMgGtT]
xfs扩展:xfs_growfs [/dev/VG_NAME/LV_NAME]
缺省大小表示,扩展到所有可用空间。

一次完整的操作过程

创建逻辑卷首先需要创建pv,在将pv组织成vg,最后才能在vg上划分lv。

1.准备多个分区。
2.创建3个pv,使用3个pv创建1个vg,从vg中移除1个pv后再加入。
3.在这个vg中划分lv,做成文件系统后向lv中复制数据,接着扩展lv空间,查看数据。
4.缩减lv空间大小,保证数据无损。

  • 第一步:准备多个分区,我这里使用1块100G的硬盘,共创建了4个分区,并且分区类型也调整为8e。
    用到的命令:fdisk

  • 第二步:创建3个pv,用3个pv创建1个vg,从中移除1个pv后再加入。
    首先创建3个pv,用到的命令:pvcreate、pvs、pvdisplay
    在这里插入图片描述
    这里共创建了4个pv,其中PV:/dev/sda2是系统安装时创建的。使用pvdisplay命令查看pv属性,可以看到这里pe size等属性还是0,这就是因为它还没有加入任何vg中,所以还无法确定。

    接下来使用3个pv创建1个vg,用到的命令vgcreate、vgs、vgdisplay
    在这里插入图片描述
    我这里手动指定了 pe大小为8M,并且创建完成后,将myvg改名为newvg。
    然后在newvg中移除一个pv,在加入。用到的命令:vgextend、vgreduce
    在这里插入图片描述
    因为这个是刚创建的vg,还未划分lv,所以拆除前未执行pvmove /dev/sdb3

  • 第三步:在这个vg中划分lv,做成文件系统后向lv中复制数据,接着扩展lv空间,查看数据。
    用到的命令:pvcreate、mkfs.ext4、mount、cp
    在这里插入图片描述
    拷贝了/etc/下所有的数据到/mytest,现在执行扩展。
    首先查看vg的详细信息,还剩2557个pe可以分配,那么就使用指定pe的方式,实现扩展。
    用到的命令lvextend
    在这里插入图片描述
    完成扩展,但是查看vg的信息。
    在这里插入图片描述
    在这里插入图片描述
    此时vg中已经的pe已经完全被分配了,但是需要注意这只是扩展了物理边界,需要执行resize2fs命令,扩展逻辑边界。
    执行resize2fs命令前后情况对比
    在这里插入图片描述
    第四步:缩减lv大小,保证数据无损。
    首先需要卸载逻辑卷,并执行文件系统强制检测命令。如果你不执行检测,逻辑卷也会报错,提示你需要执行检测后才能缩减。(下图中可看出,没有执行文件系统检测命令,会提示你,一定注意,==逻辑边界大小一定要能承载现有的数据才行==)
    在这里插入图片描述
    接着缩减物理边界,物理边界一定要大于逻辑边界。我这里故意缩减的比逻辑边界小,挂载的时候报错了😂。

[root@node1 ~]# lvreduce -L -20G /dev/mapper/newvg-mylv 
WARNING: Reducing active logical volume to <39.98 GiB.
THIS MAY DESTROY YOUR DATA (filesystem etc.)
Do you really want to reduce newvg/mylv? [y/n]: y
Size of logical volume newvg/mylv changed from <59.98 GiB (7677 extents) to <39.98 GiB (5117 extents).
Logical volume newvg/mylv successfully resized.
[root@node1 ~]# mount /dev/mapper/newvg-mylv /mytest
mount: wrong fs type, bad option, bad superblock on /dev/mapper/newvg-mylv,
missing codepage or helper program, or other error

In some cases useful info is found in syslog - try
dmesg | tail or so.

我又扩展了物理边界,在挂载就没出现问题了。

[root@node1 ~]# lvextend -L +10G /dev/mapper/newvg-mylv 
Size of logical volume newvg/mylv changed from <39.98 GiB (5117 extents) to <49.98 GiB (6397 extents).
Logical volume newvg/mylv successfully resized.
[root@node1 ~]# mount /dev/mapper/newvg-mylv /mytest
[root@node1 ~]#

==小知识点==:缩减的时候,如果物理边界指定小了,挂载会报错。为了数据稳妥只能将逻辑边界手动指定比物理边界小一点来保证它不会损坏,但是肯定就会出现一个问题。我提供的物理边界一定会有浪费。本着勤俭节约的精神,哪怕是浪费1KB也不行😆。那么你就可以执行resize2fs DEVICE_NAME max来充分扩展逻辑边界,保证1KB都不浪费😆。


快照卷:

它其实是访问同一位置的不同路径而已,但通过它访问到的数据,全部都是创建快照那一刻是的状态。lvm在你创建快照的那一刻,立即启动一个监视器,时刻监控着元数据的变化,若某个文件的元数据发生改变,它就会在修改前将未修改的数据复制一份存到快照卷中,来保证通过它访问的数据依然是创建快照那一刻时的状态。结果就是未变化数据通过源卷访问,变化的数据在它变化之前复制一份到快照卷,通过快照卷访问,这样保证了通过快照卷访问到的数据,全部都是统一时间点的。但需要注意的是,快照卷需要和源卷来自同一卷组。并且,它与源卷共用卷组中的存储空间,你需要预先评估快照卷的存活时间,因为快照卷也是有空间大小的,一旦变化的数据超过卷的规定大小,那它就没有意义了,务必留好空间冗余。
快照卷和源卷必须是统一卷组中,确保空间足够,一定是某个卷的快照,所以要针对某个卷来创建,其他与逻辑卷无异。

举个栗子
在这里插入图片描述
如图中所示,用户通过哪个路径访问的数据都是一样的。当某一时刻,B.txt发生改变时,/mytest快照为了保证数据时间点一致,就会复制一份备份到快照中。这样,用户通过/mytest快照访问数据,发生改变的在快照卷中查找,未改变的直接查源卷即可。

创建快照卷的命令:

lvcreate -L #[mMgGtT] -p r|rw -s -n snapshot_name src_lvm_name
-L:指明快照卷大小。
-p:指明权限,r或rw。
-s:指明创建快照卷。
-n:指明快照卷名字。

创建快照卷的过程

1.首先针对现有的某个卷来创建快照卷,如下所示,mylv是我自建的lv,并且查看下newvg的空闲空间,FREE PE还可以分配1280个,大概空间为10G,那么就利用这10G 创建1个快照卷。

[root@node1 ~]# lvs
LV VG Attr LSize Pool Origin Data% Meta% Move Log Cpy%Sync Convert
home centos -wi-ao---- 45.99g
root centos -wi-ao---- 50.00g
swap centos -wi-ao---- 3.00g
mylv newvg -wi-ao---- <49.98g
[root@node1 ~]# vgdisplay newvg
--- Volume group ---
VG Name newvg
System ID
Format lvm2
Metadata Areas 3
Metadata Sequence No 10
VG Access read/write
VG Status resizable
MAX LV 0
Cur LV 1
Open LV 1
Max PV 0
Cur PV 3
Act PV 3
VG Size <59.98 GiB
PE Size 8.00 MiB
Total PE 7677
Alloc PE / Size 6397 / <49.98 GiB
Free PE / Size 1280 / 10.00 GiB
VG UUID lWBfYV-1jGu-aaVZ-gsyL-XER7-0wHR-t3tRYv
[root@node1 ~]# lvcreate -l 1280 -s -n mylv-snap /dev/mapper/newvg-mylv
Logical volume "mylv-snap" created.

创建完毕后就可以挂载并使用了,我将mylv-snap挂载到了/mytest-snap。
此时访问/mytest/a.txt/mytest-snap/a.txt得到的结果是一样的。
在这里插入图片描述
现在向/mytest/a.txt中加入一些数据再来查看。
在这里插入图片描述
发现快照卷中的数据并没有变化,验证完毕。


来点小练习

  1. 创建至少由两个PV组成的大小为20G名为testvg的VG,要求PE大小为16M,而后在卷组中创建大小为5G的逻辑卷,testlv,挂载至/users目录。
  2. 新建用户archlinux,要求其家目录为/users/archlinux,而后su切换至archlinux用户,复制/etc/pam.d目录至自己的家目录。
  3. 扩展testlv至7G,要求archlinux用户的文件不能丢失;
  4. 收缩testlv3G,要求用户文件不能丢失;
  5. 对testlv创建快照,并尝试基于快照备份数据,验证快照功能;

总结

  1. lvm使用的难点在于对它的扩展和缩减,搞清逻辑边界与物理边界:
    • 扩展时:保证底层设备已经加入vg,先扩展物理边界在扩展逻辑边界。
    • 缩减时:确保缩减后的空间可以承载现有数据,然后再卸载--> 文件系统检测--> 缩逻辑边界 --> 缩物理边界
      如果是想拆掉某个分区,那么需要在缩减的步骤前,先对预卸载分区执行pvmove
  2. 在命令中引用lv的名字是一定要给全路径如/dev/mapper/vg_name-lv_name,自己在做实验时,很多次都是因为给的lv名称不对导致排半天错。
  3. 快照的的功用在于备份文件时特别有用。应该可以使用服务停止命令 && 创建快照命令 && 服务启动命令,这样保证服务最短时间的中断来备份数据,这个我后续会慢慢的尝试。再则就是快照卷和目标卷共享卷组空间,一是保证卷组中有足够的空间来创建快照卷,二是评估好快照的存活时间,一定保证存活时间内,变化的数据大小不会超过快照卷设置的空间大小。
  4. lvm的优缺点:可扩容、缩减。但是损坏后数据很难恢复,因为lvm是纯软件的方式实现。

问一下:

  1. 我使用代码块把命令扩起来后,应该是里面的#号把部分代码变成斜体了,而且高亮了。尝试过转义符 \ ,但是转义符也一并显示出来了,想问一下,有没有什么方法可以让#号在代码块中只表示#,同时转义符也不要显示出来 的方法。(我现在用的是csdn自带的网页markdown编辑器)
  2. 逻辑卷需要把分区类型调整为8e,但是我尝试过不调整直接pvcreate,也是可以创建pv的,敢问阁下可否指定,到底调整与不调整,对于数据存储有何影响。😟

作者:busyops
邮箱:busyops@outlook.com
本文仅是我的一些简单理解,迫切希望大家指定 One two,ten分感谢。
欢迎随时讨论。
最后更新时间为:2021-05-09 23:24:00