跳转至内容

LVM

来自 ArchWiki
(重定向自 LVM2)

来自 维基百科:逻辑卷管理器 (Linux)

逻辑卷管理器 (LVM) 是一个 device mapper 框架,为 Linux 内核提供逻辑卷管理功能。

背景

LVM 组成要素

逻辑卷管理利用内核的 device-mapper 特性,提供一套独立于底层磁盘布局的分区系统。通过 LVM,您可以抽象化存储并拥有“虚拟分区”,使扩容/缩减更加容易(受限于潜在的文件系统限制)。

虚拟分区允许添加和删除,而无需担心特定磁盘上是否有足够的连续空间、无需在磁盘使用中陷入 fdisk 操作(并怀疑内核是否在使用旧的或新的分区表),也无需为了挪出空间而移动其他分区。

LVM 的基本组成要素

物理卷 (PV)
Unix 块设备节点,可供 LVM 用于存储。例如:硬盘、MBRGPT 分区、回环文件、device mapper 设备(如 dm-crypt)。它承载 LVM 头部。
卷组 (VG)
PV 的组合,作为 LV 的容器。PE 从 VG 中分配给 LV。
逻辑卷 (LV)
位于 VG 中并由 PE 组成的“虚拟/逻辑分区”。LV 是类似于物理分区的 Unix 块设备,例如,它们可以直接格式化为 文件系统
物理范围 (PE)
PV 中可分配给 LV 的最小连续范围(默认 4 MiB)。可以将 PE 看作是可以分配给任何 LV 的 PV 组成部分。

示例

Physical disks

  Disk1 (/dev/sda):
    ┌──────────────────────────────────────┬─────────────────────────────────────┐
    │ Partition1  50 GiB (Physical volume) │ Partition2 80 GiB (Physical volume) │
    │ /dev/sda1                            │ /dev/sda2                           │
    └──────────────────────────────────────┴─────────────────────────────────────┘

  Disk2 (/dev/sdb):
    ┌──────────────────────────────────────┐
    │ Partition1 120 GiB (Physical volume) │
    │ /dev/sdb1                            │
    └──────────────────────────────────────┘
LVM logical volumes

  Volume Group1 (/dev/MyVolGroup/ = /dev/sda1 + /dev/sda2 + /dev/sdb1):
    ┌─────────────────────────┬─────────────────────────┬──────────────────────────┐
    │ Logical volume1 15 GiB  │ Logical volume2 35 GiB  │ Logical volume3 200 GiB  │
    │ /dev/MyVolGroup/rootvol │ /dev/MyVolGroup/homevol │ /dev/MyVolGroup/mediavol │
    └─────────────────────────┴─────────────────────────┴──────────────────────────┘
注意: 逻辑卷可以通过 /dev/卷组名/逻辑卷名/dev/mapper/卷组名-逻辑卷名 访问。然而,lvm(8) § VALID NAMES 建议“软件和脚本”(如 fstab)使用前者格式,因为后者旨在供“内部使用”,且可能在“版本和发行版之间发生变化”。

优点

相比于仅使用普通的硬盘分区,LVM 为您提供了更多的灵活性:

  • 可以将任意数量的磁盘当作一个大磁盘使用。
  • 可以让逻辑卷跨越多个磁盘(RAID、镜像、条带化,这些提供了额外的弹性与性能优势 [1])。
  • 创建较小的逻辑卷,并在它们填满时“动态地”调整大小。
  • 调整逻辑卷大小不受其在磁盘上顺序的影响。它不依赖于 LV 在 VG 中的位置,无需确保周围有可用空间。
  • 在线调整/创建/删除逻辑卷和物理卷。其中的文件系统仍需调整大小,但部分文件系统(如 Ext4Btrfs)支持在线调整大小。
  • 可以将服务正在使用的 LV(或段)在线/实时迁移到不同磁盘,而无需重启服务。
  • 快照功能允许您备份文件系统的冻结副本,同时将服务停机时间降至最低,并可在稍后轻松将快照合并回原始卷。
  • 支持解锁独立卷,而无需在启动时多次输入密钥(在 LUKS 之上构建 LVM)。
  • 内置对常用数据缓存的支持 (lvmcache(7))。

缺点

  • 系统设置中增加了额外步骤(可能需要更改 mkinitcpio 配置),更加复杂。需要(多个)守护进程持续运行。
  • 如果是双系统,请注意 Windows 不支持 LVM;您将无法从 Windows 访问任何 LVM 分区。第三方软件可能允许挂载某些类型的 LVM 设置。[2]
  • 如果您的物理卷不在 RAID-1、RAID-5 或 RAID-6 上,那么如果您将逻辑卷跨越(或扩展)到多个非冗余磁盘,丢失一个磁盘可能会导致丢失一个或多个逻辑卷。
  • 缩减逻辑卷管理器占用的空间(即用于逻辑卷的物理卷)并不总是那么容易。如果物理范围分散在物理卷中直到末尾,您可能需要检查段并移动它们(可能移动到另一个物理设备)或移动到具有自定义分配设置(例如 --alloc anywhere)的同一设备。如果您想与其他操作系统(例如 Microsoft Windows)双启动,设备上留给 Microsoft Windows 的唯一空间是 LVM 未使用的空间/未作为物理卷使用的空间。
  • 性能可能比使用普通分区差。[3]
  • 可能无法与所有文件系统很好地协作,尤其是那些设计为感知(多)设备的文件系统。例如,Btrfs 提供了一些相同的功能(多设备支持(子)卷、快照和 RAID),这可能会产生冲突(进一步了解 Btrfs 在 LVM 快照方面的相关问题)。

