当前位置: 首页 > news >正文

逻辑卷管理器 (LVM) 简介

古老的 e5 主机目前有这些存储设备 (硬盘): 系统盘 (M.2 NVMe SSD 480GB), 数据盘 (3.5 英寸 SATA 硬盘 4TB x2). 窝决定使用 LVM 对数据盘进行管理.

逻辑卷管理器 (LVM) 可以认为是一种 (单机) 存储虚拟化 技术. 多个物理存储设备 (PV) 组成一个存储池 (VG), 然后划分虚拟分区 (LV).

窝觉得, 对窝等穷人 (不超过 4 块大容量硬盘) 来说, RAID (磁盘阵列) 的用处不大. 只有很多块硬盘的时候, RAID 才可能有明显优势.

LVM 在管理方面具有很高的灵活度, 功能非常强大. 比如, 可以很方便的随时调整虚拟分区 (LV) 的大小 (扩容/缩容, lvresize), 将 LV 从一块硬盘移动到另一块硬盘 (pvmove), 一个 LV 横跨多块硬盘. 还有快照 (snapshot), 软件 RAID (lvmraid), 动态存储空间分配 (lvmthin), 加速缓存 (lvmcache), 压缩去重 (lvmvdo), 加密等许多功能. 运行虚拟机 (比如 QEMU/KVM) 时, 可以直接将 LV 分配给虚拟机作为虚拟硬盘使用, 提高性能.


相关文章: 《安装 Fedora CoreOS 操作系统》 https://blog.csdn.net/secext2022/article/details/139805083

参考资料:

  • https://sourceware.org/lvm2/
  • https://gitlab.com/lvmteam/lvm2
  • https://www.man7.org/linux/man-pages/man8/lvm.8.html

目录

  • 1 LVM 工作原理简介
  • 2 LVM 常用基础命令
    • 2.1 使用 fdisk 对硬盘分区 (可选)
    • 2.2 创建 pv (物理卷)
    • 2.3 创建 vg (卷组)
    • 2.4 创建 lv (逻辑卷)
    • 2.5 显示详细信息
  • 3 格式化分区并挂载
    • 3.1 建立文件系统 (btrfs)
    • 3.2 挂载 (mount)
    • 3.3 systemd 开机挂载
  • 4 LVM 基础管理操作
    • 4.1 在线扩容
    • 4.2 更多高级操作
  • 5 总结与展望

操作系统与 LVM 软件的版本信息:

core@MiWiFi-RA74-srv:~$ rpm-ostree status
State: idle
AutomaticUpdatesDriver: ZincatiDriverState: active; periodically polling for updates (last checked Sun 2024-06-16 09:20:10 UTC)
Deployments:
● fedora:fedora/x86_64/coreos/stableVersion: 40.20240519.3.0 (2024-06-04T23:21:15Z)Commit: 724ce262d4a27f6b7cb1508e8737e2244d69bb78509d2749cebd7972042bf814GPGSignature: Valid signature by 115DF9AEF857853EE8445D0A0727707EA15B79CC
core@MiWiFi-RA74-srv:~$ sudo lvm versionLVM version:     2.03.23(2) (2023-11-21)Library version: 1.02.197 (2023-11-21)Driver version:  4.48.0Configuration:   ./configure --build=x86_64-redhat-linux-gnu --host=x86_64-redhat-linux-gnu --program-prefix= --disable-dependency-tracking --prefix=/usr --exec-prefix=/usr --bindir=/usr/bin --sbindir=/usr/sbin --sysconfdir=/etc --datadir=/usr/share --includedir=/usr/include --libdir=/usr/lib64 --libexecdir=/usr/libexec --localstatedir=/var --runstatedir=/run --sharedstatedir=/var/lib --mandir=/usr/share/man --infodir=/usr/share/info --with-default-dm-run-dir=/run --with-default-run-dir=/run/lvm --with-default-pid-dir=/run --with-default-locking-dir=/run/lock/lvm --with-usrlibdir=/usr/lib64 --enable-fsadm --enable-write_install --with-user= --with-group= --with-device-uid=0 --with-device-gid=6 --with-device-mode=0660 --enable-pkgconfig --enable-cmdlib --enable-dmeventd --enable-blkid_wiping --with-udevdir=/usr/lib/udev/rules.d --enable-udev_sync --with-thin=internal --with-cache=internal --enable-lvmpolld --enable-lvmlockd-dlm --enable-lvmlockd-dlmcontrol --enable-lvmlockd-sanlock --enable-dbus-service --enable-notify-dbus --enable-dmfilemapd --with-writecache=internal --with-vdo=internal --with-vdo-format=/usr/bin/vdoformat --with-integrity=internal --with-default-use-devices-file=1 --disable-silent-rules --enable-app-machineid --enable-editline --disable-readline
core@MiWiFi-RA74-srv:~$ 

1 LVM 工作原理简介

在这里插入图片描述

LVM 的核心概念有:

  • 物理卷 (PV): 一块物理硬盘, 或者硬盘上的一个分区. 也就是底层的物理存储设备.

  • 卷组 (VG): 多个 PV 组成的一个存储池, 相当于一块虚拟大硬盘.

  • 逻辑卷 (LV): 从 VG 之中划分, 相当于一个虚拟分区.

LVM 将 PV 划分为许多小的数据存储块 (PE, 默认 4MB), VG 就是一堆 PE 的集合, 然后把 PE 分配给 LV. 当上层软件 (比如 filesystem 文件系统) 访问 LV 时, LVM 找出要访问的数据对应哪个 PE, 从而访问对应的 PV.

有了这个虚拟化架构, 许多强大的高级功能就能很容易实现了. 比如动态调整 LV 的大小, 只要重新分配 PE 即可, 比如把未使用的空闲 PE 分配给 LV (扩容), 所以操作很快, 通常在几秒之内即可完成. 比如有 2 块 500GB 的硬盘 (PV), 但是想创建一个 800GB 的 LV, 超过了单块硬盘的容量. 此时只需要将这 2 块硬盘加入同一个 VG, 然后创建 LV 即可. 也就是把不同 PV 的 PE 分配给同一个 LV.

2 LVM 常用基础命令

本章节介绍使用 LVM 的常见基础命令, 并给出实际操作进行举栗.

