本文共 14859 字,大约阅读时间需要 49 分钟。
目录
目录
LVM (logical volume manager) 逻辑卷管理是通过将底层物理硬盘抽象封装起来的,以逻辑卷的形式表现给上层系统,逻辑卷的大小可以动态调整,而且不会丢失现有的数据,新加入磁盘也不会改变现有上层的逻辑卷,作为一种动态的逻辑磁盘管理机制,很大程度上提高了磁盘管理的灵活性。
当你用 pvcreate
命令创建 PV 时,该命令会(在逻辑上)把物理存储介质划分为了 N 个大小相同的块,“physical extent”,简称 PE。
pvdisplay
命令查看某个 PV 的详细信息,就能看到如下信息: PE 的尺寸 该 PV 中的 PE 总数 已分配的 PE 总数 未分配的 PE 总数
LVM2 默认的 PE 尺寸是 4MiB。对于新手而言,用【默认的】PE 尺寸就可以啦。
某些老手可能想要自己控制 PE 尺寸——可以在创建 VG 时指定 PE 尺寸,命令如下:vgcreate -s 64M VG_XXX /dev/sdb1
(注:上述命令指定新创建的 VG 使用 64MiB 作为 PE 尺寸;对于 LVM2,PE 最小值是 1KiB)
早期的 LVM1,对 LV 有一个硬性上限——每个 LV 最多只能有 65534 个 LE(仔细看下图的右上角)。所以,早期的 LVM1 用户,如果想要创建一个超大的 LV,需要在创建 VG 时就指定一个偏大的“PE 尺寸”。 到了如今的 LVM2,每个 LV 包含的 LE 数量已经【没有】那个上限了。所以“PE 尺寸”就不像以前那么重要了。在 LVM 的术语中,“物理卷”(PV)用来对应【底层】的“物理硬盘 or 物理分区”。
你可以用 LVM 的命令行工具,把某个“物理硬盘”或“物理分区”创建成 PV。这个 PV 的容量也就是“物理硬盘 or 物理分区”的容量。整个磁盘或者使用fdisk 划分的普通分区。其包括很多固定带小块的PE(physical extent ,物理单元,默认是4M)
通过 LVM 的命令行工具,还可以把多个 PV 纳入到一个 VG(卷组)中。
你不妨把 VG 想象成一个【存储池】,这个池子的容量也就是加入其中的所有 PV 的容量总和。每个 VG 都有自己的一些元数据。比如刚才所说的“PE 尺寸”就是它的元数据之一。
那“VG 的元数据”存储在哪里捏?它们保存在 PV 的头部——当你创建 VG 时,至少要指定一个或多个 PV;新创建的 VG,其元数据就保存在这些 PV 头部。如果这个 VG 后来又加入其它 PV,其元数据也会保存在这些新的 PV 中。元数据保存多份,也是为了达到某种冗余。 你可以用命令vgcfgbackup
把某个 VG 的元数据导出到单个文件中;需要的话,还可以再用命令 vgcfgrestore
导入。 在 LVM 的术语中,“逻辑卷”(LV)用来对应【上层】的“逻辑分区”。
你可以从 VG 中创建多个 LV。每次创建 LV 都如同从这个存储池中分配空间,直到所有存储空间都被分配完。 创建好 LV 之后,你可以对这个 LV 进行格式化,就得到一个可用的逻辑分区。最终直接使用的逻辑卷,可以根须需求格式化成需要的格式使用,注意PV 和 VG 是不能直接使用的。
pvcreate
命令创建 PV。你可以针对【硬盘分区】上创建 PV,也可以针对【整个硬盘】创建 PV,命令分别如下 针对【硬盘分区】创建 PV pvcreate /dev/sdb1针对【整个硬盘】创建 PV
pvcreate /dev/sdc
为了验证上述命令确实创建了一个 PV,你可以执行 pvs
命令,它会列出系统中所有 PV 的名称。
pvcreate
命令之后,它会在对应设备的头部写入一个 LVM 的标志,表示这个设备已经被 LVM 用作“物理卷”) /dev/sdb1
这个设备(物理分区)上创建了 PV,就可以用如下命令创建一个新的 VG,VG 的名称是 VG_XXX
(这个名称纯粹是为了举例,你也可以用其它字母组合作为 VG 的名称): vgcreate VG_XXX /dev/sdb1
为了验证上述命令确实创建了一个 VG,你可以执行 vgs
命令,它会列出系统中所有 VG 的名称。
vgextend
命令加入其它 PV。举例如下: pvcreate /dev/sdc1vgextend VG_XXX /dev/sdc1
(注:前一个命令创建了新的 PV,后一个命令把这个 PV 加入到刚才那个 VG 里面)
添加了 PV 之后,你可以用如下命令查看该 VG,就可以看到它包含的 PV 数。vgdisplay VG_XXX
VG_XXX
中创建一个新的 LV,名叫 lv_xxxx
(这个名字纯属举例,你可以用别的字母组合)。 lvcreate -L 100G -n lv_xxxx VG_XXX
请注意:上述命令中的 -L
和 100G
都是大写;其中的 G
,表示 GB 为单位。你也可以用大写 M
后缀表示多少兆字节(MB)。
lvs
命令,它会列出系统中所有 LV 的名称,以及每个 LV 所属的 VG。 如果你想要创建一个 LV,把 VG 的剩余空间都用掉,可以用如下命令: lvcreate --extents 100%FREE VG_XXX -n lv_xxxx步骤2 “步骤1”只是创建了一个“逻辑设备”,你还需要在该设备上创建文件系统。不同的文件系统,创建的命令也不同。下面以 ext4 为例,在刚才那个
lv_xxxx
之上创建 ext4 文件系统。 mkfs.ext4 /dev/VG_XXX/lv_xxxx步骤3 最后,你用
mount
命令挂载新创建的文件系统。 友情提示 Linux 有个很有用的命令 lsblk
,他以【树状风格】展示系统中所有“块设备”(block device)的层次关系;如果该设备有挂载点,也会一并标注。 当你创建了 LV 之后,可以运行该命令体验一下。 /etc/fstab
文件,把需要自动挂载的“LV 路径”以及“挂载点路径”添加到该文件中。 lvresize -L +50G VG_XXX/lv_xxxx
(注:上述命令中,VG_XXX
是“VG 名称”;lv_xxxx
是“LV 名称”;两者之间用【半角斜杠】相连接)
lvresize -L 50G VG_XXX/lv_xxxx
上述两个命令,就差了一个【加号】。-L +50G
表示空间【再增加 50GB】;-L 50G
表示空间【增加到 50GB】。
resize2fs
,用法如下: resize2fs /dev/VG_XXX/lv_xxxx
ext 家族的好处是——支持【在线扩容】,你不需要卸载文件系统,就可以直接扩大其容量。
文件系统的差异 并【不是】所有的文件系统都支持“扩容”的功能。另外,有些文件系统虽然支持“扩容”,但不支持“在线扩容”——也就是说,你要先卸载文件系统,然后再执行“扩容命令”。
vgrename
命令改名。举例如下: vgrename 旧名称 新名称
对 VG 改名之后,可以用 vgs
命令进行验证。
lvrename VG名称 LV旧名称 LV新名称
对 LV 改名之后,可以用 lvs
命令进行验证。
pvdisplay
命令分别看一下这3个 PV,评估空间的使用情况。 步骤2 假如你评估之后,另2个 PV 的剩余空间足够,就可以考虑用如下方式迁移。 pvmove /dev/sda1
(注:上述命令会智能地判断 sda1 属于哪个 VG,并把它的数据转移到【同一个 VG】的其它 PV)
如果你想手动干预。比如说:你想要指定 sda1 的数据全都转移到 sdb2,可以用如下命令:pvmove /dev/sda1 /dev/sdb2
(注:上述命令的前提是:sdb2 有足够的剩余空间来容纳 sda1 已存储的数据)
步骤3 完成上述步骤之后,再执行如下命令,那么这个 VG 就【不再】包含 sda1 了。vgreduce VG_XXX /dev/sda1步骤4 完成上述命令之后,sda1 也不再属于任何 VG 了。但 sda1 还是会被 Linux 内核当成 PV 来看待。前面聊
pvcreate
的时候,俺说过:pvcreate
命令会往设备头部写入一个 LVM 的标志。 如果你要把这个 sda1 设备拿去作其它用途,不希望它继续被内核当作 PV,可以用如下命令清除该设备头部的 LVM 标志。 pvremove /dev/sda1
反之,如果你要把这个 PV 拿去给别的 VG 使用,就【不】需要执行上述 pvremove
命令。
VG_XXX
,LV 的名称是 lv_xxxx
步骤1 为了保险起见,在做这个操作之前,先备份 LV 相关的数据。 步骤2 用 umount
命令卸载 LV 对应的文件系统。 步骤3 用如下命令先检查一下文件系统,以防万一。 e2fsck -f /dev/VG_XXX/lv_xxxx步骤4 用如下命令收缩文件系统的存储空间。在以下例子中,把存储空间降低到 25GB。
resize2fs /dev/VG_XXX/lv_xxxx 25G
(再次提醒:resize2fs
命令仅用于 ext 家族的文件系统)
lvreduce -L 25G /dev/VG_XXX/lv_xxxx
umount
命令卸载 LV 之上的文件系统(挂载点) 步骤2 假设该 LV 名叫 lv_xxxx
,VG 名叫 VG_XXX
,先用如下命令使之处于【不激活】状态。 lvchange -an /dev/VG_XXX/lv_xxxx步骤3 最后用如下命令彻底删除该 LV。
lvremove /dev/VG_XXX/lv_xxxx
vmware 中添加一块硬盘
可以看到新添加了一块大小为5G的磁盘 sdb,type为disk为磁盘
[root@localhost ~]# lsblkNAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINTsda 8:0 0 20G 0 disk ├─sda1 8:1 0 1G 0 part /boot└─sda2 8:2 0 19G 0 part ├─rhel-root 253:0 0 17G 0 lvm / └─rhel-swap 253:1 0 2G 0 lvm [SWAP]sdb 8:16 0 5G 0 disk sr0 11:0 1 3.8G 0 rom
1、将物理磁盘格式化为物理卷[root@localhost /]# pvcrate /dev/sdsda sda1 sda2 sdb [root@localhost /]# pvcreate /dev/sdb Physical volume "/dev/sdb" successfully created.2、创建卷组,将PV加入卷组[root@localhost /]# vgcreate ninesunvg /dev/sdb Volume group "ninesunvg" successfully created3、基于卷组创建逻辑卷[root@localhost /]# lvcreate -n mylv -L 2G ninesunvg Logical volume "mylv" created.4、为创建好的逻辑卷创建文件系统[root@localhost /]# mkfs.xfs /dev/ninesunvg/mylv meta-data=/dev/ninesunvg/mylv isize=512 agcount=4, agsize=131072 blks = sectsz=512 attr=2, projid32bit=1 = crc=1 finobt=0, sparse=0data = bsize=4096 blocks=524288, imaxpct=25 = sunit=0 swidth=0 blksnaming =version 2 bsize=4096 ascii-ci=0 ftype=1log =internal log bsize=4096 blocks=2560, version=2 = sectsz=512 sunit=0 blks, lazy-count=1realtime =none extsz=4096 blocks=0, rtextents=05、将格式化好的文件系统挂载使用[root@localhost /]# mount /dev/ninesunvg/mylv /datamount: mount point /data does not exist注意需要挂载到一个已经存在的挂载点[root@localhost /]# mount /dev/ninesunvg/mylv /data[root@localhost /]# df -hTFilesystem Type Size Used Avail Use% Mounted on/dev/mapper/rhel-root xfs 17G 3.7G 14G 22% /devtmpfs devtmpfs 897M 0 897M 0% /devtmpfs tmpfs 912M 0 912M 0% /dev/shmtmpfs tmpfs 912M 9.0M 903M 1% /runtmpfs tmpfs 912M 0 912M 0% /sys/fs/cgroup/dev/sda1 xfs 1014M 179M 836M 18% /boottmpfs tmpfs 183M 28K 183M 1% /run/user/1000/dev/mapper/ninesunvg-mylv xfs 2.0G 33M 2.0G 2% /data
1、查看pv信息pvdisplaypvs[root@localhost /]# pvs PV VG Fmt Attr PSize PFree /dev/sda2 rhel lvm2 a-- <19.00g 0 /dev/sdb ninesunvg lvm2 a-- <5.00g <3.00g2、查看vg信息vgdisplayvgs[root@localhost /]# vgs VG #PV #LV #SN Attr VSize VFree ninesunvg 1 1 0 wz--n- <5.00g <3.00g rhel 1 2 0 wz--n- <19.00g 0 3、查看lv信息lvdisplay(详细)lvs[root@localhost /]# lvs LV VG Attr LSize Pool Origin Data% Meta% Move Log Cpy%Sync Convert mylv ninesunvg -wi-ao---- 2.00g root rhel -wi-ao---- <17.00g swap rhel -wi-ao---- 2.00g 4、删除一个lvm步骤 注意顺序不能打乱 1、删除lv 2、删除vg 3、删除物理卷
1、保证vg中有足够的空间
[root@localhost data]# vgs VG #PV #LV #SN Attr VSize VFree ninesunvg 1 1 0 wz--n- <5.00g <3.00g rhel 1 2 0 wz--n- <19.00g 0 [root@localhost data]# lvs LV VG Attr LSize Pool Origin Data% Meta% Move Log Cpy%Sync Convert mylv ninesunvg -wi-ao---- 2.00g root rhel -wi-ao---- <17.00g swap rhel -wi-ao---- 2.00g
2、 扩充逻辑分区
[root@localhost data]# lvextend -L +1G /dev/ninesunvg/mylv Size of logical volume ninesunvg/mylv changed from 2.00 GiB (512 extents) to 3.00 GiB (768 extents). Logical volume ninesunvg/mylv successfully resized.
3、查看扩充后的lv大小
可以看到已经扩充为3G了,切挂载点还在且数据没有丢失,可正常访问。
[root@localhost data]# lvs LV VG Attr LSize Pool Origin Data% Meta% Move Log Cpy%Sync Convert mylv ninesunvg -wi-ao---- 3.00g root rhel -wi-ao---- <17.00g swap rhel -wi-ao---- 2.00g [root@localhost data]# mount|grep mylv/dev/mapper/ninesunvg-mylv on /data type xfs (rw,relatime,seclabel,attr2,inode64,noquota)
4、为何df -hT的空间没有变化呢?
[root@localhost data]# df -hT|grep data/dev/mapper/ninesunvg-mylv xfs 2.0G 33M 2.0G 2% /data
逻辑卷属于底层的东西,操作系统要使用底层的空间都需要对其格式化,即必须要创建文件系统。
文件系统创建的时候大小已经固定了,mulv此文件系统创建好就是2G,拉伸了底层的空间,但是并没有更新其文件系统,这里需要格外注意没有更新mylv xfs这个文件系统。此时需要更新一下文件系统,请注意 xfs 格式化是需要xfs_growfs.
[root@localhost /]# resize2fs /dev/ninesunvg/mylv resize2fs 1.42.9 (28-Dec-2013)resize2fs: Bad magic number in super-block while trying to open /dev/ninesunvg/mylvCouldn't find valid filesystem superblock.[root@localhost /]# [root@localhost /]# xfs_growfs /dev/ninesunvg/mylv meta-data=/dev/mapper/ninesunvg-mylv isize=512 agcount=4, agsize=131072 blks = sectsz=512 attr=2, projid32bit=1 = crc=1 finobt=0 spinodes=0data = bsize=4096 blocks=524288, imaxpct=25 = sunit=0 swidth=0 blksnaming =version 2 bsize=4096 ascii-ci=0 ftype=1log =internal bsize=4096 blocks=2560, version=2 = sectsz=512 sunit=0 blks, lazy-count=1realtime =none extsz=4096 blocks=0, rtextents=0data blocks changed from 524288 to 786432[root@localhost /]#
如果是ext4 则使用resize2fs
[root@P1QMSPGPM01 mapper]# resize2fs /dev/rootvg/optlv resize2fs 1.41.12 (17-May-2010)Filesystem at /dev/rootvg/optlv is mounted on /opt; on-line resizing requiredold desc_blocks = 1, new_desc_blocks = 1Performing an on-line resize of /dev/rootvg/optlv to 3145728 (4k) blocks.The filesystem on /dev/rootvg/optlv is now 3145728 blocks long.
此时df 查看就变成3G了
[root@localhost /]# df -hT|grep data/dev/mapper/ninesunvg-mylv xfs 3.0G 33M 3.0G 2% /data
实际上拉伸逻辑卷的原理就是将所属VG新的PE添加到LV中。
-----实战
root@P1QMSPL2RTM01 rootvg]# lvextend -L +10G /dev/rootvg/homelv Size of logical volume rootvg/homelv changed from 5.00 GiB (1280 extents) to 15.00 GiB (3840 extents). Logical volume homelv successfully resized[root@P1QMSPL2RTM01 rootvg]# df -hFilesystem Size Used Avail Use% Mounted on/dev/mapper/rootvg-rootlv 4.8G 429M 4.2G 10% /tmpfs 158G 0 158G 0% /dev/shm/dev/sda2 477M 33M 419M 8% /boot/dev/sda1 500M 272K 500M 1% /boot/efi/dev/mapper/rootvg-homelv 4.8G 4.4G 233M 95% /home/dev/mapper/rootvg-optlv 15G 5.4G 8.6G 39% /opt/dev/mapper/rootvg-tmplv 4.8G 12M 4.6G 1% /tmp/dev/mapper/rootvg-usrlv 9.8G 3.1G 6.2G 34% /usr/dev/mapper/rootvg-locallv 3.9G 1.6G 2.2G 43% /usr/local/dev/mapper/rootvg-varlv 4.8G 345M 4.3G 8% /var/dev/mapper/rootvg-aploglv1 20G 44M 19G 1% /aplog/dev/mapper/rootvg-datalv 9.8G 30M 9.2G 1% /data/dev/mapper/rootvg-redislv 818G 288G 489G 38% /redis[root@P1QMSPL2RTM01 rootvg]# resize2fs /dev/rootvg/homelv resize2fs 1.41.12 (17-May-2010)Filesystem at /dev/rootvg/homelv is mounted on /home; on-line resizing requiredold desc_blocks = 1, new_desc_blocks = 1Performing an on-line resize of /dev/rootvg/homelv to 3932160 (4k) blocks.The filesystem on /dev/rootvg/homelv is now 3932160 blocks long.[root@P1QMSPL2RTM01 rootvg]# df -hFilesystem Size Used Avail Use% Mounted on/dev/mapper/rootvg-rootlv 4.8G 429M 4.2G 10% /tmpfs 158G 0 158G 0% /dev/shm/dev/sda2 477M 33M 419M 8% /boot/dev/sda1 500M 272K 500M 1% /boot/efi/dev/mapper/rootvg-homelv 15G 4.4G 9.6G 32% /home/dev/mapper/rootvg-optlv 15G 5.4G 8.6G 39% /opt/dev/mapper/rootvg-tmplv 4.8G 12M 4.6G 1% /tmp/dev/mapper/rootvg-usrlv 9.8G 3.1G 6.2G 34% /usr/dev/mapper/rootvg-locallv 3.9G 1.6G 2.2G 43% /usr/local/dev/mapper/rootvg-varlv 4.8G 345M 4.3G 8% /var/dev/mapper/rootvg-aploglv1 20G 44M 19G 1% /aplog/dev/mapper/rootvg-datalv 9.8G 30M 9.2G 1% /data/dev/mapper/rootvg-redislv 818G 288G 489G 38% /redisYou have new mail in /var/spool/mail/root
-----实战
vg空间足时,就需要拉伸一个vg,如果有新的硬盘,可进行pv 然后把pv 加入到vg中。
1、将要添加的vg 格式化为PV
pv create /dev/sdc
2、将新的PV添加到指定的VG什么时候会用到该操作呢?
vgextend vgname /dev/sdc
例如线上服务磁盘空间不足了,逻辑卷又没有剩余空间了,这时就可以选择拉伸逻辑卷。注意该操作是online的。前提时必须个有空闲的硬盘。
如下图就是实际业务中,/redis 目录被撑爆了,但是vg 又没了,只能offline加硬盘上去。也有前辈实践过online加硬盘
TODO
2020年8月9日13:59:09
在网上看到对新增硬盘上做lvm,都会先将磁盘用分区,然后再使用呢?不分区也能使用呀,例如上面 “pv vg lv详细步骤” 这个操作就是直接在裸硬盘上操作的,操作完全没有问题。
lvm本身支持直接硬盘 raid 和分区。但是这会埋下不安全的隐患。
摘自知乎:https://www.zhihu.com/question/30609658/answer/52253948
主要是安全性考虑。给硬盘分区就是宣布了“这个硬盘已经在用了”。因为大部分软件都默认你的硬盘是存在MBR的,如果找不到MBR可能就会有未定义行为。有的软件还可能自作主张的给你创建一个MBR,因为它觉得你这个硬盘是全新的。有的人看到只有sda没有sda1也可能自作主张给分区,比如说这个
如果你的电脑只有自己在维护,原则上应该还是很安全的,我还没碰到那种自作主张的奇芭软件。多年来一直是把LUKS直接建立在sda上,然后在LUKS里做LVM。
看到这里就知道埋下什么不安全的隐患了,以后还是按照正常硬盘分区,再做LVM。
转载地址:http://hshqj.baihongyu.com/