安装

确保已安装 lvm2 软件包。

如果您有未通过 initramfs 激活的 LVM 卷,请启用 lvm2-monitor.service,该服务由 lvm2 软件包提供。

卷操作

物理卷

创建

要在 /dev/sda1 上创建 PV,运行:

# pvcreate /dev/sda1

您可以使用以下命令检查 PV 是否已创建:

# pvs

扩容

在扩展承载物理卷的设备之后或缩小该设备之前,您需要使用 pvresize(8) 来增加或缩小 PV。

要在扩大分区后扩展 /dev/sda1 上的 PV,运行:

# pvresize /dev/sda1

这将自动检测设备的新大小并将 PV 扩展到其最大值。

注意: 此命令可以在卷在线时执行。

缩减

要在缩小底层设备之前缩小物理卷,请在命令中添加 --setphysicalvolumesize 大小 参数,例如:

# pvresize --setphysicalvolumesize 40G /dev/sda1

上述命令可能会提示以下错误:

/dev/sda1: cannot resize to 25599 extents as later ones are allocated.
0 physical volume(s) resized / 1 physical volume(s) not resized

确实,如果 PV 在其新末尾之后分配了范围,pvresize 将拒绝缩小该 PV。如果有足够的空闲空间,需要在事先运行 pvmove 将这些范围重新定位到卷组中的其他位置。

移动物理范围

在释放卷末尾的物理范围之前,必须运行 pvdisplay -v -m 来查看它们。另一种以表格形式查看段的方法是 pvs --segments -v

在以下示例中,/dev/sdd1 上有一个物理卷,一个卷组 vg1 和一个逻辑卷 backup

# pvdisplay -v -m
    Finding all volume groups.
    Using physical volume(s) on command line.
  --- Physical volume ---
  PV Name               /dev/sdd1
  VG Name               vg1
  PV Size               1.52 TiB / not usable 1.97 MiB
  Allocatable           yes 
  PE Size               4.00 MiB
  Total PE              399669
  Free PE               153600
  Allocated PE          246069
  PV UUID               MR9J0X-zQB4-wi3k-EnaV-5ksf-hN1P-Jkm5mW
   
  --- Physical Segments ---
  Physical extent 0 to 153600:
    FREE
  Physical extent 153601 to 307199:
    Logical volume	/dev/vg1/backup
    Logical extents	1 to 153599
  Physical extent 307200 to 307200:
    FREE
  Physical extent 307201 to 399668:
    Logical volume	/dev/vg1/backup
    Logical extents	153601 to 246068

可以观察到 FREE 空间分布在整个卷中。要缩小物理卷,我们必须首先将所有使用的段移至开头。

这里,第一个空闲段是从 0 到 153600,留给我们 153601 个空闲范围。我们现在可以将这个段号从最后一个物理范围移动到第一个物理范围。命令如下:

# pvmove --alloc anywhere /dev/sdd1:307201-399668 /dev/sdd1:0-92467
/dev/sdd1: Moved: 0.1 %
/dev/sdd1: Moved: 0.2 %
...
/dev/sdd1: Moved: 99.9 %
/dev/sdd1: Moved: 100.0 %
  • 此命令将 399668 - 307201 + 1 = 92468 个 PE 最后一个段移动到第一个段。这是可能的,因为第一个段包含 153600 个空闲 PE,可以容纳 92467 - 0 + 1 = 92468 个移动的 PE。
  • 由于我们在同一个分区内移动 PE,因此使用 --alloc anywhere 选项。如果是不同的分区,命令将类似于:
    # pvmove /dev/sdb1:1000-1999 /dev/sdc1:0-999
  • 对于大型卷,此命令可能需要很长时间(一到两个小时)。建议在 tmuxGNU Screen 会话中运行此命令。任何意外的进程停止都可能是致命的。
  • 操作完成后,运行 fsck 以确保您的文件系统有效。
调整物理卷大小

一旦所有空闲物理段都位于最后的物理范围上,请以 root 权限运行 vgdisplay 并查看您的空闲 PE。

然后您可以再次运行命令:

# pvresize --setphysicalvolumesize size PhysicalVolume

查看结果:

# pvs
  PV         VG   Fmt  Attr PSize    PFree 
  /dev/sdd1  vg1  lvm2 a--     1t     500g