警告: 对硬盘和 LVM 进行操作可能造成数据丢失或损坏 (特别是误操作), 请提前备份重要数据 !! 免责声明: 本文不对因此造成的数据丢失或损坏承担任何责任.

警告: 对硬盘和 LVM 进行操作可能造成数据丢失或损坏 (特别是误操作), 请提前备份重要数据 !! 免责声明: 本文不对因此造成的数据丢失或损坏承担任何责任.

警告: 对硬盘和 LVM 进行操作可能造成数据丢失或损坏 (特别是误操作), 请提前备份重要数据 !! 免责声明: 本文不对因此造成的数据丢失或损坏承担任何责任.

2.1 使用 fdisk 对硬盘分区 (可选)

虽然 LVM 可以直接把整块硬盘作为 PV 使用, 但是保险起见, 以及为了更高的灵活度, 窝还是决定对硬盘分区 (建立 GPT 分区表).

如果硬盘接到别的计算机, 能够看到分区 (可能无法识别), 而不是识别为一块未分区的硬盘, 这或许可能减小数据丢失的概率 (一定程度上避免误操作). 另外, 分区之后, 可以只把一块硬盘的一部分 (分区) 分给 LVM, 其余部分还可以作为普通分区使用, 这提高了管理的灵活度.

首先使用 fdisk -l 命令查看硬盘分区情况:

core@MiWiFi-RA74-srv:~$ sudo fdisk -l
Disk /dev/sdb: 3.64 TiB, 4000787030016 bytes, 7814037168 sectors
Disk model: HGST HMS5C4040BL
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 4096 bytes
I/O size (minimum/optimal): 4096 bytes / 4096 bytesDisk /dev/sda: 3.64 TiB, 4000787030016 bytes, 7814037168 sectors
Disk model: TOSHIBA MG04ACA4
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 4096 bytes
I/O size (minimum/optimal): 4096 bytes / 4096 bytesDisk /dev/nvme0n1: 476.94 GiB, 512110190592 bytes, 1000215216 sectors
Disk model: KINGBANK KP230                          
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disklabel type: gpt

可以看到 2 块数据盘 (/dev/sda, /dev/sdb), 还没有分区表. /dev/nvme0n1 是系统盘, GPT 分区表 (Disklabel type: gpt), 忽略.

关于 fdisk 工具的使用, 请读者自行查阅相关资料. 下面是分区之后的结果:

core@MiWiFi-RA74-srv:~$ sudo fdisk -l
Disk /dev/sdb: 3.64 TiB, 4000787030016 bytes, 7814037168 sectors
Disk model: HGST HMS5C4040BL
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 4096 bytes
I/O size (minimum/optimal): 4096 bytes / 4096 bytes
Disklabel type: gpt
Disk identifier: 1A08BE7B-ED19-4EF9-AC4D-7F5ECB213941Device     Start        End    Sectors  Size Type
/dev/sdb1   2048 7814035455 7814033408  3.6T Linux LVMDisk /dev/sda: 3.64 TiB, 4000787030016 bytes, 7814037168 sectors
Disk model: TOSHIBA MG04ACA4
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 4096 bytes
I/O size (minimum/optimal): 4096 bytes / 4096 bytes
Disklabel type: gpt
Disk identifier: AC9E4B43-C8C9-408E-8B28-16828A83EB83Device     Start        End    Sectors  Size Type
/dev/sda1   2048 7814035455 7814033408  3.6T Linux LVM

目前没有更多需求, 所以将整个硬盘空间分成了一个分区. 一共 2 个分区: /dev/sda1, /dev/sdb1.

2.2 创建 pv (物理卷)

使用 blkid 命令查看块设备 (省略部分结果):

core@MiWiFi-RA74-srv:~$ sudo blkid/dev/sdb1: UUID="a6mk78-Ns4R-25hg-5ztz-VG1u-w52o-jLbIe6" TYPE="LVM2_member" PARTLABEL="d202406b-pv" PARTUUID="49d0afd3-38b3-4d7b-9bc2-3662068a4c84"
/dev/sda1: UUID="Q7krxa-lvh5-36Qx-Vc0a-YKjs-XCnz-fTOxPd" TYPE="LVM2_member" PARTLABEL="d202406a-pv" PARTUUID="4e9a63b9-7d38-478a-a6e9-bfc7cd339e8e"

使用 pvs 命令查看 PV 列表, 使用 pvcreate 命令创建 PV (相当于格式化分区). 这些命令需要 root 权限, 所以前面加上 sudo. 比如:

core@MiWiFi-RA74-srv:~$ sudo pvs
core@MiWiFi-RA74-srv:~$ sudo pvcreate /dev/sda1Physical volume "/dev/sda1" successfully created.
core@MiWiFi-RA74-srv:~$ sudo pvcreate /dev/sdb1Physical volume "/dev/sdb1" successfully created.
core@MiWiFi-RA74-srv:~$ sudo pvsPV         VG Fmt  Attr PSize  PFree /dev/sda1     lvm2 ---  <3.64t <3.64t/dev/sdb1     lvm2 ---  <3.64t <3.64t
core@MiWiFi-RA74-srv:~$ 

可以看到, 已经创建了 2 个 PV.

2.3 创建 vg (卷组)

使用 vgs 命令查看 VG, 使用 vgcreate 命令创建 VG. 在创建前后分别查看 PV 和 VG 的状态, 比如:

core@MiWiFi-RA74-srv:~$ sudo pvsPV         VG Fmt  Attr PSize  PFree /dev/sda1     lvm2 ---  <3.64t <3.64t/dev/sdb1     lvm2 ---  <3.64t <3.64t
core@MiWiFi-RA74-srv:~$ sudo vgs
core@MiWiFi-RA74-srv:~$ sudo vgcreate d202406a /dev/sda1Volume group "d202406a" successfully created
core@MiWiFi-RA74-srv:~$ sudo vgcreate d202406b /dev/sdb1Volume group "d202406b" successfully created
core@MiWiFi-RA74-srv:~$ sudo pvsPV         VG       Fmt  Attr PSize  PFree /dev/sda1  d202406a lvm2 a--  <3.64t <3.64t/dev/sdb1  d202406b lvm2 a--  <3.64t <3.64t
core@MiWiFi-RA74-srv:~$ sudo vgsVG       #PV #LV #SN Attr   VSize  VFree d202406a   1   0   0 wz--n- <3.64t <3.64td202406b   1   0   0 wz--n- <3.64t <3.64t
core@MiWiFi-RA74-srv:~$ 

