{"msg":"操作成功","code":200,"data":{"createBy":"admin","createTime":"2019-12-23 16:35:28","updateBy":"admin","updateTime":"2025-08-23 15:57:29","remark":null,"id":9,"articleTitle":"Linux基础：LVM介绍","articleUrl":"linux_lvm","articleThumbnail":"https://www.asumimoe.com/imgfiles/20220908/ee03af4419724d50a127c34d6a588554.png","articleFlag":"0","draftStatus":"1","reprintStatement":"1","articleSummary":"LVM (Logical Volume Manager) 是 Linux 内核提供的一种强大的磁盘管理机制。它在物理硬盘和文件系统之间增加了一个抽象层，允许管理员创建一个“存储池”，并从中动态地划分和调整逻辑存储空间。","articleContent":"## 1.LVM 概述\n\n### 什么是 LVM？\n\nLVM (Logical Volume Manager) 是 Linux 内核提供的一种强大的磁盘管理机制。它在物理硬盘和文件系统之间增加了一个抽象层，允许管理员创建一个“存储池”，并从中动态地划分和调整逻辑存储空间。\n\n### 为什么使用 LVM？\n\n*   **灵活的容量管理**：可以动态地调整逻辑卷的大小，无需重启。\n*   **抽象的存储池**：将多个物理磁盘/分区聚合为一个大的卷组，突破物理磁盘大小的限制。\n*   **在线数据迁移**：支持将数据从一个物理磁盘移动到另一个，无需卸载文件系统。\n*   **快照功能**：可以创建逻辑卷的瞬时只读或读写副本，用于备份或测试。\n*   **条带化和镜像**：支持类似 RAID 0 和 RAID 1 的功能，提升性能或可靠性。\n\n### 核心组件\n\n*   **物理卷 (PV)**：最底层的物理存储单元，可以是整块磁盘 (`/dev/sdb`)、MBR 或 GPT 分区。PV 是构成 LVM 的基础块。\n*   **卷组 (VG)**：由一个或多个 PV 组成的存储池。LVM 将所有的 PV 空间打碎成一个个小的 **PE (Physical Extents)**，默认大小为 4MiB。VG 的大小就是所有 PV 的 PE 数量之和。\n*   **逻辑卷 (LV)**：从 VG 中划分出的逻辑存储空间，由多个 PE 组成。LV 可以被格式化并挂载到文件系统树上使用，例如 `/home` 或 `/data`。它是用户最终操作的对象。\n\n**关系链**： **PV** → 加入 → **VG** → 划分出 → **LV** → 格式化为 → **文件系统** → 挂载到 → **目录**\n\n---\n\n## 2.管理物理卷 (PV)\n\n### 创建 PV\n\n假设我们有一块新硬盘 `/dev/sdb`。\n\n```bash\n# 使用整块磁盘创建 PV\npvcreate /dev/sdb\n\n# 也可以先使用 fdisk/gdisk 创建分区并将类型标记为 ‘Linux LVM’ (8e)，然后再创建 PV\n# fdisk /dev/sdb -> n -> p -> 1 -> ... -> t -> 8e -> w\npvcreate /dev/sdb1\n```\n\n### 查看 PV 信息\n\n```bash\npvs\t\t\t\t# 简明信息列表\npvdisplay\t\t\t# 详细信息\npvscan\t\t\t\t# 扫描系统中所有的 PV\n```\n\n### 移除 PV\n\n在从 VG 中移除 PV 后（见下文），可以移除 PV 标签。\n\n```bash\npvremove /dev/sdb1\n```\n\n---\n\n## 3.管理卷组 (VG)\n\n### 创建 VG\n\n使用一个或多个 PV 创建名为 `vg_data` 的卷组。\n\n```bash\nvgcreate vg_data /dev/sdb1 /dev/sdc1\n# 可以使用 -s 选项指定 PE 大小，如 ‘vgcreate -s 8M vg_data /dev/sdb1’\n```\n\n### 查看 VG 信息\n\n```bash\nvgs\t\t\t\t# 简明信息列表\nvgdisplay\t\t\t# 详细信息\n# 查看特定 VG 的剩余空间\nvgdisplay vg_data | grep \"Free PE\"\n```\n\n### 扩展 VG (添加新磁盘)\n\n当 VG 空间不足时，可以添加新的 PV。\n\n```bash\n# 假设新硬盘 /dev/sdd 已初始化为 PV\nvgextend vg_data /dev/sdd1\n```\n\n### 缩减 VG (移除磁盘)\n\n在移除一个 PV 前，必须先将该 PV 上的数据转移到 VG 中的其他 PV 上。\n\n```bash\n# 1. 检查 PV 上的数据分布\npvs -o+pv_used\n\n# 2. 将数据从 /dev/sdb1 移出 (确保 VG 中有其他 PV 且有足够空间)\npvmove /dev/sdb1\n\n# 3. 将 /dev/sdb1 从 VG 中移除\nvgreduce vg_data /dev/sdb1\n\n# 4. 此时可以移除 PV (pvremove)\n```\n\n### 删除 VG\n\n必须先删除 VG 中的所有 LV。\n\n```bash\nvgremove vg_data\n```\n\n---\n\n## 4.管理逻辑卷 (LV)\n\n### 创建 LV\n\n从 `vg_data` 卷组中创建逻辑卷。\n\n```bash\n# 创建固定大小的 LV (20G)，命名为 lv_files\nlvcreate -L 20G -n lv_files vg_data\n\n# 使用卷组所有剩余空间创建 LV\nlvcreate -l 100%FREE -n lv_files vg_data\n\n# 创建指定 PE 数量的 LV\nlvcreate -l 512 -n lv_files vg_data\n```\n\n### 查看 LV 信息\n\n```bash\nlvs\t\t\t\t# 简明信息列表\nlvdisplay\t\t\t# 详细信息\n```\n\n### 格式化与挂载\n\nLV 设备文件通常位于 `/dev/mapper/` 或 `/dev/VG_NAME/`。\n\n```bash\n# 格式化 (选择一种文件系统)\nmkfs.xfs /dev/vg_data/lv_files    # CentOS 7 默认\n# 或\nmkfs.ext4 /dev/vg_data/lv_files\n\n# 创建挂载点并挂载\nmkdir /data\nmount /dev/vg_data/lv_files /data\n```\n\n### 扩展 LV (在线扩容)\n\n这是 LVM 最常用的功能。**第一步扩展 LV 大小，第二步扩展文件系统。**\n\n```bash\n# 1. 扩展 LV 本身 (增加 10G)\nlvextend -L +10G /dev/vg_data/lv_files\n# 或扩展到绝对大小 30G\n# lvextend -L 30G /dev/vg_data/lv_files\n\n# 2. 扩展文件系统以使用新空间\n# 对于 XFS 文件系统：\nxfs_growfs /data\n# 对于 ext4 文件系统：\n# resize2fs /dev/vg_data/lv_files\n```\n\n### 缩减 LV (极其谨慎！)\n\n**警告：XFS 不支持缩减！ext4 可以，但风险极高，必须提前备份数据！**\n\n```bash\n# 1. 卸载文件系统\numount /data\n\n# 2. 强制检查文件系统 (ext4)\ne2fsck -f /dev/vg_data/lv_files\n\n# 3. 缩减文件系统 (先做！)\nresize2fs /dev/vg_data/lv_files 15G # 缩减到 15G\n\n# 4. 缩减 LV\nlvreduce -L 15G /dev/vg_data/lv_files\n\n# 5. 重新挂载\nmount /dev/vg_data/lv_files /data\n```\n\n### 删除 LV\n\n```bash\n# 确保已卸载\nlvremove /dev/vg_data/lv_files\n```\n\n### LV 重命名\n\n```bash\nlvrename vg_data lv_oldname lv_newname\n```\n\n---\n\n## 5.高级主题\n\n### LV 快照\n\n快照是原 LV 在某个时间点的只读或读写副本，常用于备份。\n\n```bash\n# 创建一个大小为 1G 的只读快照 (大小取决于备份期间可能的数据变化量)\nlvcreate -L 1G -s -n lv_files_snapshot /dev/vg_data/lv_files\n\n# 挂载快照进行备份\nmkdir /mnt/snapshot\nmount -o ro /dev/vg_data/lv_files_snapshot /mnt/snapshot\n\n# 使用 rsync/tar 备份 /mnt/snapshot 中的数据\n# ...\n\n# 备份完成后，卸载并删除快照\numount /mnt/snapshot\nlvremove /dev/vg_data/lv_files_snapshot\n```\n\n### 使用 `fstab` 实现自动挂载\n\n为避免使用易变的设备路径，最好使用 UUID 或 `/dev/mapper/` 路径。\n\n```bash\n# 获取 LV 的 UUID\nblkid /dev/vg_data/lv_files\n\n# 编辑 /etc/fstab，添加如下一行：\n# UUID=xxxxxxxx-xxxx-...    /data    xfs    defaults    0 0\n# 或\n# /dev/mapper/vg_data-lv_files /data xfs defaults 0 0\n\n# 测试 fstab 配置是否正确\nmount -a\n```\n\n## 6.实战案例：扩展根 （ / ）文件系统\n\nlinux系统所有的文件都是存放在根分区中的，如果根分区容量即将耗尽，我们就需要给根分区扩容，我们可以使用lsblk命令来查看，系统的根分区实际是逻辑卷，所以想要扩展根分区只要将逻辑卷扩容就可以了。此时我的根分区容量为17G，已用12G，我想要给它扩展容量应该怎么做呢？\n\n**由于我是在虚拟机上做的实验，生产环境中一般会是raid，稍有不同，仅供学习之用。**\n\n```shell\n[root@v1 ~]# df -h\n文件系统             容量  已用  可用 已用% 挂载点\n/dev/mapper/cl-root   17G   12G  5.8G   66% /\ndevtmpfs             478M     0  478M    0% /dev\ntmpfs                489M     0  489M    0% /dev/shm\ntmpfs                489M  6.7M  482M    2% /run\ntmpfs                489M     0  489M    0% /sys/fs/cgroup\n/dev/sda1           1014M  139M  876M   14% /boot\ntmpfs                 98M     0   98M    0% /run/user/0\n/dev/sr0             4.1G  4.1G     0  100% /mnt\n\n[root@v1 ~]# lsblk\nNAME        MAJ:MIN RM  SIZE RO TYPE MOUNTPOINT\nsda           8:0    0   20G  0 disk \n├─sda1        8:1    0    1G  0 part /boot\n└─sda2        8:2    0   19G  0 part \n  ├─cl-root 253:0    0   17G  0 lvm  /\n  └─cl-swap 253:1    0    2G  0 lvm  [SWAP]\nsr0          11:0    1  4.1G  0 rom  /mnt\n```\n\n### 新添加一块磁盘\n\n```bash\n[root@v1 ~]# lsblk\nNAME        MAJ:MIN RM  SIZE RO TYPE MOUNTPOINT\nsda           8:0    0   20G  0 disk \n├─sda1        8:1    0    1G  0 part /boot\n└─sda2        8:2    0   19G  0 part \n  ├─cl-root 253:0    0   17G  0 lvm  /\n  └─cl-swap 253:1    0    2G  0 lvm  [SWAP]\nsdb           8:16   0   10G  0 disk \nsr0          11:0    1  4.1G  0 rom \n```\n\n### 将新添加的磁盘进行分区\n\n```bash\n[root@v1 ~]# fdisk /dev/sdb\n欢迎使用 fdisk (util-linux 2.23.2)。\n\n更改将停留在内存中，直到您决定将更改写入磁盘。\n使用写入命令前请三思。\n\nDevice does not contain a recognized partition table\n使用磁盘标识符 0x0d87e961 创建新的 DOS 磁盘标签。\n\n命令(输入 m 获取帮助)：n\nPartition type:\n   p   primary (0 primary, 0 extended, 4 free)\n   e   extended\nSelect (default p): \nUsing default response p\n分区号 (1-4，默认 1)：\n起始 扇区 (2048-20971519，默认为 2048)：\n将使用默认值 2048\nLast 扇区, +扇区 or +size{K,M,G} (2048-20971519，默认为 20971519)：\n将使用默认值 20971519\n分区 1 已设置为 Linux 类型，大小设为 10 GiB\n命令(输入 m 获取帮助)：w\nThe partition table has been altered!\n\nCalling ioctl() to re-read partition table.\n正在同步磁盘。\n\n[root@v1 ~]# lsblk\nNAME        MAJ:MIN RM  SIZE RO TYPE MOUNTPOINT\nsda           8:0    0   20G  0 disk \n├─sda1        8:1    0    1G  0 part /boot\n└─sda2        8:2    0   19G  0 part \n  ├─cl-root 253:0    0   17G  0 lvm  /\n  └─cl-swap 253:1    0    2G  0 lvm  [SWAP]\nsdb           8:16   0   10G  0 disk \n└─sdb1        8:17   0   10G  0 part \nsr0          11:0    1  4.1G  0 rom  \n```\n\n如果未识别到新分区，使用partprobe命令加载即可。\n\n### 将新分区sdb1创建为物理卷\n\n```bash\n[root@v1 ~]# pvcreate /dev/sdb1\n  Physical volume \"/dev/sdb1\" successfully created.\n```\n\n### 将创建好的物理卷扩展到根分区所在卷组\n\n```bash\n[root@v1 ~]# vgdisplay -v\n  --- Volume group ---\n  VG Name               cl\n  System ID             \n  Format                lvm2\n  Metadata Areas        2\n  Metadata Sequence No  4\n  VG Access             read/write\n  VG Status             resizable\n  MAX LV                0\n  Cur LV                2\n  Open LV               2\n  Max PV                0\n  Cur PV                2\n  Act PV                2\n  VG Size               28.99 GiB\n  PE Size               4.00 MiB\n  Total PE              7422\n  Alloc PE / Size       4863 / 19.00 GiB\n  Free  PE / Size       2559 / 10.00 GiB\n  VG UUID               oKc6Ae-l0QZ-xNir-7U0d-sH4K-HTtN-RDm4hl\n   \n  --- Logical volume ---\n  LV Path                /dev/cl/swap\n  LV Name                swap\n  VG Name                cl\n  LV UUID                6ENYna-OkIl-avmF-m977-tE4z-8iCO-VyVC44\n  LV Write Access        read/write\n  LV Creation host, time localhost.localdomain, 2019-05-29 19:59:53 +0800\n  LV Status              available\n  # open                 2\n  LV Size                2.00 GiB\n  Current LE             512\n  Segments               1\n  Allocation             inherit\n  Read ahead sectors     auto\n  - currently set to     8192\n  Block device           253:1\n   \n  --- Logical volume ---\n  LV Path                /dev/cl/root　　这个是根分区所挂载的逻辑卷路径\n  LV Name                root\n  VG Name                cl　　这个是根分区所在卷组名字\n  LV UUID                IS5BXN-jIrh-lrr5-mp7O-SAU5-YLSt-MMWcdC\n  LV Write Access        read/write\n  LV Creation host, time localhost.localdomain, 2019-05-29 19:59:53 +0800\n  LV Status              available\n  # open                 1\n  LV Size                17.00 GiB\n  Current LE             4351\n  Segments               1\n  Allocation             inherit\n  Read ahead sectors     auto\n  - currently set to     8192\n  Block device           253:0\n   \n  --- Physical volumes ---\n  PV Name               /dev/sda2     \n  PV UUID               YRWhHU-7nfd-cJkw-uhNG-iW7U-Z8ZB-3n2IHG\n  PV Status             allocatable\n  Total PE / Free PE    4863 / 0\n\n  PV Name               /dev/sdb1     \n  PV UUID               OIu5Ny-VPsy-w0f8-O1Y1-QtOU-Ayey-3Hb9Om\n  PV Status             allocatable\n  Total PE / Free PE    2559 / 2559　　我们发现此物理卷上可用的PE为全部\n```\n\n扩展卷组容量\n\n```bash\n[root@v1 ~]# vgextend cl /dev/sdb1\n  Volume group \"cl\" successfully extended\n```\n\n### 扩展根分区所挂载的逻辑卷\n\n```bash\n[root@v1 ~]# lvextend -l +100%FREE /dev/cl/root　　将剩余可用容量全部扩展到/dev/cl/root\n  Size of logical volume cl/root changed from 17.00 GiB (4351 extents) to 26.99 GiB (6910 extents).\n  Logical volume cl/root successfully resized.\n\n[root@v1 ~]# xfs_growfs /dev/cl/root\nmeta-data=/dev/mapper/cl-root    isize=512    agcount=4, agsize=1113856 blks\n         =                       sectsz=512   attr=2, projid32bit=1\n         =                       crc=1        finobt=0 spinodes=0\ndata     =                       bsize=4096   blocks=4455424, imaxpct=25\n         =                       sunit=0      swidth=0 blks\nnaming   =version 2              bsize=4096   ascii-ci=0 ftype=1\nlog      =internal               bsize=4096   blocks=2560, version=2\n         =                       sectsz=512   sunit=0 blks, lazy-count=1\nrealtime =none                   extsz=4096   blocks=0, rtextents=0\ndata blocks changed from 4455424 to 707584\n```\n\n### 查看扩展后的根分区容量\n\n```bash\n[root@v1 ~]# df -h\n文件系统             容量  已用  可用 已用% 挂载点\n/dev/mapper/cl-root   27G   12G   16G   42% /　　根分区容量已经被扩展到27G\ndevtmpfs             478M     0  478M    0% /dev\ntmpfs                489M     0  489M    0% /dev/shm\ntmpfs                489M  6.7M  482M    2% /run\ntmpfs                489M     0  489M    0% /sys/fs/cgroup\n/dev/sda1           1014M  139M  876M   14% /boot\ntmpfs                 98M     0   98M    0% /run/user/0\n```\n\n","categoryId":1,"viewCount":1120,"categoryName":"Linux","author":"球接子","authorAvatar":null,"tagIds":[10],"tagNames":["Linux基础"]}}