调整分区大小

最后,您需要使用您喜欢的分区工具来缩小分区。

卷组

创建卷组

要创建一个包含关联 PV /dev/sdb1 的 VG MyVolGroup,运行:

# vgcreate MyVolGroup /dev/sdb1

您可以使用以下命令检查 VG MyVolGroup 是否已创建:

# vgs

在创建 VG 时可以绑定多个 PV,如下所示:

# vgcreate MyVolGroup /dev/sdb1 /dev/sdb2

激活卷组

注意: 您可以通过在 /etc/lvm/lvm.conf 中设置 auto_activation_volume_list 来限制自动激活的卷。如有疑问,请保留此选项为注释状态。
# vgchange -a y MyVolGroup

默认情况下,这将在适用时重新激活卷组。例如,如果您的镜像中有一个驱动器出现故障,并且您更换了驱动器;并运行了 (1) pvcreate、(2) vgextend 和 (3) vgreduce --removemissing --force

修复卷组

要开始本示例中降级镜像阵列的重建过程,您需要运行:

# lvconvert --repair /dev/MyVolGroup/mirror

您可以使用以下命令监控重建过程(Cpy%Sync 列输出):

# lvs -a -o +devices

停用卷组

只需调用:

# vgchange -a n MyVolGroup

这将停用卷组并允许您卸载存储它的容器。

重命名卷组

使用 vgrename(8) 命令重命名现有的卷组。

以下任一命令都会将现有的卷组 MyVolGroup 重命名为 my_volume_group

# vgrename /dev/MyVolGroup /dev/my_volume_group
# vgrename MyVolGroup my_volume_group

确保更新所有引用重命名后的卷组的配置文件(例如 /etc/fstab/etc/crypttab)。

向卷组添加物理卷

首先在您希望使用的块设备上创建一个新的物理卷,然后扩展您的卷组:

# pvcreate /dev/sdb1
# vgextend MyVolGroup /dev/sdb1

这当然会增加卷组中物理范围的总数,您可以根据需要将其分配给逻辑卷。

注意: 在 LVM 下方的存储介质上保留分区表被认为是一种良好的做法。使用适当的分区类型:MBR 使用 8e,GPT 分区使用 E6D6D379-F507-44C2-A23C-238F2A3DF928gdisk 中的 8e00 类型代码,fdisk 中的 lvm 类型别名)。

从卷组移除分区

如果您在分区上创建了逻辑卷,请先将其移除

该分区上的所有数据都需要移动到另一个分区。幸运的是,LVM 让这变得很容易:

# pvmove /dev/sdb1

如果您希望将数据移动到特定的物理卷,请将其指定为 pvmove 的第二个参数:

# pvmove /dev/sdb1 /dev/sdf1

然后需要从卷组中移除该物理卷:

# vgreduce MyVolGroup /dev/sdb1

或者移除所有空的物理卷:

# vgreduce --all MyVolGroup

例如:如果组中有一个损坏的磁盘,因为已被移除或发生故障而无法找到:

# vgreduce --removemissing --force MyVolGroup

最后,如果您想将该分区用于其他用途,并希望避免 LVM 认为该分区是物理卷:

# pvremove /dev/sdb1

逻辑卷

注意: lvresize(8) 提供的选项与专门的 lvextend(8)lvreduce(8) 命令大致相同,同时允许执行两种类型的操作。尽管如此,所有这些工具都提供 -r/--resizefs 选项,允许使用 fsadm(8) 将文件系统与 LV 一起调整大小(支持 ext2, ext3, ext4, ReiserFSXFS)。因此,简单地使用 lvresize 进行这两种操作并使用 --resizefs 来简化事情可能会更容易,除非您有特定需求或想要完全控制该过程。
警告: 虽然通常可以在线(即在挂载时)扩大文件系统,即使是根分区,但缩小文件系统几乎总是需要先卸载文件系统,以防止数据丢失。请确保您的文件系统支持您尝试执行的操作。
提示: 如果逻辑卷将格式化为 ext4,请在卷组中保留至少 256 MiB 的空闲空间,以便使用 e2scrub(8)。在使用 -l 100%FREE 创建最后一个卷后,可以通过使用 lvreduce -L -256M 卷组/逻辑卷 减小其大小来实现此目的。

创建逻辑卷

要在容量为 300 GiB 的 VG MyVolGroup 中创建 LV homevol,运行:

# lvcreate -L 300G MyVolGroup -n homevol

或者,要在 VG MyVolGroup 中使用剩余容量创建 LV homevol,运行:

# lvcreate -l 100%FREE MyVolGroup -n homevol

要在将 LV 限制在 VG 内特定 PV 的同时创建它,请将它们附加到命令中:

# lvcreate -L 300G MyVolGroup -n homevol /dev/sda1

新的 LV 将显示为 /dev/MyVolGroup/homevol。现在您可以使用适当的文件系统格式化 LV。

