一文搞懂LVM软RAID

409 阅读8分钟

LVM

LVM简介

LVM利用Linux内核的device-mapper功能来实现存储系统的虚拟化(系统分区独立于底层硬件)。 通过LVM,你可以实现存储空间的抽象化并在上面建立虚拟分区(virtual partitions),可以更简便地扩大和缩小分区,可以增删分区时无需担心某个硬盘上没有足够的连续空间,避免为正在使用的磁盘重新分区的麻烦、为调整分区而不得不移动其他分区的不便。

PV --> VG --> LV

image-20220208234228958.png

  • Physical Volumes 一个可供存储LVM的块设备,通过pvdisplay查看
  • Volume Groups 物理卷的一个组,作为存放逻辑卷的容器,通过vgdisplay查看
  • Logical Volumes "虚拟/逻辑卷"存放在一个卷组中并由物理块组成。包含一个文件系统,通过lvdisplay查看

优点

比起普通的硬盘分区管理方式,LVM更富于灵活性:

  • 将多块硬盘看作一块大硬盘
  • 使用逻辑卷(LV),可以创建跨越众多硬盘空间的分区。
  • 可以创建小的逻辑卷(LV),在空间不足时再动态调整它的大小。
  • 在调整逻辑卷(LV)大小时可以不用考虑逻辑卷在硬盘上的位置,不用担心没有可用的连续空间。
  • 可以在线(online)对逻辑卷(LV)和卷组(VG)进行创建、删除、调整大小等操作。不过LVM上的文件系统也需要重新调整大小,好在某些文件系统(例如ext4)也支持在线操作。
  • 无需重新启动服务,就可以将服务中用到的逻辑卷(LV)在线(online)/动态(live)迁移至别的硬盘上。
  • 允许创建快照,可以保存文件系统的备份,同时使服务的下线时间(downtime)降低到最小。
  • 支持各种设备映射目标(device-mapper targets),包括透明文件系统加密和缓存常用数据(caching of frequently used data)。这将允许你创建一个包含一个或多个磁盘、并用LUKS加密的系统,使用LVM on top 可轻松地管理和调这些整独立的加密卷 (例如. /, /home, /backup等) 并免去开机时多次输入密钥的麻烦。
任务PV 阶段VG 阶段LV 阶段
搜寻(scan)pvscanvgscanlvscan
建立(create)pvcreatevgcreatelvcreate
列出(display)pvdisplayvgdisplaylvdisplay
增加(extend)vgextendlvextend (lvresize)
减少(reduce)vgreducelvreduce (lvresize)
删除(remove)pvremovevgremovelvremove
改变容量(resize)lvresize
改变属性(attribute)pvchangevgchangelvchange

LVM的3种模式

查看方式

$ sudo lvs -v --segments
  LV                                          VG           Attr       Start    SSize    #Str Type   Stripe Chunk
  volume-27a3eb5e-2e9d-40c3-a64a-95cd511d59b1 vg_lvm_local -wi-ao----       0     1.17t    1 linear     0     0
  volume-30b00dff-4236-44f6-86ca-ed9daf27e514 vg_lvm_local -wi-ao----       0     1.07t    1 linear     0     0
$ lvdisplay -m
  --- Logical volume ---
  LV Path                /dev/vg_lvm_local/volume-fc98bca6-dfb1-4684-a9b8-160a3901c1e6
  LV Name                volume-fc98bca6-dfb1-4684-a9b8-160a3901c1e6
  VG Name                vg_lvm_local
  LV UUID                JJTdTc-OaiN-KXPY-zETE-GBKE-kDhN-tROu1k
  LV Write Access        read/write
  LV Creation host, time prit2-nova-xxx.org, 2022-03-23 18:29:56 +0800
  LV Status              available
  # open                 1
  LV Size                1000.00 GiB
  Current LE             256000
  Segments               1
  Allocation             inherit
  Read ahead sectors     auto
  - currently set to     256
  Block device           254:1

  --- Segments ---
  Logical extents 0 to 255999:
    Type                linear
    Physical volume     /dev/nvme1n1
    Physical extents    0 to 255999