创建了 2 个 VG, 名称分别为 d202406a, d202406b.

因为窝只有 2 块硬盘, 窝希望一块硬盘突然挂掉之后, 另一块完全不受影响, 所以分别对每块硬盘创建一个 VG, 而没有加入同一个 VG.

作为穷人, 预计窝一个月买不了几块硬盘 (很可能一年也买不了几块), 所以使用这种命名方案. 读者随意.

2.4 创建 lv (逻辑卷)

使用 lvs 命令查看 LV, 使用 lvcreate 命令创建 LV. 在创建前后分别查看 PV, VG, LV 的状态, 比如:

core@MiWiFi-RA74-srv:~$ sudo pvsPV         VG       Fmt  Attr PSize  PFree /dev/sda1  d202406a lvm2 a--  <3.64t <3.64t/dev/sdb1  d202406b lvm2 a--  <3.64t <3.64t
core@MiWiFi-RA74-srv:~$ sudo vgsVG       #PV #LV #SN Attr   VSize  VFree d202406a   1   0   0 wz--n- <3.64t <3.64td202406b   1   0   0 wz--n- <3.64t <3.64t
core@MiWiFi-RA74-srv:~$ sudo lvs
core@MiWiFi-RA74-srv:~$ sudo lvcreate -L 500g d202406a -n d202406a1Logical volume "d202406a1" created.
core@MiWiFi-RA74-srv:~$ sudo lvcreate -L 500g d202406b -n d202406b1Logical volume "d202406b1" created.
core@MiWiFi-RA74-srv:~$ sudo pvsPV         VG       Fmt  Attr PSize  PFree/dev/sda1  d202406a lvm2 a--  <3.64t 3.15t/dev/sdb1  d202406b lvm2 a--  <3.64t 3.15t
core@MiWiFi-RA74-srv:~$ sudo vgsVG       #PV #LV #SN Attr   VSize  VFreed202406a   1   1   0 wz--n- <3.64t 3.15td202406b   1   1   0 wz--n- <3.64t 3.15t
core@MiWiFi-RA74-srv:~$ sudo lvsLV        VG       Attr       LSize   Pool Origin Data%  Meta%  Move Log Cpy%Sync Convertd202406a1 d202406a -wi-a----- 500.00g                                                    d202406b1 d202406b -wi-a----- 500.00g                                                    
core@MiWiFi-RA74-srv:~$ 

在每个 VG 创建了一个 LV, 名称分别为 d202406a1, d202406b1, 容量为 500GB. 可以看到, 创建 LV 之后, PV 和 VG 的空闲空间 (Free) 相应减少.

由于对 LV 进行扩容是很方便快捷的操作, 刚开始创建 LV 时可以指定较小的容量, 以后再增加. 这可以提高管理灵活度, VG 有空闲空间可以应对更多需求.

2.5 显示详细信息

使用 pvdisplay, vgdisplay, lvdisplay 命令分别查看 PV, VG, LV 的详细信息, 比如:

core@MiWiFi-RA74-srv:~$ sudo pvdisplay--- Physical volume ---PV Name               /dev/sdb1VG Name               d202406bPV Size               <3.64 TiB / not usable 2.00 MiBAllocatable           yes PE Size               4.00 MiBTotal PE              953861Free PE               825861Allocated PE          128000PV UUID               a6mk78-Ns4R-25hg-5ztz-VG1u-w52o-jLbIe6--- Physical volume ---PV Name               /dev/sda1VG Name               d202406aPV Size               <3.64 TiB / not usable 2.00 MiBAllocatable           yes PE Size               4.00 MiBTotal PE              953861Free PE               825861Allocated PE          128000PV UUID               Q7krxa-lvh5-36Qx-Vc0a-YKjs-XCnz-fTOxPdcore@MiWiFi-RA74-srv:~$ sudo vgdisplay--- Volume group ---VG Name               d202406bSystem ID             Format                lvm2Metadata Areas        1Metadata Sequence No  2VG Access             read/writeVG Status             resizableMAX LV                0Cur LV                1Open LV               0Max PV                0Cur PV                1Act PV                1VG Size               <3.64 TiBPE Size               4.00 MiBTotal PE              953861Alloc PE / Size       128000 / 500.00 GiBFree  PE / Size       825861 / 3.15 TiBVG UUID               tqpcF9-p02c-J0gU-nfhY-FLRo-tSSk-FiGAU9--- Volume group ---VG Name               d202406aSystem ID             Format                lvm2Metadata Areas        1Metadata Sequence No  2VG Access             read/writeVG Status             resizableMAX LV                0Cur LV                1Open LV               0Max PV                0Cur PV                1Act PV                1VG Size               <3.64 TiBPE Size               4.00 MiBTotal PE              953861Alloc PE / Size       128000 / 500.00 GiBFree  PE / Size       825861 / 3.15 TiBVG UUID               PBFQtB-la8e-PyNQ-Dbd0-OMzc-ziMn-0lgzD8core@MiWiFi-RA74-srv:~$ sudo lvdisplay--- Logical volume ---LV Path                /dev/d202406b/d202406b1LV Name                d202406b1VG Name                d202406bLV UUID                Ddwkdz-E1JX-Hjrh-hl9B-J1bK-k5Ph-eVzmr0LV Write Access        read/writeLV Creation host, time MiWiFi-RA74-srv, 2024-06-16 09:06:46 +0000LV Status              available# open                 0LV Size                500.00 GiBCurrent LE             128000Segments               1Allocation             inheritRead ahead sectors     auto- currently set to     256Block device           253:1--- Logical volume ---LV Path                /dev/d202406a/d202406a1LV Name                d202406a1VG Name                d202406aLV UUID                F44xAN-fMq6-LT6d-jeAt-bVyx-vd4a-BwnQ0eLV Write Access        read/writeLV Creation host, time MiWiFi-RA74-srv, 2024-06-16 09:06:21 +0000LV Status              available# open                 0LV Size                500.00 GiBCurrent LE             128000Segments               1Allocation             inheritRead ahead sectors     auto- currently set to     256Block device           253:0core@MiWiFi-RA74-srv:~$ 