您可以使用以下命令检查 LV 是否已创建:

# lvs

重命名逻辑卷

要重命名现有的逻辑卷,请使用 lvrename(8) 命令。

以下任一命令都会将卷组 MyVolGroup 中的逻辑卷 old_vol 重命名为 new_vol

# lvrename /dev/MyVolGroup/old_vol /dev/MyVolGroup/new_vol
# lvrename MyVolGroup old_vol new_vol

确保更新所有引用重命名后的逻辑卷的配置文件(例如 /etc/fstab/etc/crypttab)。

一步调整逻辑卷及文件系统大小

注意: 仅支持 ext2, ext3, ext4, ReiserFSXFS 文件系统。对于其他类型的文件系统,请参见#分别调整逻辑卷及文件系统大小

MyVolGroup 中的逻辑卷 mediavol 扩展 10 GiB,并同时调整其文件系统大小:

# lvresize -L +10G --resizefs MyVolGroup/mediavol

MyVolGroup 中的逻辑卷 mediavol 的大小设置为 15 GiB,并同时调整其文件系统大小:

# lvresize -L 15G --resizefs MyVolGroup/mediavol

如果您想填满卷组上的所有空闲空间,请使用以下命令:

# lvresize -l +100%FREE --resizefs MyVolGroup/mediavol

有关更详细的选项,请参见 lvresize(8)

分别调整逻辑卷及文件系统大小

对于 fsadm(8) 不支持的文件系统,需要在缩小逻辑卷之前或扩展逻辑卷之后,使用适当的工具来调整文件系统的大小。

要在修改文件系统的情况下将卷组 MyVolGroup 内的逻辑卷 mediavol 扩展 2 GiB:

# lvresize -L +2G MyVolGroup/mediavol

现在将文件系统(本例中为 ext4)扩展到其底层逻辑卷的最大大小:

# resize2fs /dev/MyVolGroup/mediavol

对于 Btrfsbtrfs-filesystem(8) 需要挂载点而不是设备,等效操作为:

# btrfs filesystem resize max /mnt/my-mountpoint

要将 MyVolGroup 中的逻辑卷 mediavol 的大小减少 500 MiB,首先计算生成的文件系统大小,并将文件系统(本例中为 Ext4)缩小到新大小:

# resize2fs /dev/MyVolGroup/mediavol NewSize

与 Ext4 不同,Btrfs 支持在线缩小(同样应指定挂载点),例如:

# btrfs filesystem resize -500M /mnt/my-mountpoint

文件系统缩小后,减少逻辑卷的大小:

# lvresize -L -500M MyVolGroup/mediavol

要计算 ext2, ext3, ext4 文件系统的精确逻辑卷大小,请使用简单的公式:LVM_EXTENTS = FS_BLOCKS × FS_BLOCKSIZE ÷ LVM_EXTENTSIZE

# tune2fs -l /dev/MyVolGroup/mediavol | grep Block
Block count:              102400000
Block size:               4096
Blocks per group:         32768
# vgdisplay MyVolGroup | grep "PE Size"
PE Size               4.00 MiB
注意: 文件系统块大小以字节为单位。确保块大小和范围 (extent) 大小使用相同的单位。
102400000 blocks × 4096 bytes/block ÷ 4 MiB/extent = 100000 extents

传递 --resizefs 将确认其正确性。

# lvreduce -l 100000 --resizefs /dev/MyVolGroup/mediavol
...
The filesystem is already 102400000 (4k) blocks long.  Nothing to do!
...
Logical volume sysvg/root successfully resized.

有关更详细的选项,请参见 lvresize(8)

移除逻辑卷

警告: 在移除逻辑卷之前,请确保将您想要保留的所有数据移动到其他地方;否则,数据将会丢失!

首先,找出您要移除的逻辑卷的名称。您可以使用以下命令获取所有逻辑卷的列表:

# lvs

接着,查找所选逻辑卷的挂载点:

$ lsblk

然后卸载逻辑卷上的文件系统:

# umount /mountpoint

最后,移除逻辑卷:

# lvremove volume_group/logical_volume

例如:

# lvremove MyVolGroup/homevol

输入 y 进行确认。

确保更新所有引用已移除逻辑卷的配置文件(例如 /etc/fstab/etc/crypttab)。

您可以再次以 root 身份输入 lvs 来验证逻辑卷的移除情况(参见本节的第一步)。

快照

LVM 支持写时复制 (CoW) 快照。CoW 快照最初指向原始数据。当数据块被覆盖时,原始副本保持不变,新块被写入磁盘的其他位置。这具有几个理想的特性:

  • 创建快照速度很快,因为它不复制数据(仅复制磁盘位置指针的简短列表)。
  • 快照仅需要足够的空闲空间来保存新数据块(加上用于指向新块的指针的极少量空间)。例如,一个 35 GiB 数据的快照,如果您只写入 2 GiB(在原始卷和快照上),则仅需要 2 GiB 的空闲空间。