Linear(线性模式)

PV 是按顺序填充的,而不是并行填充的。因此,如果一个 VG 由 4 个 PV 组成,并且使用整个 VG 资源创建了一个线性 LV,则将填充第一个 PV,然后是第二个,然后是第三个,然后是第四个。

# -l 50%VG vg大小的一半
lvcreate -l 100%FREE --name lvm1 vg_lvm_local

Mirror(镜像模式)

镜像 LV 通过一个或多个副本提供容错。最低配置是两个镜像 LV。每个镜像将由不同 PV 上的物理范围(总计 LV 的指定大小)组成。如果一个镜像发生故障,那么好的镜像仍然可用,使包含在其中的文件系统或交换设备保持运行。

# -m 1镜像
lvcreate -L 5G -m1 -n mirrlv1 vg_lvm_local

Stripe(条带模式)

条带化 LV 通过跨多个 PV 分布数据来提供改进的性能。条带单元定义一次向每个 PV 写入多少数据,并且在 PV 之间交替写入。

# -L size,-i 2条带,-I 条带大小64K, -n lv名字
lvcreate -L 5G -i2 -I64 -n strlv1 vg_lvm_local

LVM创建

# 查看可被用作物理卷的设备
lvmdiskscan
# 创建物理卷
pvcreate /dev/sdb
# 查看物理卷
pvdisplay

# 创建卷组vg_lvm_local
vgcreate vg_lvm_local /dev/sdb /dev/sdc
# 查看卷组
vgdisplay

# 创建逻辑卷 lvcreate -L <卷大小> <卷组名> -n <卷名> <指定物理卷>
lvcreate -L 4Tp -n mirror_vg vg_lvm_local
lvcreate -l +100%FREE one_data vg_lvm_local
# lv扩容
lvresize -r -l +100%FREE /dev/vg_lvm_local/one_data

# 查看逻辑卷
root@pri2-sa2:~# pvs
  PV         VG           Fmt  Attr PSize PFree
  /dev/sdc   vg_lvm_local lvm2 a--  3.27t    0
  /dev/sde   vg_lvm_local lvm2 a--  3.27t 2.55t
root@pri2-sa2:~# vgs
  VG           #PV #LV #SN Attr   VSize VFree
  vg_lvm_local   2   1   0 wz--n- 6.55t 2.55t
root@pri2-sa2:~# lvs
  LV        VG           Attr     LSize Pool Origin Data%  Move Log Copy%  Convert
  mirror_vg vg_lvm_local -wi-a--- 4.00t

# 使用
mkfs.ext4 /dev/mapper/vg_lvm_local-mirror_vg
mount /dev/mapper/VolGroup00-lvolhome /data-mirror

vg扩容 添加物理卷到卷组中

首先创建一个新的物理卷,再把卷组扩充到该物理卷上(扩容可以不需要创建分区)

pvcreate /dev/sdb
vgextend VolGroup00 /dev/sdb

lv扩容

将MyVolGroup组中的逻辑卷mediavol扩大10GiB,并同时扩大其文件系统

lvresize -L +10G --resizefs MyVolGroup/mediavol
lvresize -l +100%FREE --resizefs MyVolGroup/mediavol

快照

LVM可以给系统创建一个快照,由于使用了写入时复制(copy-on-write) 策略,相比传统的备份更有效率。

只要你修改的数据(包括原始的和快照的)不超过2G,你就可以只使用2G的空间对一个有35G数据的系统创建快照。

# 创建
lvcreate --size 100M --snapshot --name snap01 /dev/vg0/lv
# 恢复
lvconvert --merge /dev/vg0/snap01

Debug

$ pvs
WARNING: Device /dev/sdc has size of xxx sectors which is smaller than corresponding PV size of xxx sectors. Was device resized?
LVM : One or more devices used as PVs in VG have changed sizes\

