LVM是Linux中的逻辑卷管理功能,其基础是内核的Device Mapper功能。LVM为Linux提供了极其灵活的分区管理功能,可以突破MBR、GPT分区中对于分区调整的种种限制。
本文将介绍LVM的基本概念、入门使用、快照卷和精简配置。
LVM的基本概念
一般来说,LVM的基本概念有以下五项:
- 卷组(VG):Volume Group,是连接物理存储和逻辑存储的中间层,它将一个及以上的PV划分为若干块(Extent)来分配给逻辑卷(LV)使用。
- 两种卷:
- PV:Physical Volume,物理卷,是LVM格式的块设备(物理磁盘、物理分区、物理RAID、软RAID虚拟设备),其上没有传统的文件系统,而是按照LVM需要的格式组织数据。
- LV:Logical Volume,逻辑卷,是在VG上建立的供用户使用的数据卷,其空间由若干等大的逻辑单元(LE)组成。
- 两种单元:
- PE:Physical Extent,物理单元,VG将PV纳入自己的管辖时,会把PV分割为等大的单元,这些单元称为PE,默认大小为4MiB。PE的大小取决于VG的设置,而非PV本身。
- LE:Logical Extent,逻辑单元,是LV的组成单元,是PE的映射。
Extent在计算机中通常表示一段连续空间,在执行空间分配时是操作的最小单元,例如当LE为4MiB时,LV的大小必须是4MiB的整数倍,而不能是9MiB、10MiB这样的大小。
PE-LE是LVM对存储空间管理的最小单元,也是LVM灵活性的基石。通过LE的分配与释放,我们可以灵活的调整LV的大小;通过PE-LE映射关系的变更,我们可以将一个LV的数据移动到另一个LV中,从而实现精简卷和快照功能。
入门使用
命令格式
LVM的命令格式通常为层级+动作,例如变更属性,分别有pvchange,vgchange,lvchange命令。
有一些动作在PV、VG、LV三个层次都存在,见下表:
- 扫描变更:pvscan vgscan lvscan
- 查看属性:pvdisplay vgdisplay lvdisplay
- 改变属性:pvchange vgchange lvchange
- 创建对象:pvcreate vgcreate lvcreate
- 删除对象:pvremove vgremove lvremove
- 查询信息:pvs vgs lvs
另外的一些命令可能名称相同,但是在不同的层次中含义并不一致,例如lvextend和vgextend,前者是以Extend为单位扩展空间,而后者则是加入新的PV。
另外,还有一些LVM整体的设置命令,以lvm开头,这些命令可以使用man 8 lvm
查询。
PV管理
PV创建于块设备上,块设备可以是整个磁盘、标准的分区、RAID和Linux RAID设备。
最常使用的命令是pvcreate。
pvcreate创建物理卷
# pvcreate PV OPTIONS
pvremove命令可以消除块设备上的PV信息
pvdisplay显示PV信息
# pvdisplay OPTIONS PV
其他命令
- pvresize:重设PV大小,通常用于PV所在块设备大小改变后更新PV的大小信息;
- pvmove:将一个PV中的单元转移到另一个PV上;
- pvck:检查PV元数据的一致性。
VG管理
常用的命令包括vgcreate、vgextend。
vgcreate创建VG
# vgcreate VG_new PV
vgremove可以删除已经创建的VG。
vgexntend扩展VG到新的PV上
# 将PV追加到VG中
pvreduce命令可以释放VG中已有的PV。
其他命令
- vgck:检查VG的元数据一致性;
- vgrename:VG是有名称的,可以使用vgrename重命名;
- vgsplit: 将一个VG中的一个PV分离到另一个PV中;
- vgmerge:将多个VG合并为一个VG;
- vgexport: 将一个VG对系统隐藏(用于处理VG重名等冲突情况);
- vgimport: 恢复被vgexport隐藏的VG。
LV管理
LV的主要动作包括建立、扩展和收缩,分别是lvcreate、lvrextend和lvreduce。
lvcreate创建逻辑卷
# 本例中只说明一般LV(Thick Volume)的创建
需要注意-L
参数和-l
参数的区别:
-L
是--size
的短格式,直接指定容量,需要单位(不同的单位格式效果一致,例如g/G/gb/GB/gib/GiB都是等效的)-l
是--extents
的段格式,指定extent的数目,不加单位
注意,由于元数据会占用部分空间,一个VG内的空间并不能全部被LV使用,一般会损失数个extents的大小。
lvremove是lvcreate的反动作,格式如下:
# 删除一个卷 lvremove VG/LV
lvremove archlinux/root
lvextend扩展逻辑卷
# lvextend的必要参数包括要扩展的LV和新大小两个参数
-L
和-l
参数的用法和lvcreate是一致的。
一次完整的卷扩展分为扩展卷和扩展文件系统两步(标准磁盘也是如此),lvextend只完成第一步,而扩展文件系统则需要使用文件系统对应的用户工具来完成。也可以在lvextend
命令中加入-r
参数来自动扩展文件系统,否则需要使用文件系统对应的命令来手动扩展。
-r
参数实际通过调用文件系统对应的工具来工作,例如对ext4使用resize2fs,对xfs使用xfs_growfs。
lvreduce收缩逻辑卷
风险操作:收缩逻辑卷时务必小心,错误的参数可能导致数据的损坏,例如将卷收缩得比文件系统更小,或者在文件系统不支持收缩的情况下收缩了卷。
进行逻辑卷收缩的前提是其上的文件系统支持缩小,如果文件系统不支持缩小(如xfs),贸然进行逻辑卷收缩会导致数据丢失。
显然,在文件系统收缩之前收缩逻辑卷,有可能导致数据丢失(被收缩的部分可能存在数据)。因此,要先收缩文件系统,后收缩逻辑卷。
以一个ext4分区为例(这里的操作只是示范,实际应用中不要这样做):
实际上,LV的扩大和缩小并不需要考虑逻辑卷是否已经挂载,但是因为文件系统通常可以在线扩大而不能在线缩小,因此扩展逻辑卷可以在线进行,而缩小则必须先执行umount。
# resize2fs 不支持在线缩小文件系统,需要先卸载:
umount /dev/archlinux/root
为了数据的安全,在实际情况下我们应该使用-r
参数自动收缩文件系统,使用-t
在正式收缩前进行测试,使用-A y
参数在操作时自动备份VG中的metadata,绝不要使用-f
和-y
两个参数。
正确示例
# 先在测试模式中运行收缩:
lvreduce -L 1G -t -r /dev/archlinux/root
如果真的翻车了,请参考vgcfgbackup
和vgcfgresotre
的使用方法。
其他命令
- lvrename: LV和VG一样是具有名称的,可以使用lvrename来重命名;
- lvconvert:转变LV的类型/布局。
快照卷
快照功能是基于CoW技术的。
CoW:Copy on Write,写入时复制。在需要多份相同的数据实例时,并不会立刻将一份数据复制为多份,而是使用指针指向数据源,在读取一个实例时通过指针找到数据内容;当需要像实例中写入内容时,才会将数据复制到实例中,再进行写入。
LVM快照卷创建时,内部并不包含数据,而是通过指针指向原始卷中的数据;当原始卷中的数据发生变化时,快照卷中会复制原始卷中修改前的数据,而原始卷中记录修改后的数据;未经修改的部分任然通过指针指向旧的数据卷。
“数据变化”的判断依据是“卷是否变化”而非“文件是否变化”。例如在创建快照后,在已有2GB数据的原始卷中创建一个4GB的新文件,快照卷中也会记录4GB的内容——原始卷中的4GB空白区域。虽然快照前已经存在的文件并未发生变化,但是创建新文件后原始卷确实发生变化了,快照卷也忠实的记录下了变化前变化区域的内容。
快照卷分为普通快照卷和精简快照卷,后者在精简配置部分中介绍。
# 使用lvcreate -s参数或--snapshot创建快照卷
相比于创建普通卷,快照卷的建立有两个特征:
- 不需要指定卷组:由于快照卷中需要存在指向数据的指针,因此只能和原始卷存放于同一个卷组中。
- 独立的容量参数:快照卷的容量来自于卷组,故卷组中需要留有空余空间才能创建快照卷;快照卷的容量是可以记录变化的总容量,当原始卷的变化总量超过了快照卷的容量时,快照就会失效。
如果要创建一个长期有效的快照,这个快照的大小必须等同于原始卷的大小(快照前后的差异量小于等于总容量),这显然是空间不经济的,因为其中包含了文件系统的空白部分,但是在时间上是经济的,它不需要花费额外的时间执行备份和还原,快照生成和还原都是非常迅速地过程。
实际上,我们做快照的目的和备份是不同的,其作用在于风险操作后的快速回滚,例如安装系统更新、安装新软件等。以安装Gnome为例,它造成的数据变化大约在2GB左右,这时候只需要创建一个3GB的快照卷即可,如果安装不成功需要回滚,由于快照卷大于该变量,所以可以立即回退到快照中的状态;如果安装成功,则这个快照并不会被使用,就可以直接删除了,快照一般不需要长期保留。
恢复快照使用lvconvert
命令:
# lvconvert --merge VG/SNAPSHOT
lvconvert --merge archlinux/snap1
快照和原始卷存在联系关系,因此命令中只需要指出要恢复的快照即可。
此外,快照卷也可以单独的挂载并进行读写,通过这种方式可以恢复单个或多个文件/目录,而非以卷为单位还原。
注意:快照默认不是只读的,用户可以挂载快照卷直接在其中进行修改,这样快照的效果类似于分支。
精简配置
精简配置(Thin Provisioning)指分配的资源量超过实际的物理资源量,类似于现实社会中的“超售”概念。
LVM的精简配置中有两个要素,分别是精简池和精简卷。
精简池
精简池是一个特殊的普通LV,在它建立时会立即从VG中分配空间,与正常的LV没有什么不同;但是这个LV不能被创建文件系统直接使用,而是处于一种特殊的格式,包含数据和元数据两个部分。
精简池的作用是为精简卷提供空间,而精简卷本身不能从VG中直接获取空间。
# 创建一个精简池
--thinpool
参数表示建立名为XX的精简池,因此不再需要-n
或--name
表示卷名称。
精简卷
精简卷和普通卷的根本差异,在于其创建时,并不从VG中真的分配空间,而是虚拟的分配空间,当进行写入时,则会写入到对应的精简池中。
从创建参数上我们就可以看出区别:
# 在精简池tp1中创建两个精简卷
lvcreate -V 4G --name thinv1 --thin archlinux/tp1
lvcreate -V 4G --name thinv2 --thin archlinux/tp1
指定空间是使用的是-V
参数而非-L
,是分配虚拟的空间,并且需要指定所在池而非所在VG。
初始创建的精简池占用空间为0,会随着写入而扩大,类似于动态扩展的虚拟磁盘。需要注意的是,因为LVM无法得知文件系统内的事件,这种扩大不是以文件为单位的,即你创建了一个2GiB的文件,然后删除了它,精简池并不会将这2GiB的空间收回。
自动扩展
显然,我们的tp1本来只有4GiB的空间,而thinv1和thinv2的总量已经达到8GiB。如果thinv1和thinv2中的写入总量不超过4GiB,就永远不会出问题,但是为考虑到可能的空间耗尽的情况,我们需要对精简池设置自动扩展功能。
卷的配置文件存放于/etc/lvm/profile
中。
我们需要为精简池创建一个配置文件,并设置两个参数:阈值和扩展量。
也可以直接在
lvm.conf
设置全局参数
下面是一个例子:/etc/lvm/profile/tp1.conf
activation {
thin_pool_autoextend_threshold=70
thin_pool_autoextend_percent=20
}
启用这个配置文件:
lvchange --metadataprofile tp1 archlinux/tp1
如此,精简池就会在使用量达到70%时自动从VG中分配20%的空间,例如1GiB的池在使用了0.7GiB时会自动扩展到1.2GiB。
需要注意的是,虽然精简池可以实现自动扩展,但是VG并不能自动扩展,因为PV提供的空间是有限的。在使用精简配置时,需要注意VG的剩余量,对于大型的生产环境,必须使用服务器监控工具进行监视,来避免资源耗尽无法写入的情况。
精简快照卷
精简快照卷是基于精简卷的快照卷,相比于传统快照卷有如下优点:
- 只占用被使用的空间:传统快照卷需要指定不小于预计该变量的大小并分配空间,而精简快照卷则根据改变总量自动的扩展;
- 递归快照:精简快照卷可以被作为一个原始卷来创建一个新的精简快照,并且继续套娃下去;
- 传统快照CoW需要把原始数据复制到所有快照中,快照数目会导致性能降低;而多个精简快照卷公用一个CoW操作保留数据,大量快照不会导致显著性能降低;
- 源卷可删除:源卷删除后它的快照会成为新的精简逻辑卷——简而言之精简快照卷不像传统快照卷那样强烈的依赖原始卷。
例子:创建精简快照卷
# 创建thinv1的精简快照
lvcreate -s archlinux/thinv1 --name snap1
值得注意的是,精简快照卷的大小并不会受到限制,所以会随着变化的增加而不断地增长,在写入量大的卷上创建精简快照卷后,快照可能会在不被注意的情况下增长到和源卷相近的大小。
总结
如果认为LVM的结构难以理解,可以认为LVM实际上就是物理磁盘的虚拟化,物理块设备转化为类似于虚拟磁盘的逻辑卷,将VG看作是一种可以跨越物理设备(PV)的文件系统,LV是文件系统中存放的虚拟磁盘文件。
LVM实际上是一个相对复杂的系统,本文的介绍也仅是冰山一角。除去本文介绍的内容之外,VG的元数据备份还原,lvm.conf
的配置等,以及基于MD的RAID、加密功能调用都在实际应用中可能涉及。
参考内容
- 逻辑卷管理器管理 Red Hat Enterprise Linux 7(Red Hat Customer Portal)
- 逻辑卷管理(IBM Developer)
- LVM - ArchWiki