LVM 快照位于块级别。它们创建了一个新的块设备,除了在处理 LVM 工具时,与原始设备没有明显的关系。因此,删除原始副本中的文件不会释放快照中的空间。如果您需要文件系统级别的快照,则需要 btrfsZFSbcachefs

警告
  • CoW 快照不是备份,因为它没有制作原始数据的第二个副本。例如,影响原始数据的损坏磁盘扇区也会影响快照。也就是说,快照在利用其他工具进行备份时会很有帮助,如下文所述
  • Btrfs 要求不同的文件系统具有不同的 UUID。如果您对包含 btrfs 文件系统的 LVM 卷进行快照,请确保在挂载两者(或使其对内核可见,例如如果无关的守护进程触发 btrfs device scan)之前,更改原始卷或副本的 UUID。有关详细信息,请参阅 btrfs wiki Gotcha's

配置

您可以像创建普通逻辑卷一样创建快照逻辑卷。

# lvcreate --size 100M --snapshot --name snap01vol /dev/MyVolGroup/lvol

对于该卷,在快照卷填满之前,您可以修改少于 100 MiB 的数据。

将修改后的 lvol 逻辑卷恢复到拍摄 snap01vol 快照时的状态,可以使用以下命令:

# lvconvert --merge /dev/MyVolGroup/snap01vol

如果原始逻辑卷处于激活状态,合并将在下次重启时发生(甚至可以从 LiveCD 进行合并)。

注意: 合并后快照将不再存在。

此外,可以拍摄多个快照,并且每个快照都可以根据需要与原始逻辑卷合并。

备份

快照提供文件系统的冻结副本以进行备份。例如,耗时两小时的备份比直接备份分区提供更一致的文件系统镜像。

快照可以挂载并使用 ddtar 进行备份。使用 dd 制作的备份文件的大小将是快照卷上文件的大小。要恢复,只需创建一个快照,挂载它,然后将备份写入或解压到其中,接着将其与原始卷合并。

参见 使用 LVM 创建根文件系统快照,了解如何在系统启动期间自动创建干净的根文件系统快照,以便进行备份和回滚。

本文章或章节需要扩充。

原因: 展示在更新前自动制作根快照、回滚... 更新 menu.lst 以启动快照的脚本(也许放在单独的文章中?)(在 Talk:LVM 中讨论)

加密

参见 dm-crypt/加密整个系统#LVM 上的 LUKSdm-crypt/加密整个系统#LUKS 上的 LVM,了解 LUKS 与 LVM 结合的可能方案。

缓存

本文章或章节需要扩充。

原因: LVM 还支持使用 dm-writecache 的 --type writecache。(在 Talk:LVM 中讨论)

来自 lvmcache(7)

缓存逻辑卷类型使用一个小而快的 LV 来提高大而慢的 LV 的性能。它通过在较快的 LV 上存储常用块来实现这一点。LVM 将小而快的 LV 称为缓存池 LV。大而慢的 LV 称为原始 LV。由于 dm-cache(内核驱动程序)的要求,LVM 将缓存池 LV 进一步拆分为两个设备:缓存数据 LV 和缓存元数据 LV。缓存数据 LV 用于保存原始 LV 的数据块副本以提高速度。缓存元数据 LV 保存记账信息,指定数据块的存储位置(例如,在原始 LV 上还是在缓存数据 LV 上)。如果用户希望创建最佳且最健壮的缓存逻辑卷,应熟悉这些 LV。所有这些关联的 LV 必须位于同一个 VG 中。

创建缓存

将您的快速磁盘 (/dev/fastdisk) 转换为 PV 并添加到现有的 VG (MyVolGroup):

# vgextend MyVolGroup /dev/fastdisk

使用缓存逻辑卷

/dev/fastdisk 上创建一个带有自动元数据的缓存逻辑卷,并将现有的 LV MyVolGroup/rootvol 转换为缓存 LV,一步完成:

# lvcreate --type cache --cachemode writethrough -l 100%FREE -n root_cachevol MyVolGroup/rootvol /dev/fastdisk
提示: 您可以使用 -L 20G 仅为 cachevol 分配 20 GiB,而不是使用 -l 100%FREE 从 PV /dev/fastdisk 分配 100% 的可用空间。

使用缓存池

使用缓存逻辑卷时,LVM 会自动管理缓存的元数据和数据。但您也可以手动创建元数据和缓存 LV,并创建一个缓存池:

# lvcreate -n cache_meta -l 1%FREE MyVolGroup /dev/fastdisk
# lvcreate -n cache_data -l 100%FREE MyVolGroup /dev/fastdisk
# lvconvert --type cache-pool --cachemode writeback --poolmetadata MyVolGroup/cache_meta MyVolGroup/cache_data
# lvconvert --type cache --cachepool MyVolGroup/cache_data MyVolGroup/rootvol

缓存模式选项

