资讯动态

从裸盘到LVM:Linux逻辑卷在线扩容实战与踩坑记录

发布时间:2026/9/30 3:07:21 来源:尧图企业网站定制
两周前的凌晨一点我被一通电话吵醒业务库报错“磁盘空间不足无法写入”。登录服务器一看那台机器数据盘 Usage 已经是 100%临时日志都进不去了。最让我头疼的不是空间满了而是这块盘当初是裸盘单分区直接挂载的想扩容必须停机、拔盘、换更大盘、重新分区做文件系统再想办法把数据搬回来。那天晚上我一边紧急找没用的目录删文件救火一边在心里发誓以后所有项目的数据盘一律用 LVM 管。这篇东西就是那次事故之后整理出来的实操记录。我会从 LVM 的三个基本概念讲起到裸盘创建 LVM 卷、格式化挂载、再到业务运行中在线扩容的完整链路最后把我在生产环境踩过的坑和排查思路一并写出来。适合三类人看正在学 Linux 的小白、刚接手服务器想理顺磁盘规划的新运维、以及想把手头几台机器统一纳入 LVM 管理的老手。整套方法在 CentOS、Ubuntu、麒麟这类主流发行版上都适用步骤不会差太多。提到 LVM很多人的第一反应是“我这机器就一块盘用不上”。这个想法我能理解但说实话是个误区。磁盘管理最尴尬的从来不是“现在不够用”而是“三年后不够用”的时候——你当初根本没法预料业务增长曲线。与其到时候手足无措不如从一开始就留着 LVM 这个后手。1. 传统分区的硬伤正好是 LVM 的出发点1.1 单磁盘、单分区的扩容困境传统做法是一块物理盘分一个或几个区每个区格式化之后挂到某个目录。看起来清爽但有一个致命问题——文件系统的大小在创建那一刻就被固定了。业务跑着跑着某个分区满了你想扩容要么找一块更大的盘把数据整个搬过去要么只能在旁边加一块新盘把新目录挂上去。但原来的挂载路径又不能随便改业务侧往往还不想改路径这就非常难受。更麻烦的是某些文件系统在挂载状态下是不能直接做缩小的xfs 和 ext4 在这方面差异很大后面我会专门讲。一旦规划失误修复成本非常高。如果当初只是单盘整块格式化没有做任何抽象层那个“抽象的缓冲”就不存在扩容基本等于搬家中间还必然有停机窗口。我现在给团队定的规矩很简单系统盘保持传统分区不乱动数据盘尽量纳入 LVM。系统盘卷组一旦出问题牵一发动全身数据盘用 LVM日常扩容、备份、快照都非常顺手。这个边界很多教程不会讲但实际运维时非常关键。1.2 PV、VG、LV一套“乐高积木”式的抽象层LVM 全称是 Logical Volume Manager逻辑卷管理器。它介于物理磁盘和文件系统之间插入了一层逻辑映射。理解这层映射只需要记住三个缩写PVPhysical Volume物理卷。把一块硬盘或一个分区标记成“可以被 LVM 管理”的状态这一步相当于把积木块打磨成标准尺寸。VGVolume Group卷组。把多个 PV 拼成一个统一的“空间池”相当于把所有积木块拼成一个大底板。LVLogical Volume逻辑卷。从这个空间池里按需划出一块“逻辑磁盘”格式化之后挂载使用。打个比方PV 是乐高积木单块VG 是拼好的大底板LV 是从底板上按需掰下来的那个零件。要加零件就往底板上多拼一块积木要让零件变大只要底板还有剩余空间用 lvextend 往外面扩就行。但如果是传统分区积木块出厂是多大就是多大想变大只能重新拼搭。1.3 LVM 的代价不是零成本但值得LVM 不是没有代价的。多了一层逻辑映射IO 多多少少会有额外开销在现代服务器上小到几乎可以忽略但如果你的存储本身就由阵列或 NAS 提供再叠加单块盘堆到数十 TB 的极限场景LVM 的收益确实需要重新权衡。多块裸盘直接做 PV 的场景下硬件故障兜底应该靠 RAID 或上层存储系统而不是指望 LVM 本身来保证数据安全。所以我给大多数中等规模业务场景的建议是如果你的机器是物理机加多块数据盘或者虚拟机里挂载了独立数据盘LVM 可以作为默认选项。它让你从“磁盘规划问题”里解放出来以后加盘、扩容、做快照都是几分钟的事。如果你只是跑一个轻量容器、一块盘随便用用那确实没必要为了用 LVM 而 LVM。2. 环境准备确认内核支持、安装工具与磁盘规划2.1 三行命令确认环境并安装 LVM 管理工具大部分主流 Linux 发行版的内核都原生支持 LVM你甚至不需要额外加载模块。不过管理工具链是另外一回事CentOS/RHEL 系默认会带Ubuntu/Debian 有时需要自己装。我一般先用一条命令确认系统里有没有相关工具which pvcreate vgcreate lvcreate lvextend如果没有任何输出就说明缺包。CentOS/RHEL 系装 LVM2 工具集sudo yum install -y lvm2Ubuntu/Debian 系sudo apt install -y lvm2安装完成后建议顺手执行一次sudo pvscan或sudo lvm version确认命令能正常跑起来。这一步看着简单但我在一些精简版国产操作系统上还真遇到过 lvm2 没有随系统预装的情况尤其是用容器镜像或嵌入式系统改造的服务器最容易漏。2.2 识别磁盘设备名别把系统盘搭进去准备工作的重心不是装软件而是把磁盘认清楚。服务器上常见的设备命名规律是/dev/sda通常是系统盘/dev/sdb、/dev/sdc这类是后来的数据盘VMware 或 KVM 虚拟机里也可能是vdX、nvmeXnYpZ这些命名。一定要先跑下面两条命令lsblk fdisk -llsblk输出非常直观能一眼看到每个设备的大小、挂载点和文件系统类型。我强烈建议在看清楚之前不要执行任何创建命令。之前有个同事就是没仔细看直接pvcreate /dev/sda差点把系统盘给弄成物理卷。虽然不至于立刻丢失数据但后续清理非常麻烦。磁盘规划阶段还有一个小建议一块全新的数据盘你既可以整块盘直接做 PV也可以先分成一个分区比如/dev/sdb1再做 PV。分区的做法更稳妥因为后期的标识更清晰也方便和某些上层软件比如部分虚拟化平台对接。分区的话用fdisk /dev/sdb交互式建一个主分区类型保持默认的 Linux filesystem 就行不需要特意改成 LVM 类型改了也没关系——LVM 在pvcreate时并不强制校验分区类型。2.3 留足卷组的“弹性空间”创建 VG 的时候我常看到一个新手误区把整块盘全部划入 VG然后立刻把 LV 也建到 100% 容量。这样做不是不行但 LVM 最大的价值之一——弹性——就完全没发挥出来。我的习惯是初始 LV 只占 VG 的 60% 到 80%留下部分空间作为“机动储备”。举个实际场景某条业务线的数据目录我一开始建了 200G 的 LVVG 里还留着 80G 空闲。过了半年业务涨得比预期快200G 快满了我只需要lvextend -L 50G把机动储备划进去业务零中断。如果没有预留空间就得临时加物理盘、扩展 VG再把空间划给 LV虽然也支持在线做但整个操作链就长了。另一个细节是 PEPhysical Extent大小。创建 VG 时可以用-s参数指定 PE 大小比如vgcreate -s 16M data_vg /dev/sdb1。PE 是 LVM 分配空间的最小单位默认一般是 4MB。如果卷组很大、容量达到数十 TB默认 4MB 的 PE 数量会非常庞大可以在创建卷组时调大到 16MB 或 32MB。对于普通几 TB 的磁盘保持默认即可不必过度优化。3. 从裸盘到可挂载卷PV、VG、LV 三步走3.1 创建 PV 并确认状态假设服务器新加了一块 400G 的数据盘设备名是/dev/sdb已经用 fdisk 分好区得到/dev/sdb1。第一步就是把它初始化为物理卷sudo pvcreate /dev/sdb1执行完可以用两条命令检查状态sudo pvs sudo pvdisplay /dev/sdb1pvs输出的信息比较精炼能看到 PV 名称、所属 VG、PV 大小和空闲空间pvdisplay则更详细会显示 PE 大小、PV UUID 这些信息。创建完之后如果pvs里显示 VG 那一列为空说明 PV 还没有加入任何卷组这是正常的。这里分享一个我自己的习惯给物理卷打好标签。虽然 LVM 有 UUID 机制但设备名会漂移所以我在云服务器上一般会同时做一层 udev 规则固化磁盘名或者在维护文档里记录 PV 对应的物理盘位置。裸奔的服务器上这一条对老手来说也是不可忽视的纪律。3.2 创建 VG 与 LV把刚才创建的 PV 变成一个卷组我通常这样命名卷组名用vg前缀加用途逻辑卷名用lv前缀加目录用途。这样lsblk或/dev/mapper/下看到名字就能猜出大概用途排查问题时非常省心。sudo vgcreate data_vg /dev/sdb1创建后运行sudo vgs或者sudo vgdisplay data_vg重点看 VG Size 和 Free PE / Alloc PE 这两项。Free PE 就是后面扩容时能支配的“储备空间”。然后创建逻辑卷。比如我要挂载到/data打算先分配 300Gsudo lvcreate -L 300G -n data_lv data_vg-n指定逻辑卷名-L指定大小。创建完成后设备路径会是/dev/data_vg/data_lv同时在/dev/mapper/data_vg-data_lv下也会出现一个映射节点。不少新手会疑惑这两个路径有什么区别实际上两者指向同一个设备只是符号链接和映射设备名的关系。我习惯在命令里统一使用/dev/卷组名/逻辑卷名这种写法可读性更好。如果你更愿意用百分比而不是绝对值也可以这样写sudo lvcreate -l 100%FREE -n data_lv data_vg这样会把卷组剩余空间全部给 LV。但我前面提过不建议一次性划满否则后续要扩容就必须先加物理盘。3.3 格式化、挂载与开机自动挂载LV 设备创建后它还是一个没有文件系统的“空壳”。Linux 下不同发行版默认文件系统偏好不同CentOS 7/8 系默认推荐 xfsUbuntu 默认常用 ext4。我在生产上常用 ext4因为它可在线缩小虽然很少用排查工具也更丰富但如果你跑的是高并发大文件场景xfs 在大文件读写上往往更有优势。两种都支持在线扩容只是后续命令不同这里先统一用 ext4sudo mkfs.ext4 /dev/data_vg/data_lv然后临时挂载sudo mkdir -p /data sudo mount /dev/data_vg/data_lv /data这时候df -h /data就能看到新卷了。但临时挂载只是这次开机有效重启后就没了。要永久挂载需要写入/etc/fstab。我强烈建议不要直接写/dev/data_vg/data_lv到 fstab而是使用设备 UUID。因为设备路径在重启后可能因为内核识别顺序变化而变掉UUID 才是唯一稳定的标识sudo blkid /dev/data_vg/data_lv拿到类似UUIDxxxxxx的输出后写入 fstabUUIDxxxxxx /data ext4 defaults 0 2写完不要立刻重启先执行sudo mount -a测试一下配置能否被正确解析。如果输出没有报错再用df -h确认挂载成功。这一步可以避免很多“重启后系统卡死”的事故具体我会在踩坑章节详细说。4. 在线扩容实战lvextend 之后文件系统扩展才是关键4.1 扩容前的两个必查项在线扩容是 LVM 的核心卖点业务不中断命令敲完空间立刻变大。但在动手之前我每次都会核对两件事。第一卷组里有没有剩余空间。执行sudo vgs看 Free 那一列。如果 Free 是 0那你需要先做“加物理盘、扩展 VG”的操作如果有富余就继续往下走。第二确认逻辑卷当前的文件系统类型。这一步很多人会理所当然地跳过但它决定了后续扩展命令用哪个。用blkid或者lsblk -f就能看到ext4 对应resize2fsxfs 对应xfs_growfs两个命令不能混用。4.2 扩容 LV 与文件系统的正确操作顺序在线扩容容易犯的错是只扩展了 LV却没有扩展文件系统。LV 扩了但文件系统还是老大小df -h看起来自然没变化。正确的顺序是先扩展 LV再扩展文件系统。设备路径是/dev/data_vg/data_lv当前 300G卷组还有 100G 空闲想给工作目录加 80Gsudo lvextend -L 80G /dev/data_vg/data_lv-L 80G表示在当前大小基础上增加 80G。如果你想直接把 LV 扩到某个绝对值比如 380G也可以写-L 380G。如果用的是较新的 LVM2 版本其实有更省心的做法直接给lvextend加-r参数让它在扩容 LV 的同时自动调整文件系统大小sudo lvextend -r -L 80G /dev/data_vg/data_lv这个参数会根据 LV 上的文件系统类型自动调用resize2fs或xfs_growfs对于大多数场景都够用。但如果你所在的发行版 LVM 版本较老或者对文件系统扩展过程有精细化控制的需求还是建议一步步来# ext4 场景 sudo resize2fs /dev/data_vg/data_lv # xfs 场景注意参数不是设备路径而是挂载点 sudo xfs_growfs /data4.3 扩容后的验证与回滚思路命令敲完之后用两个维度验证sudo lvs df -h /datalvs会显示逻辑卷现在的真实大小df -h显示的是文件系统实际可用空间。两者都能对上扩容才算成功。之所以强调两个命令都看一眼是因为如果只看了lvs你可能会误以为文件系统也自动大了只看了df -h又可能错过 LV 层面没扩成功的情况。扩展操作一般不需要回滚因为它是增长性的。但如果是在扩容过程中发现业务负载异常升高比如扩展 ext4 时元数据操作量较大我的建议是不要在高峰期对大文件系统做 resize。其实 ext4 的在线 resize 已经相当成熟日常扩几百 G 基本不会有服务中断但高负载数据库场景下稳妥起见可以选在低谷期执行。4.4 多块物理盘加入 VG 再扩容完整流程前面提到过“卷组没空间了怎么办”这里补上一个完整例子。假设/dev/datavG的空间用完了手上又有一块新盘/dev/sdc# 1. 分区可选 sudo fdisk /dev/sdc # 2. 创建 PV sudo pvcreate /dev/sdc1 # 3. 扩展 VG sudo vgextend data_vg /dev/sdc1 # 4. 确认 VG 有了新空间 sudo vgs # 5. 再执行 lvextend resize sudo lvextend -r -L 100G /dev/data_vg/data_lv整条链路全程不需要卸载挂载点、不需要重启服务。我就经常在白天正常业务时对数据库数据目录做这种操作只要文件系统本身支持在线生长风险是可控的。这也是 LVM 相比传统分区最大的体验差异——把以前需要几小时停机窗口的工作压缩成了几条命令。5. 真实环境踩坑记录三种容易翻车的操作场景5.1 ext4 和 xfs 的扩展命令完全不同这个坑几乎是每个接触 LVM 的人都会遇到。resize2fs是 ext 系列文件系统的扩展命令而 xfs 文件系统对应的是xfs_growfs而且参数还不同一个是设备路径一个是挂载点。我有一次给一台 CentOS 7 的机器扩展数据盘当时系统默认文件系统是 xfs但我习惯性敲了resize2fs /dev/data_vg/data_lv直接报错resize2fs: Bad magic number in super-block。那一瞬间确认了文件系统类型改用xfs_growfs /data才正常完成。事后想想这个错误其实在blkid里早就能看出来我纯粹是肌肉记忆害了自己。对老手来说我的建议是把这个差异刻进操作习惯任何文件系统扩展命令前先blkid或lsblk -f确认类型再决定用哪个命令。对新手来说请记住最小结论——ext4 用resize2fsxfs 用xfs_growfsxfs 只能扩大不能缩小。5.2 fstab 写错导致系统无法启动这个坑我踩得不轻说多了都是泪。以前帮客户改一台老服务器想给/data加挂一块 LVM 卷我图省事直接在 fstab 里写了一句/dev/data_vg/data_lv /data ext4 defaults 0 2。结果重启后系统直接进不了正常模式卡在A start job is running for dev-disk-by\x2duuid这种等待设备超时的界面最后只能进 rescue 模式把 fstab 改回来。问题出哪了设备路径在重启后变了。那一台机器上有多块型号相同的盘由于内核识别顺序变化/dev/sdb在重启后可能变成了/dev/sdc于是 fstab 里写的/dev/data_vg/data_lv就找不到对应设备了。系统挂载失败启动流程等不到设备就直接卡住。此后我在生产环境的铁律是fstab 里一律用UUID挂载写入方式如下# 先查 UUID sudo blkid /dev/data_vg/data_lv # 再把 UUID 写进 fstab而不是写 /dev/xxx UUID你的UUID /data ext4 defaults 0 2另外每次改完 fstab 后先执行sudo mount -a。如果命令安静返回说明配置能被正确解析如果它报错说明 fstab 里有问题在重启前赶紧修正。5.3 扩容后 df 没变化大部分是忘了文件系统那一步在线扩容时只 lvextend 不扩展文件系统是新手最容易迷茫的地方。你执行完了lvextend -L 80G再看df -h还是原来的大小就会怀疑是不是命令失败了。其实 LV 已经变大了只是文件系统还停在老尺寸。所以我说lvextend -r是日常最快的路径。但如果你刻意不用-r一定要形成“LV 扩展 文件系统扩展”的组合动作。我甚至可以建议你把它固化成一句口头禅“扩 LV 不算完文件系统不扩等于白干。”df -h没变化还有一个可能就是resize2fs执行时文件系统正在被使用ext4 一般没问题但如果你开了某些特殊挂载选项比如nobarrier之类可能需要确认没有冲突。这种情况少见但值得留意。5.4 挂载点原目录有文件时直接 mount 会“遮住”这是一个不算 LVM 专属、但很多人在挂载新卷时踩过的坑。假设/data目录原本存在里面已经有一些临时文件你直接把新的 LVM 卷挂到/data上原目录里的文件就会被“遮住”。它们没有消失还在底层分区里占着空间只是从新挂载点看不到了。我处理这种问题的方式是先把原有目录内容备份出来再挂载新卷然后把内容拷回去。或者反过来先挂载新卷到临时目录把旧内容拷贝进来再重新挂载到最终路径。总之不要带着旧数据直接挂载新卷不然一个误操作就可能造成两份数据互相“看不见”的困惑。6. 空间回收、物理盘移出与快照备份LVM 的进阶用法6.1 缩减逻辑卷操作顺序与风险在线扩容是 LVM 的拿手好戏但缩减就不是了尤其是 xfs 文件系统根本不支持缩小。所以如果你的数据盘是 xfs请直接放弃“缩小 LV”的念头而 ext4 虽然支持但操作必须严格遵守顺序先缩小文件系统再缩小 LV。以 100G 的 ext4 LV 缩小到 80G 为例# 1. 卸载文件系统 sudo umount /data # 2. 缩小文件系统到 80G sudo e2fsck -f /dev/data_vg/data_lv sudo resize2fs /dev/data_vg/data_lv 80G # 3. 缩小 LV 到 80G sudo lvreduce -L 80G /dev/data_vg/data_lv注意lvreduce缩的是 LV但如果你之前已经把文件系统缩到 80GLV 还是 100G缩 LV 到 80G 刚好对齐。顺序反了会直接损坏文件系统结构。我的实际经验是缩减操作的风险远高于扩容除非真的空间紧张到必须回收否则我不建议在生产环境做。即便要做也得先有备份或快照同时要在业务低谷期执行做好救火方案。6.2 移除一块物理盘pvmove 与 vgreduce 的组合数据中心偶尔要更换物理盘这时候 LVM 的优势又体现出来了。假设卷组data_vg里有/dev/sdb1和/dev/sdc1两块 PV现在想把/dev/sdb这块旧盘换掉。传统分区方案下你得停机复制数据LVM 方案下可以用 pvmove 把数据从旧盘平滑搬到新盘# 1. 把旧盘上的数据移动到卷组内其他 PV sudo pvmove /dev/sdb1 # 2. 确认移动完成后从卷组中移除旧 PV sudo vgreduce data_vg /dev/sdb1 # 3. 删除 PV 标识 sudo pvremove /dev/sdb1pvmove过程持续多久取决于数据量期间业务可以继续写入因为 LVM 在迁移数据块时对文件系统来说是透明的。我有一次换盘800G 数据迁了一个半小时业务全程无感。这种体验是任何传统分区方案都给不了的。6.3 快照LVM 给备份开的一扇窗LVM 快照的本质是写时复制Copy-on-Write创建快照那一刻并不会把源数据完整拷一份而是先记录当前状态后续对源卷的新写入会被“另存”到快照空间里从而保持快照所代表的旧状态。创建一个快照非常简单sudo lvcreate -s -L 20G -n data_lv_snap /dev/data_vg/data_lv-s表示创建快照-L指定快照空间大小。快照空间不是随便给的它要容纳“快照创建后源卷上被修改的数据量”。如果你创建一个 100G 数据卷的快照只给它 20G 空间然后业务在源卷上写入了超过 20G 的新数据快照就会被写满自动失效。我常用的做法是凌晨低峰期创建快照挂载快照到临时目录只读备份关键数据然后立刻删除快照。这样快照体积小、存活时间短、风险可控。LVM 快照不能当成长期备份手段这家伙更像一个“短时记忆”真正长期保留还得靠独立的备份系统。如果以后想给某块逻辑卷做永久快照需要注意源卷所在 VG 必须有足够的剩余空间应对快照增长怎么留、留多少要在创建快照前就用vgs看清楚。最后再分享一个小技巧。我在生产环境中维护 LVM 卷养成了“三步确认”的习惯操作前lsblk看设备、vgs看剩余空间、blkid看文件系统类型操作中尽量用lvextend -r减少遗漏操作后一定用df -h和lvs双命令核对结果。这套习惯帮我躲过了不少本可以避免的意外。LVM 本质上是在给未来留余地但它也要求你对自己的每一步操作比以往更清醒——用好了它磁盘管理从“九死一生的换盘工程”变成“几分钟的命令行操作”这个改进值的。

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价 →
↑