3 格式化分区并挂载

上面使用 LVM 命令成功创建了 PV, VG, LV, 也就是相当于给虚拟硬盘划分好了虚拟分区, 关于 LVM 使用的部分已经结束了, 喵呜啦 ~~

但是通常在使用之前, 还要格式化分区, 也就是建立 文件系统 (filesystem).

3.1 建立文件系统 (btrfs)

此处选择使用 btrfs, 因为 btrfs 功能丰富, 具有很高的管理灵活度. btrfs 技术上基于 B-Tree 和写时复制 (CoW), 具有压缩, 子卷 (subvol), 快照, 软件 RAID 等功能.

使用 mkfs.btrfs 命令对 LV 进行格式化, 使用 -L 参数指定卷标 (名称), 比如:

core@MiWiFi-RA74-srv:~$ sudo mkfs.btrfs -L d202406a1 /dev/d202406a/d202406a1
btrfs-progs v6.8.1
See https://btrfs.readthedocs.io for more information.NOTE: several default settings have changed in version 5.15, please make surethis does not affect your deployments:- DUP for metadata (-m dup)- enabled no-holes (-O no-holes)- enabled free-space-tree (-R free-space-tree)Label:              d202406a1
UUID:               11ee8928-3809-4faa-adb1-629def031e35
Node size:          16384
Sector size:        4096	(CPU page size: 4096)
Filesystem size:    500.00GiB
Block group profiles:Data:             single            8.00MiBMetadata:         DUP               1.00GiBSystem:           DUP               8.00MiB
SSD detected:       no
Zoned device:       no
Features:           extref, skinny-metadata, no-holes, free-space-tree
Checksum:           crc32c
Number of devices:  1
Devices:ID        SIZE  PATH                   1   500.00GiB  /dev/d202406a/d202406a1core@MiWiFi-RA74-srv:~$ sudo mkfs.btrfs -L d202406b1 /dev/d202406b/d202406b1
btrfs-progs v6.8.1
See https://btrfs.readthedocs.io for more information.NOTE: several default settings have changed in version 5.15, please make surethis does not affect your deployments:- DUP for metadata (-m dup)- enabled no-holes (-O no-holes)- enabled free-space-tree (-R free-space-tree)Label:              d202406b1
UUID:               787b22e1-f9ff-4aea-a2fa-b03b6c925ae8
Node size:          16384
Sector size:        4096	(CPU page size: 4096)
Filesystem size:    500.00GiB
Block group profiles:Data:             single            8.00MiBMetadata:         DUP               1.00GiBSystem:           DUP               8.00MiB
SSD detected:       no
Zoned device:       no
Features:           extref, skinny-metadata, no-holes, free-space-tree
Checksum:           crc32c
Number of devices:  1
Devices:ID        SIZE  PATH                   1   500.00GiB  /dev/d202406b/d202406b1core@MiWiFi-RA74-srv:~$ sudo blkid/dev/mapper/d202406b-d202406b1: LABEL="d202406b1" UUID="787b22e1-f9ff-4aea-a2fa-b03b6c925ae8" UUID_SUB="44d918eb-21b0-4b76-a104-4e5ea9e2838e" BLOCK_SIZE="4096" TYPE="btrfs"/dev/mapper/d202406a-d202406a1: LABEL="d202406a1" UUID="11ee8928-3809-4faa-adb1-629def031e35" UUID_SUB="e9c7bd1d-8650-4c31-8ab7-5015dea5065a" BLOCK_SIZE="4096" TYPE="btrfs"

格式化之后可以使用 blkid 命令确认结果.

3.2 挂载 (mount)

Linux 的文件系统 (VFS) 整个系统形成一棵完整的树状结构, 从根目录 (/) 开始. 挂载 (mount) 就是把文件系统 (块设备) 安装到这棵树上的操作. 挂载之后才能访问文件系统之中的文件.

挂载点 (mount point) 类似于这棵树上的某个枝条, 也就是挂载安装的位置 (目录). 与挂载相反的操作是卸载 (umount), 关机之前需要正常卸载文件系统, 防止数据丢失.

首先使用 mkdir -p 命令创建想要的挂载点 (目录), 比如:

core@MiWiFi-RA74-srv:~$ sudo mkdir -p /mnt/data/d1
core@MiWiFi-RA74-srv:~$ sudo mkdir -p /mnt/data/d2
core@MiWiFi-RA74-srv:~$ ls -l /mnt/data
total 0
drwxr-xr-x. 2 root root 6 Jun 16 09:44 d1
drwxr-xr-x. 2 root root 6 Jun 16 09:44 d2
core@MiWiFi-RA74-srv:~$ 

此处创建了两个目录 /mnt/data/d1, /mnt/data/d2. 挂载点最好是空目录, 否则挂载后会 “遮盖” 原来的目录, 导致原来目录中的文件无法访问 (卸载后会恢复原状).

使用 mount 命令进行挂载, 指定块设备 (LV) 和挂载点, 使用 -o 指定挂载选项, 比如:

core@MiWiFi-RA74-srv:~$ sudo mount /dev/d202406a/d202406a1 /mnt/data/d1 -o compress=zstd,nosuid,nodev
core@MiWiFi-RA74-srv:~$ sudo mount /dev/d202406b/d202406b1 /mnt/data/d2 -o compress=zstd,nosuid,nodev

其中 compress=zstd 选项表示启用压缩 (btrfs 文件系统的功能), 压缩算法为 zstd. nosuid 表示不允许使用 suid, nodev 表示不允许创建设备文件. 因为这个是数据盘, 所以禁止这些特殊文件, 可以提高系统的安全性.

挂载之后, 可以使用 df, mount 命令查看效果, 比如:

core@MiWiFi-RA74-srv:~$ df -h
Filesystem                      Size  Used Avail Use% Mounted on/dev/mapper/d202406a-d202406a1 1000G  5.8M  998G   1% /var/mnt/data/d1
/dev/mapper/d202406b-d202406b1 1000G  5.8M  998G   1% /var/mnt/data/d2
core@MiWiFi-RA74-srv:~$ mount/dev/mapper/d202406a-d202406a1 on /var/mnt/data/d1 type btrfs (rw,nosuid,nodev,relatime,seclabel,compress=zstd:3,space_cache=v2,subvolid=5,subvol=/)
/dev/mapper/d202406b-d202406b1 on /var/mnt/data/d2 type btrfs (rw,nosuid,nodev,relatime,seclabel,compress=zstd:3,space_cache=v2,subvolid=5,subvol=/)

在挂载之后写入文件, 有助于理解挂载的工作方式:

core@MiWiFi-RA74-srv:~$ sudo touch /mnt/data/d1/20240616-d202406a1
core@MiWiFi-RA74-srv:~$ sudo touch /mnt/data/d2/20240616-d202406b1
core@MiWiFi-RA74-srv:~$ ls -l /mnt/data/d1 /mnt/data/d2
/mnt/data/d1:
total 0
-rw-r--r--. 1 root root 0 Jun 16 09:48 20240616-d202406a1/mnt/data/d2:
total 0
-rw-r--r--. 1 root root 0 Jun 16 09:48 20240616-d202406b1
core@MiWiFi-RA74-srv:~$ sync

挂载之后查看 PV, VG, LV 的状态:

core@MiWiFi-RA74-srv:~$ sudo pvsPV         VG       Fmt  Attr PSize  PFree/dev/sda1  d202406a lvm2 a--  <3.64t 3.15t/dev/sdb1  d202406b lvm2 a--  <3.64t 3.15t
core@MiWiFi-RA74-srv:~$ sudo vgsVG       #PV #LV #SN Attr   VSize  VFreed202406a   1   1   0 wz--n- <3.64t 3.15td202406b   1   1   0 wz--n- <3.64t 3.15t
core@MiWiFi-RA74-srv:~$ sudo lvsLV        VG       Attr       LSize   Pool Origin Data%  Meta%  Move Log Cpy%Sync Convertd202406a1 d202406a -wi-ao---- 500.00g                                                    d202406b1 d202406b -wi-ao---- 500.00g                                                    
core@MiWiFi-RA74-srv:~$ 

注意挂载后 LV 属性会变成 -wi-ao (多了 o).

3.3 systemd 开机挂载

上面使用 mount 命令手动挂载, 重启之后就会失效. 如果想要开机挂载, 可以编写 systemd 配置文件, 比如:

core@MiWiFi-RA74-srv:~$ cat /etc/systemd/system/var-mnt-data-d1.mount
[Mount]
What=/dev/d202406a/d202406a1
Where=/var/mnt/data/d1
Type=btrfs
Options=compress=zstd,nosuid,nodev[Install]
WantedBy=multi-user.target
core@MiWiFi-RA74-srv:~$ 

使用 systemctl enable 命令启用:

core@MiWiFi-RA74-srv:~$ sudo systemctl enable var-mnt-data-d1.mount
Created symlink /etc/systemd/system/multi-user.target.wants/var-mnt-data-d1.mount → /etc/systemd/system/var-mnt-data-d1.mount.
core@MiWiFi-RA74-srv:~$ sudo systemctl enable var-mnt-data-d2.mount
Created symlink /etc/systemd/system/multi-user.target.wants/var-mnt-data-d2.mount → /etc/systemd/system/var-mnt-data-d2.mount.
core@MiWiFi-RA74-srv:~$ 

重启, 就能看到开机挂载的效果了.

参考资料: https://www.freedesktop.org/software/systemd/man/latest/systemd.mount.html

4 LVM 基础管理操作

上面介绍了开始使用 LVM 的完整操作, 包括: 硬盘分区, 创建 PV, VG, LV, 格式化, 挂载, 开机挂载.

在日常使用 LVM 的过程中还需要一些管理操作.

4.1 在线扩容

增加 LV 的容量可能是最常用的操作了.

使用 lvextend 命令对 LV 进行扩容, 使用 -L 参数指定容量, +500g 表示增大 500GB, 如下:

core@MiWiFi-RA74-srv:~$ sudo lvextend -L +500g d202406a/d202406a1Size of logical volume d202406a/d202406a1 changed from 500.00 GiB (128000 extents) to 1000.00 GiB (256000 extents).Logical volume d202406a/d202406a1 successfully resized.
core@MiWiFi-RA74-srv:~$ sudo lvextend -L +500g d202406b/d202406b1Size of logical volume d202406b/d202406b1 changed from 500.00 GiB (128000 extents) to 1000.00 GiB (256000 extents).Logical volume d202406b/d202406b1 successfully resized.
core@MiWiFi-RA74-srv:~$ sudo pvsPV         VG       Fmt  Attr PSize  PFree/dev/sda1  d202406a lvm2 a--  <3.64t 2.66t/dev/sdb1  d202406b lvm2 a--  <3.64t 2.66t
core@MiWiFi-RA74-srv:~$ sudo vgsVG       #PV #LV #SN Attr   VSize  VFreed202406a   1   1   0 wz--n- <3.64t 2.66td202406b   1   1   0 wz--n- <3.64t 2.66t
core@MiWiFi-RA74-srv:~$ sudo lvsLV        VG       Attr       LSize    Pool Origin Data%  Meta%  Move Log Cpy%Sync Convertd202406a1 d202406a -wi-ao---- 1000.00g                                                    d202406b1 d202406b -wi-ao---- 1000.00g                                                    
core@MiWiFi-RA74-srv:~$ 

可以看到, LV 已经扩容了. 接下来进行文件系统的扩容, 对于 btrfs 文件系统可以使用 btrfs filesystem resize max 命令, 比如:

core@MiWiFi-RA74-srv:~$ sudo btrfs filesystem resize max /mnt/data/d1
Resize device id 1 (/dev/mapper/d202406a-d202406a1) from 500.00GiB to max
core@MiWiFi-RA74-srv:~$ sudo btrfs filesystem resize max /mnt/data/d2
Resize device id 1 (/dev/mapper/d202406b-d202406b1) from 500.00GiB to max
core@MiWiFi-RA74-srv:~$ df -h
Filesystem                      Size  Used Avail Use% Mounted on/dev/mapper/d202406a-d202406a1 1000G  5.8M  998G   1% /var/mnt/data/d1
/dev/mapper/d202406b-d202406b1 1000G  5.8M  998G   1% /var/mnt/data/d2