缓存模式有两个可选选项:

  • writethrough 确保写入的任何数据都将同时存储在缓存 LV 和原始 LV 中。在这种情况下,丢失与缓存 LV 关联的设备并不意味着丢失任何数据;
  • writeback 确保更好的性能,但代价是如果用于缓存的驱动器发生故障,数据丢失的风险更高。

如果未指定特定的 --cachemode,系统将默认采用 writethrough

提示: 缓存命中和未命中的次数可以通过 lvdisplay 查看,或者通过 libblockdev-lvm 中的 lvm-cache-stats 查看,后者还会以百分比显示。

移除缓存

如果您需要撤销上述的一步创建操作:

# lvconvert --uncache MyVolGroup/rootvol

这会将缓存中所有挂起的写入内容提交回原始 LV,然后删除缓存。其他选项在 lvmcache(7) 中有描述。

RAID

LVM 可用于创建软件 RAID。如果用户没有硬件 RAID 并且本来就打算使用 LVM,那么这是一个不错的选择。来自 lvmraid(7)

lvm(8) RAID 是一种创建逻辑卷 (LV) 的方法,该卷使用多个物理设备来提高性能或容忍设备故障。在 LVM 中,物理设备是单个卷组 (VG) 中的物理卷 (PV)。

LVM RAID 支持 RAID 0, RAID 1, RAID 4, RAID 5, RAID 6 和 RAID 10。有关各级别的详细信息,请参见 维基百科:标准 RAID 级别

提示: mdadm 也可用于创建软件 RAID。它可能更简单、更流行且更容易设置。

设置 RAID

创建物理卷

# pvcreate /dev/sda2 /dev/sdb2

在物理卷上创建卷组

# vgcreate MyVolGroup /dev/sda2 /dev/sdb2

新卷

使用 lvcreate --type raidlevel 创建逻辑卷,有关更多选项,请参见 lvmraid(7)lvcreate(8)

# lvcreate --type RaidLevel [OPTIONS] -n Name -L Size VG [PVs]

请注意以下每个示例是如何指定物理卷的。在某些情况下,让 LVM 为您的新逻辑卷使用设备的特定子集是有意义的。但通常来说,这并非必要。

RAID 0

例如:

# lvcreate -n myraid1vol -i 2 -I 64 -L 70G VolGroup00 /dev/nvme1n1p1 /dev/nvme0n1p1

将在 VolGroup00 中创建一个名为 "myraid1vol" 的 70 GiB 条带化 (raid0) 逻辑卷。条带将分布在 /dev/nvme1n1p1/dev/nvme0n1p1 上。条带大小设置为 64K。

RAID 1

例如:

# lvcreate --type raid1 --mirrors 1 -L 20G -n myraid1vol MyVolGroup /dev/sda2 /dev/sdb2

将在 /dev/sda2/dev/sdb2 上的 VolGroup00 中创建一个名为 "myraid1vol" 的 20 GiB 镜像逻辑卷。

RAID 5

RAID5 至少需要三个驱动器(--stripes 的数量加一个奇偶校验设备)。数据和奇偶校验块存储在每个设备上,通常采用轮转模式。

例如:

# lvcreate --type raid5 --stripes 2 -L 40G -n myraid5vol MyVolGroup /dev/sda2 /dev/sdb2 /dev/sdc2

将在 /dev/sda2, /dev/sdb2/dev/sdc2 上的 VolGroup00 中创建一个名为 "myraid5vol" 的 40 GiB 条带化逻辑卷。在每个磁盘上,RAID5 将占用约 20 GiB。

RAID 6

RAID6 至少需要五个驱动器(--stripes 的数量加两个奇偶校验设备)。与 RAID5 一样,数据和奇偶校验块存储在每个设备上,通常采用轮转模式。

例如:

# lvcreate --type raid6 --stripes 3 -L 60G -n myraid6vol MyVolGroup /dev/sda2 /dev/sdb2 /dev/sdc2 /dev/sdd2

将在 /dev/sda2, /dev/sdb2, /dev/sdc2/dev/sdd2 上的 VolGroup00 中创建一个名为 "myraid6vol" 的 60 GiB 条带化逻辑卷。在每个磁盘上,RAID6 将占用约 20 GiB。

RAID 10

例如:

# lvcreate -n myraid1vol -L 100G --type raid10 -m 1 -i 2 MyVolGroup /dev/sdd1 /dev/sdc1 /dev/sdb1 /dev/sda5

将在 /dev/sdd1, /dev/sdc1, /dev/sdb1/dev/sda5 上的 VolGroup00 中创建一个名为 "myraid1vol" 的 100 GiB RAID10 逻辑卷。

现有卷

只要您有足够的物理设备满足 RAID 要求,您就可以轻松地将非 RAID(如线性)卷转换为几乎任何其他 RAID 配置。其中一些可能需要您完成中间步骤,lvconvert 会通知您并提示您同意。下面的 raid10 可以替换为 raid0, raid1, raid5 等。