$ vgcfgrestore vg_lvm_local
# pvresize --setphysicalvolumesize 6249119744S /dev/sdc

unknown的pvs

$ pvs
  Error reading device /dev/disk/by-id/dm-name-k8svg-pvc--138b9f23--8778--11ea--a977--fa163e934a44 at 0 length 512.
  Error reading device /dev/disk/by-id/dm-name-k8svg-pvc--138b9f23--8778--11ea--a977--fa163e934a44 at 0 length 4096.
  Couldn't find device with uuid 9dI6CR-zfdB-Axl8-SygA-ILS9-IOwH-t6UGeh.
  PV         VG    Fmt  Attr PSize  PFree
  /dev/sdb   k8svg lvm2 a--  <1.75t       0
  /dev/sdr   k8svg lvm2 a--  <1.75t   <1.75t
  [unknown]  k8svg lvm2 a-m  <1.75t       0
$ lvs -o +devices
  LV                                       VG    Attr       LSize   Pool Origin Data%  Meta%  Move Log Cpy%Sync Convert Devices
  pvc-1370e87c-8778-11ea-a977-fa163e934a44 k8svg -wi-ao---- 100.00g                                                     /dev/sdb(0)
  pvc-1391a6cf-8778-11ea-a977-fa163e934a44 k8svg -wi-ao----   5.40t                                                     /dev/sdk(0)
  pvc-1391a6cf-8778-11ea-a977-fa163e934a44 k8svg -wi-ao----   5.40t                                                     /dev/sdn(0)
  pvc-4b1e8a5f-50ea-11ec-a5df-fa163e934a44 k8svg -wi-ao----   5.40t                                                     /dev/sdd(0)
  pvc-4b1e8a5f-50ea-11ec-a5df-fa163e934a44 k8svg -wi-ao----   5.40t                                                     /dev/sdl(340105)
# 修复
$ vgreduce --removemissing --force k8svg

lvm损坏

# 清理
$ rm /dev/k8svg/pvc-83af62e6-f181-11ea-8e27-e4434b4d0fb6
$ rmdir /dev/k8svg/
$ rm /dev/mapper/k8svg-pvc--83af62e6-f181-11ea-8e27-e4434b4d0fb6
# lsblk有报错
$ lsblk
lsblk: dm-0: failed to get device path
lsblk: dm-1: failed to get device path
lsblk: dm-2: failed to get device path
# 删除对应id的pvc
$ sudo dmsetup ls
k8svg-pvc--892a01f6--a083--11ed--b667--e4434b4d0fb6	(253:6)
k8svg-pvc--892600a1--a083--11ed--b667--e4434b4d0fb6	(253:4)
k8svg-pvc--83af62e6--f181--11ea--8e27--e4434b4d0fb6	(253:0)
k8svg-pvc--8927e9e8--a083--11ed--b667--e4434b4d0fb6	(253:5)
k8svg-pvc--e1ed1610--a083--11ed--b667--e4434b4d0fb6	(253:8)
k8svg-pvc--83c0e4c7--f181--11ea--8e27--e4434b4d0fb6	(253:2)
k8svg-pvc--83b97a09--f181--11ea--8e27--e4434b4d0fb6	(253:1)
k8svg-pvc--8917203e--a083--11ed--b667--e4434b4d0fb6	(253:3)
k8svg-pvc--b108dcb5--a083--11ed--b667--e4434b4d0fb6	(253:7)
$ sudo dmsetup remove k8svg-pvc--83af62e6--f181--11ea--8e27--e4434b4d0fb6 # 253:0
$ sudo dmsetup remove k8svg-pvc--83b97a09--f181--11ea--8e27--e4434b4d0fb6 # 253:1
$ sudo dmsetup remove k8svg-pvc--83c0e4c7--f181--11ea--8e27--e4434b4d0fb6 # 253:2