扩容完毕. 注意, 上述操作完全可以在系统正常运行的过程中进行, 无需中断或停机, 也就是 在线 扩容.

4.2 更多高级操作

这些功能可能不常用, 简单了解一下, 需要使用时再详细查找资料.

  • (1) 将新的 PV 加入 VG. 使用 vgextend 命令.

    扩大 VG 的总容量, 比如添加新的硬盘.

    https://www.man7.org/linux/man-pages/man8/vgextend.8.html

  • (2) 从 VG 移除 PV. 使用 vgreduce 命令. 移除 PV 之前, 可能需要使用 pvmove 命令将其中的数据 (PE) 转移.

    https://www.man7.org/linux/man-pages/man8/vgreduce.8.html
    https://www.man7.org/linux/man-pages/man8/pvmove.8.html

  • (3) 扫描 PV. 使用 pvscan 命令.

    当存储设备变动后 (比如插入新的硬盘), 执行此命令更新系统中的 PV 列表.

    https://www.man7.org/linux/man-pages/man8/pvscan.8.html

  • (4) 删除 LV. 使用 lvremove 命令.

    删除 LV 会删除其中的数据. 需要先卸载 (umount) 才能删除.

    https://www.man7.org/linux/man-pages/man8/lvremove.8.html

  • (5) 创建快照. 使用 lvcreate -s 命令.

    快照 (snapshot) 可以保存一个 LV 在创建快照时刻的状态 (数据). 快照可以用来备份数据, 比如对一个 LV 创建快照, 然后对快照进行备份. 因为快照中的数据是不变的, 而一个运行中的文件系统, 会不停读写数据, 对备份造成困难.

    https://www.man7.org/linux/man-pages/man8/lvcreate.8.html

  • (6) 软件 RAID (磁盘阵列).

    LVM 支持 raid0, raid1, raid4, raid5, raid6, raid10. 需要多块硬盘 (PV) 才能创建 RAID.

    和硬件 RAID (阵列卡) 相比, 软件 RAID 会使用更多的 CPU 和内存资源. 但是软件 RAID 具有更高的灵活度, 比如可以只把一块硬盘的一部分用于 RAID, 而硬件 RAID 只能把整块硬盘用于 RAID.

    https://www.man7.org/linux/man-pages/man7/lvmraid.7.html

  • (7) 加速缓存.

    LVM 可以构建带缓存的多级存储系统. 比如使用大容量硬盘存储数据, 前面使用快速的 SSD 作为缓存, 缓存通过存储热点数据, 可能提高整个系统的存储性能.

    https://www.man7.org/linux/man-pages/man7/lvmcache.7.html

  • (8) 压缩去重.

    在块设备 (LV) 层级进行数据压缩和重复数据去除 (相同数据只存储一份).

    https://www.man7.org/linux/man-pages/man7/lvmvdo.7.html

5 总结与展望

逻辑卷管理器 (LVM) 使用物理卷 (PV), 卷组 (VG), 逻辑卷 (LV) 这 3 层抽象, 提供了很高的灵活度, 功能很强大, 使用起来却简单方便.

文本介绍了使用 LVM 对硬盘进行存储管理的整个过程: 硬盘分区 (fdisk), 创建 PV, VG, LV, 格式化 (btrfs), 挂载 (mount), 开机挂载 (systemd). 另外介绍了一些 LVM 的管理操作与高级功能.

作为穷人, 很难拥有大规模服务器集群 (几十台甚至数百台), 能有两三台廉价二手服务器就已经很不错了, 只有一台那也能凑合. LVM 作为一种单机的存储虚拟化技术, 应该能发挥很好的作用. 狠狠的使用 LVM 吧 !


本文使用 CC-BY-SA 4.0 许可发布.

相关文章:

逻辑卷管理器 (LVM) 简介

古老的 e5 主机目前有这些存储设备 (硬盘): 系统盘 (M.2 NVMe SSD 480GB), 数据盘 (3.5 英寸 SATA 硬盘 4TB x2). 窝决定使用 LVM 对数据盘进行管理. 逻辑卷管理器 (LVM) 可以认为是一种 (单机) 存储虚拟化 技术. 多个物理存储设备 (PV) 组成一个存储池 (VG), 然后划分虚拟分区…...

Swift开发——弱占用