# lvconvert --type raid10 /dev/vg01/lv01

使用特定 PV

# lvconvert --type raid10 /dev/vg01/lv01 /dev/sda1 /dev/sdb2 /dev/nvme0n1p1 ...

您可以使用以下命令跟踪转换进度:

# watch lvs -o name,vg_name,copy_percent

精简置备 (Thin provisioning)

注意: 挂载精简 LV 文件系统时,请务必记得使用 discard 选项或定期使用 fstrim,以便在删除文件时允许精简 LV 缩小。

来自 lvmthin(7)

标准 lvm(8) 逻辑卷 (LV) 中的块在创建 LV 时分配,但精简置备 LV 中的块在写入时分配。因此,精简置备 LV 被赋予一个虚拟大小,可以远大于实际可用的物理存储。精简置备 LV 的物理存储量可以在以后根据需要增加。

示例:实现虚拟专用服务器 (VPS)

这是一个经典用例。假设您想启动自己的 VPS 服务,初始在配备 930 GiB 硬盘的单台 PC 上托管约 100 个 VPS。几乎没有哪个 VPS 会真正用完分配给它们的所有存储空间,因此与其为每个 VPS 分配 9 GiB,不如允许每个 VPS 最大使用 30 GiB,并使用精简置备仅为每个 VPS 分配它们实际使用的硬盘空间。假设 930 GiB 硬盘为 /dev/sdb。以下是设置步骤:

准备卷组 MyVolGroup

# vgcreate MyVolGroup /dev/sdb

创建精简池 LV MyThinPool。此 LV 提供存储块。

# lvcreate --type thin-pool -n MyThinPool -l 95%FREE MyVolGroup

精简池由两个子卷组成:数据 LV 和元数据 LV。此命令会自动创建两者。但如果其中任何一个填满,精简池就会停止工作,并且 LVM 目前不支持缩小这些卷。这就是为什么上述命令允许 5% 的额外空间,以防您以后需要扩展精简池的数据或元数据子卷。

为每个 VPS 创建一个精简 LV。这是公开给用户作为其根分区的块设备。

# lvcreate -n SomeClientsRoot -V 30G --thinpool MyThinPool MyVolGroup

块设备 /dev/MyVolGroup/SomeClientsRoot 随后可由 VirtualBox 实例作为根分区使用。

使用精简快照节省更多空间

精简快照比常规快照强大得多,因为它们本身就是精简 LV。有关精简快照优势的完整列表,请参阅 Red Hat 指南 [4]

与其每次创建 VPS 时都从头开始安装 Linux,不如从一个包含 Linux 基本安装的精简 LV 开始,这样更节省空间:

# lvcreate -n GenericRoot -V 30G --thinpool MyThinPool MyVolGroup
*** install Linux at /dev/MyVolGroup/GenericRoot ***

然后为每个 VPS 创建它的快照:

# lvcreate -s MyVolGroup/GenericRoot -n SomeClientsRoot

这样,在精简池中最初只存在一份所有 VPS 共有的数据副本。作为额外奖励,创建新 VPS 是瞬间完成的。

由于这些是精简快照,对 GenericRoot 的写入操作总共只会引起一次 COW 操作,而不是每个快照一次 COW 操作。这使您更新 GenericRoot 的效率比每个 VPS 都是常规快照时更高。

示例:零停机存储升级

精简置备在 VPS 托管之外也有应用。以下是您如何使用它在不卸载文件系统的情况下增加已挂载文件系统的有效容量。再次假设服务器只有一个 930 GiB 的硬盘。设置与 VPS 托管相同,只是只有一个精简 LV,且该 LV 的大小远大于精简池的大小。

# lvcreate -n MyThinLV -V 16T --thinpool MyThinPool MyVolGroup

这个额外的虚拟空间可以在以后通过扩展精简池来填充实际存储。

假设一段时间后需要升级存储,并将一块新硬盘 /dev/sdc 插入服务器。要升级精简池的容量,请将新硬盘添加到 VG:

# vgextend MyVolGroup /dev/sdc

现在,扩展精简池:

# lvextend -l +95%FREE MyVolGroup/MyThinPool

由于此精简 LV 的大小为 16 TiB,您可以再添加 15.09 TiB 的硬盘空间,最后才需要卸载并调整文件系统大小。

注意: 您可能需要使用保留块磁盘配额来防止应用程序尝试使用超过实际物理存储的空间。

自定义

可以通过编辑 /etc/lvm/lvm.conf 进行一些自定义。您可能会发现自定义 lvspvs 的输出很有用,默认输出不包括 % sync(用于查看例如线性和 RAID 类型之间转换的进度)和逻辑卷的类型:

/etc/lvm/lvm.conf
report {
 	lvs_cols = "lv_name,lv_attr,lv_active,vg_name,lv_size,lv_layout,lv_allocation_policy,copy_percent,chunk_size"
	pvs_cols = "pv_name,vg_name,pv_size,pv_free,pv_used,dev_size"
}

故障排除

LVM 命令不起作用

  • 加载正确的模块
# modprobe dm_mod

dm_mod 模块应该会自动加载。如果未加载,请显式地在启动时加载该模块

  • 尝试在命令前加上 lvm,如下所示:
# lvm pvdisplay

逻辑卷未显示

如果您尝试挂载现有的逻辑卷,但它们未显示在 lvscan 中,可以使用以下命令激活它们:

# vgscan
# vgchange -ay

可移动媒体上的 LVM

症状:输入/输出错误。

# vgscan
  Reading all physical volumes.  This may take a while...
  /dev/backupdrive1/backup: read failed after 0 of 4096 at 319836585984: Input/output error
  /dev/backupdrive1/backup: read failed after 0 of 4096 at 319836643328: Input/output error
  /dev/backupdrive1/backup: read failed after 0 of 4096 at 0: Input/output error
  /dev/backupdrive1/backup: read failed after 0 of 4096 at 4096: Input/output error
  Found volume group "backupdrive1" using metadata type lvm2
  Found volume group "networkdrive" using metadata type lvm2

原因:在未先停用卷组的情况下移除外部 LVM 驱动器。在断开连接之前,请确保:

# vgchange -an volume_group_name

修复:假设您已经尝试使用 vgchange -ay vg 激活卷组,并且收到输入/输出错误:

# vgchange -an volume_group_name

拔掉外部驱动器并等待几分钟。

# vgscan
# vgchange -ay volume_group_name

在 LVM 和可移动媒体上挂起/恢复

本文或本章节的准确性存在争议。

原因: 提供的解决方案在更复杂的设置中不起作用,例如 LVM 上的 LUKS。(在 Talk:LVM#LVM on removable media 中讨论)

为了让 LVM 与可移动媒体(如外部 USB 驱动器)正常工作,需要在挂起前停用外部驱动器的卷组。如果不这样做,可能会在 dm 设备上出现缓冲 I/O 错误(恢复后)。因此,不建议在同一个卷组中混合使用外部和内部驱动器。

要自动停用带有外部 USB 驱动器的卷组,请按以下方式为每个卷组标记 sleep_umount 标签:

# vgchange --addtag sleep_umount vg_external

设置标签后,使用以下 systemd 单元文件在挂起前正确停用卷。恢复时,它们将被 LVM 自动激活。

/etc/systemd/system/ext_usb_vg_deactivate.service
[Unit]
Description=Deactivate external USB volume groups on suspend
Before=sleep.target

[Service]
Type=oneshot
ExecStart=-/etc/systemd/system/deactivate_sleep_vgs.sh

[Install]
WantedBy=sleep.target

以及此脚本:

/etc/systemd/system/deactivate_sleep_vgs.sh
#!/bin/sh

TAG=@sleep_umount
vgs=$(vgs --noheadings -o vg_name $TAG)

echo "Deactivating volume groups with $TAG tag: $vgs"

# Unmount logical volumes belonging to all the volume groups with tag $TAG
for vg in $vgs; do
    for lv_dev_path in $(lvs --noheadings  -o lv_path -S lv_active=active,vg_name=$vg); do
        echo "Unmounting logical volume $lv_dev_path"
        umount $lv_dev_path
    done
done

# Deactivate volume groups tagged with sleep_umount
for vg in $vgs; do
    echo "Deactivating volume group $vg"
    vgchange -an $vg
done

最后,启用该单元。

调整连续逻辑卷大小失败

如果尝试扩展逻辑卷报错:

" Insufficient suitable contiguous allocatable extents for logical volume "

原因是该逻辑卷是使用显式的连续分配策略(选项 -C y--alloc contiguous)创建的,且没有更多相邻的连续范围可用。[5][失效链接 2025-11-17—SSL 错误]

要解决此问题,在扩展逻辑卷之前,使用 lvchange --alloc inherit logical_volume 更改其分配策略。如果您需要保留连续分配策略,另一种方法是将卷移动到具有足够空闲范围的磁盘区域。参见 [6]

命令 "grub-mkconfig" 报错 "unknown filesystem"

生成 grub.cfg 之前,请务必移除快照卷。

精简置备的根卷设备超时

当快照数量较多时,thin_check 运行时间过长,导致等待根设备超时。为了补偿,请在引导加载程序配置中添加 rootdelay=60 内核启动参数。或者,让 thin_check 跳过块映射检查(参见 [7])并重新生成 initramfs

/etc/lvm/lvm.conf
thin_check_options = [ "-q", "--clear-needs-check-flag", "--skip-mappings" ]

关机延迟

如果您使用 RAID、快照或精简置备并在关机时遇到延迟,请确保 lvm2-monitor.service启动。参见 FS#50420

休眠到精简置备的交换卷

参见 电源管理/挂起与休眠#休眠到精简置备的 LVM 卷

参见