自动引用计数(Automatic Reference Counting&#xff0c;ARC)&#xff0c;是Swift语言管理类的实例的方式。当创建某个类的一个新实例后&#xff0c;ARC自动为新实例分配内存空间&#xff0c;用于保存实例的类型和存储属性&#xff0c;当将该实例赋给常量、变量或其他实例的属性…...

化工电力系统RFID无线测温技术的重要性。

在现代工业体系中&#xff0c;化工电力系统的安全与效率对于整个生产链的顺畅运行至关重要。在日常工作中,由于设备制造的原因,设备受环境污染的原因、设备长期运行、严重超载运行、触点氧化、电弧冲击等原因造接触电阻增大,因此在运行时往往不断发热,温度不断上升,给设备安全运…...

Linux系统:线程互斥

Linux系统&#xff1a;线程互斥 线程互斥互斥锁 mutex互斥锁原理 常见的锁死锁自旋锁 spinlock其它锁 线程互斥 讲解线程互斥前&#xff0c;先看到一个抢票案例&#xff1a; class customer { public:int _ticket_num 0;pthread_t _tid;string _name; };int g_ticket 10000…...

【网络协议栈】TCP/IP相关知识点收集

TCP/IP知识点收集 1 TCP分段 在TCP/IP协议栈中&#xff0c;“MSS”&#xff08;Maximum Segment Size&#xff09;是一个关键参数&#xff0c;它指定了TCP协议在发送数据时可以使用的最大数据段&#xff08;segment&#xff09;的大小。这个参数是TCP连接建立时通过三次握手&…...

Java开发中的常用字段校验注解

在 Java 开发中&#xff0c;数据校验是确保应用程序的数据完整性和一致性的重要步骤。Java 提供了一系列注解来简化数据校验的过程&#xff0c;以下是一些常用的字段校验注解及其示例代码&#xff1a; NotNull NotNull 用于确保字段不为 null&#xff0c;适用于任何类型的字段…...

面试经验分享 | 24年6月某安全厂商HW面试经验

所面试的公司&#xff1a;某安全厂商 所在城市&#xff1a;安徽省 面试职位&#xff1a;蓝初 面试过程&#xff1a; 腾讯会议&#xff08;语音&#xff09; 面试过程&#xff1a;整体流程就是自我介绍加上一些问题问题balabalabala。。。由于面的是蓝队所以渗透部分不会太多…...

JSON学习

一、JSON 1.1 简介 JSON&#xff1a;JavaScript Object Notation是一种表示对象的方式 基于JavaScript语言的轻量级的数据交换格式;&#xff08;即:用来传输数据的一种格式&#xff09; 现在传输数据的方式更多是采用json的格式&#xff0c;渐渐代替了XML 1.2 JSON的数据表示 …...

LabVIEW在中国航天中的应用

​LabVIEW是一种系统设计平台及开发环境&#xff0c;由美国国家仪器公司&#xff08;NI&#xff09;开发。它在中国航天领域的应用非常广泛&#xff0c;涵盖了测试与测量、数据采集、控制系统设计等多个方面。以下是LabVIEW在中国航天中的几个主要应用实例&#xff1a; 1. 测试…...

编程思维的培养

培养编程思维是成为一名优秀程序员的重要步骤。编程思维不仅仅是写代码的能力&#xff0c;还包括解决问题的思维方式、对复杂系统的理解、代码优化的意识、团队合作的能力等。以下是一些培养编程思维的方法和建议。 1. 学习基础知识 1.1 掌握编程语言 从一门编程语言开始&am…...

Docker笔记-Debian容器内搭建ssh服务

登陆容器之后修改密码&#xff1a; passwd 密码设置完成后安装openssh-server apt-get install openssh-server 修改端口号为50022并添加配置 vim /etc/ssh/sshd_config 修改成 Port 50022 PasswordAuthentication yes PermitRootLogin yes 启动 rootlinux:~# /etc/in…...

爬虫的法律风险是什么?以及合法使用爬虫技术的建议。

爬虫的法律风险是什么&#xff1f; 网络爬虫技术&#xff0c;虽然在数据获取方面具有巨大优势&#xff0c;但其使用过程中可能引发的法律风险也不容忽视。这些风险主要包括违反数据保护法规、侵犯知识产权、构成不正当竞争等。下面将详细探讨网络爬虫的法律风险&#xff0c;并在…...

微信小程序允许相机访问相册

// 允许从相机和相册扫码 // uni.scanCode({ // success: function(res) { // console.log(条码类型&#xff1a; res.scanType); // console.log(条码内容&#xff1a; res.result); …...

AMEYA360 | 江苏润石最新发布12颗车规级模拟芯片

日前江苏润石再度新增12颗通过AEC-Q100 Grade1&#xff0c;满足MSL 1湿敏等级认证的车规级芯片。截止目前&#xff0c;润石科技总计有70颗Grade1 & MSL1的车规级芯片通过认证并进入量产。凭借卓越的产品技术指标和稳定的品质性能不仅展示了公司在车规级模拟芯片领域的技术积…...

PHP表单设计:确保必需字段完整性的最佳实践

在开发网页应用程序时&#xff0c;设计一个具有必需字段的PHP表单是至关重要的。必需字段是用户提交表单时必须填写的信息&#xff0c;它们对于确保数据完整性和准确性至关重要。本文将从多个方面讨论如何在PHP表单中设计必需字段&#xff0c;并探讨确保表单数据完整性的最佳实…...

CentOS 7 安装部署Cassandra4.1.5

一、Cassandra的介绍 Cassandra是一套开源分布式NoSQL数据库系统。它最初由Facebook开发&#xff0c;用于储存收件箱等简单格式数据&#xff0c;集GoogleBigTable的数据模型与Amazon Dynamo的完全分布式的架构于一身Facebook于2008将 Cassandra 开源&#xff0c;此后&#xff0…...

【数据结构与算法】对称矩阵,三角矩阵 详解

给出对称矩阵、三角矩阵的节省内存的存贮结构并写出相应的输入、输出算法。 对称矩阵和三角矩阵可以通过特殊的存储结构来节省内存。这种存储结构只存储矩阵的一部分元素&#xff0c;而不是全部元素。 对称矩阵&#xff1a;对于一个n阶对称矩阵&#xff0c;我们只需要存储主对…...

Apache IoTDB 走进东南大学,深入分享项目发展历程与收获

源于高校&#xff0c;回到高校&#xff0c;Apache IoTDB PMC 成员乔嘉林为同学们详细分享行业前瞻、研发历程与心得体会。 01 把领先的数据库知识带到校园 6 月 5 日&#xff0c;东南大学计算机科学与工程学院、软件学院、人工智能学院主办的“拔尖领航系列活动特别策划篇-第二…...

Stable Diffusion AI绘画助力建筑设计艺术创新——城市建筑设计大模型分享

大家好&#xff0c;我是向阳 今天我将针对建筑设计方面的AI大模型进行简单介绍&#xff0c;我们将通过富有想象力的关键词或结合Stable Diffusion 的ControlNet 给原本只有黑白线条的线稿变成彩色的效果图&#xff0c;可能你只需要短短几分钟就可以让黑白线稿变成几种甚至十几种…...

没有 ADetailer,ComfyUI 画图脸崩了怎么办?

我们都知道 SD 的 WebUI 中的面部修复神器是 ADetailer&#xff0c;不过它是 WebUI 的专属插件&#xff0c;在 ComfyUI 中是搜索不到这个插件的&#xff0c;但是并不代表 ComfyUI 就不能使用面部修复功能了&#xff0c;ComfyUI 中也是可以找到平替的。 今天我们就来讲讲在 Com…...

防爆气象仪的工作原理

TH-WFB5矿山气象传感器在矿山安全监测系统中扮演着至关重要的角色&#xff0c;它们能够及时发现异常情况&#xff0c;为矿山的安全运营提供可靠的数据支持。矿山气象传感器能够实时监测矿山环境中的风速、风向、温度、湿度和大气压力等关键气象参数。这些传感器采用先进的传感技…...

深度学习入门5——为什么神经网络可以学习?

在理解神经网络的可学习性之前&#xff0c;需要先从数学中的导数、数值微分、偏导数、梯度等概念入手&#xff0c;从而理解为什么神经网络具备学习能力。 1.数值微分的定义 先从导数出发理解什么是梯度。某一点的导数直观理解就是在该点的切线的斜率。在数学中导数表示某个瞬…...

Integer溢出问题

0. 背景 在刷 LeetCode 时&#xff0c;代码的执行结果与预期出现了偏差&#xff0c;原因是 Int 值超过了允许范围 [ − 2 31 , 2 31 − 1 ] [-2^{31},2^{31}-1 ] [−231,231−1]。工作中从来没有遇到过这种情况&#xff0c;之前的认知是如果 Int 中存储的值超过了允许范围也许…...

软件测试全面指南:提升软件质量的系统流程

一、引言 随着软件行业的飞速发展&#xff0c;确保软件质量、稳定性和用户体验已成为企业竞争的关键。本文档旨在为测试团队提供一套全面的软件测试指南&#xff0c;通过规范测试用例管理、功能测试、接口测试、性能测试及缺陷管理等流程&#xff0c;助力测试团队实现高效、系统…...

《逆贫大叔》:一部穿越时光的温情史诗

《逆贫大叔》&#xff1a;一部穿越时光的温情史诗 在历史的长河中&#xff0c;有些故事能够穿越时光的尘埃&#xff0c;直击人心。《逆贫大叔》就是这样一部作品&#xff0c;它不仅是一部电视剧&#xff0c;更是一段历史的缩影&#xff0c;一次心灵的触动。 背景设定&#xff1…...

【电机控制】FOC算法验证步骤——PWM、ADC

【电机控制】FOC算法验证步骤 文章目录 前言一、PWM——不接电机1、PWMA-H-50%2、PWMB-H-25%3、PWMC-H-0%4、PWMA-L-50%5、PWMB-L-75%6、PWMC-L-100% 二、ADC——不接电机1.电流零点稳定性、ADC读取的OFFSET2.电流钳准备3.运放电路分析1.电路OFFSET2.AOP3.采样电路的采样值范围…...

如何衡量llm 数据集的多样性

衡量大型语言模型&#xff08;LLM&#xff09;数据集的多样性是一个复杂的问题&#xff0c;因为多样性可以从多个角度来考虑。以下是一些常用的方法和指标来评估数据集的多样性&#xff1a; 词汇多样性&#xff1a; 类型-词符比&#xff08;Type-Token Ratio, TTR&#xff09;…...

编程天才是什么意思

编程天才是什么意思 编程天才&#xff0c;这个词汇似乎充满了神秘与敬畏的色彩。那么&#xff0c;它究竟意味着什么呢&#xff1f;在本文中&#xff0c;我们将从四个方面、五个方面、六个方面和七个方面深入探讨编程天才的内涵与外延&#xff0c;带您领略这一领域的独特魅力。…...

创建npm私包

参考文章&#xff1a; 使用双重身份验证访问 npm | npm 中文网 私有npm包的实例详解-js教程-PHP中文网 1.注册npm账号 npm官网&#xff1a; npm | Home 2.安装node 百度挺多的&#xff0c;安装完后&#xff0c;检查是否安装成功就行 3.写一个简单的模块 创建个文件夹&am…...

provider追加android:name的命名有哪些?

在Android中&#xff0c;为<provider>元素添加android:name属性时&#xff0c;命名应遵循Android组件的命名规范和包名的命名规范。以下是一些关于命名android:name的要点&#xff1a; 包名前缀&#xff1a;android:name属性的值通常应以包名开始&#xff0c;这是应用程序…...

新的南宁网站建设公司/代理广告投放平台

点击上方“Java之间”&#xff0c;选择“置顶或者星标”你关注的就是我关心的&#xff01;作者&#xff1a;Apocalypsa一、简介毕业答辩搞定&#xff0c;总算可以闲一段时间&#xff0c;把这段求职经历写出来&#xff0c;也作为之前三个半月的求职的回顾。首先说说我拿到的offe…...

做网站最简单/软文广告范例大全

目录第一章 Discord账号注册第二章 Discord创建服务器第三章 Discord创建机器人3.1、创建应用3.2、创建机器人3.3、配置机器人3.4、添加机器人第四章 Discord机器人开发准备4.1、推荐资料4.2、创建工程4.3、添加依赖4.4、获取Token4.5、编写主类第五章 Discord机器人开发初级5.…...

购物帮做特惠的导购网站/北京seo网络优化招聘网

在edge浏览器下载tampermonkey 然后 这个网站 安装出来 再下载 https://www.lanzoui.com/b0ev69v1i 中文免激活绿色版(是一个IDM下载器) 下载完成后运行绿化.bat 把要下载的东西搞个分享链接 复制链接在edge浏览器打开 点击网盘工具箱直链 配置卡密 如果出现查询失败 就是需要…...

wordpress 4.8上传漏洞/seo搜索规则

这篇文章我会推荐一些优质的 Spring Boot 开源教程 和 Spring Boot 实战项目&#xff0c;帮助大家深入学习 Spring Boot。项目质量的话&#xff0c;大家可以放心。 不会 Spring Boot 或者想要深入学习 Spring Boot 的小伙伴直接学起来好吧&#xff01;&#xff08;♂️不需要 …...

页面模板怎么修改/seo 网站排名

因为题目的数据处理起来比较乱&#xff0c;我们平时在学习的时候一定要学习这种规范的数据存储方式&#xff1a; 上图中&#xff0c;nodes那个数据&#xff0c;只是在for循环中暂存的&#xff0c;他把结果过渡到res的结果集中。...

wordpress 文章字体/cfa一级看多久两分钟

我有一个在经纬度网格上的数据集。我需要从这个数据集中选择一个近乎完美的“矩形”覆盖北美。某物&#xff0c;但位于北美上空&#xff1a;1。我如何选择纬度和经度&#xff1f;因为经度向两极靠拢&#xff0c;所以我需要更多的经度往北。在这是我的拙劣和可能不正确的尝试。我…...