ARTICLE DETAIL

资讯详情

深耕网站视觉设计与运营推广的一线实战洞察。

CentOS磁盘扩容实战:LVM与物理分区在线扩容全攻略

CentOS磁盘扩容实战:LVM与物理分区在线扩容全攻略 1. 扩容前的系统状态评估1.1 先搞清楚当前磁盘布局给 Centos 做分区扩容最怕的就是拿到一台机器上来就敲命令。我见过不少朋友在/dev/sda上直接fdisk /dev/sda删分区重建结果数据全没了因为根本没有先确认这台机器的底层存储方案到底是什么。接手任何一台需要扩容的 Centos 机器第一步永远是做信息采集。我的习惯是先跑三组命令lsblk df -hT fdisk -llsblk看的是整个块设备的树形结构能一眼看出磁盘、分区、逻辑卷之间的从属关系df -hT看的是文件系统当前的使用率和类型判断到底哪里满了fdisk -l看的是最底层的分区表信息确认分区类型是 MBR 还是 GPT。三组命令结合起来基本能把一台机器的存储拓扑摸清楚。这里要特别提醒一点很多人只看df -h发现根分区满了就开始折腾。但根分区满只是一个表象你要搞清楚它到底是跑在物理分区上、LVM 逻辑卷上还是跑在云平台的块存储上三种场景的扩容路径完全不一样。如果底层是 LVM后续扩容会轻松很多如果是物理分区直接格式化挂载那就得走分区表调整的老路风险和处理流程截然不同。1.2 判断文件系统类型决定后续操作拿到df -hT的输出后重点看 Type 这一列。Centos 6 时代默认是 ext4Centos 7 开始默认变成 xfsCentos 8/9 依然沿用 xfs。这两种文件系统的扩容方式有本质区别文件系统类型扩容工具是否支持在线扩容是否支持缩小ext4resize2fs支持挂载状态下直接扩容支持缩小但风险较高xfsxfs_growfs支持挂载状态下直接扩容不支持缩小只能扩大xfs 的设计哲学就是只能增不能减所以如果你建的是 xfs 文件系统扩容时不用卸载分区直接拉大后执行xfs_growfs就能生效。而 ext4 在线扩容也基本是常规操作两者在扩大这个方向上都非常成熟遇到需要缩小的情况就只能绕道了。另外还要确认分区表格式。fdisk -l输出里如果看到 Disk label type: dos 就是 MBR 分区表看到 gpt 就是 GPT。MBR 单块磁盘支持最大 2TB而且最多只能建 4 个主分区GPT 没有这些限制。现在新机器基本都是 GPT但早期虚拟机模板和旧物理机还大量存在 MBR扩容时如果磁盘超过 2TBMBR 会直接变成拦路虎。提示pvs、vgs、lvs三个命令可以快速确认系统是否在用 LVM。如果lsblk输出里能看到vg或lv字样说明这台机器走的是逻辑卷管理后面的扩容路径会完全不一样。2. 磁盘挂载与 LVM 扩容的核心流程2.1 认识 LVM 的三层抽象Centos 默认安装时如果选择的不是自动分区而是手动配置过逻辑卷那么根分区所在的存储层级通常是这样的物理磁盘Physical Disk→ 物理卷PVPhysical Volume→ 卷组VGVolume Group→ 逻辑卷LVLogical Volume→ 文件系统这个结构可能一开始看着有点绕但举个生活化的例子就很好理解。把物理磁盘想象成一大块原始面粉PV 就是把面粉称量好、分装好的独立袋子VG 是一个大储物柜多个 PV 袋子的面粉可以都倒进这个大柜子里LV 则是从柜子里取出来的面粉团专门用来做特定的面包也就是挂载到某个目录的文件系统。LVM 最核心的价值在于它把底层物理磁盘的容量变化和上层文件系统的容量变化解耦了。物理磁盘不够用时加入新硬盘或者扩大虚拟磁盘把新增的空间划给 PV再扩充到 VG再从 VG 里划给 LV最后才扩展文件系统。每一步都有对应的命令任何一步都可以停下来检查出错也能回退这是物理分区直接扩容无法比拟的优势。2.2 新磁盘加入与 PV/VG 扩展如果原系统是 LVM 布局扩容路径就非常顺畅。假设我们把虚拟机的虚拟磁盘从 40G 扩到 100G新出现的空间在/dev/sda末段开始操作# 重新扫描磁盘让内核识别新增的容量 partprobe /dev/sda lsblk如果lsblk已经能看到磁盘总容量变成 100G但分区大小还是旧的就需要新建一个分区来使用剩余空间。用fdisk操作时注意分区类型设置为 Linux LVM8efdisk /dev/sda # 交互式操作n新建分区 → p主分区 → 回车选默认扇区 → t改类型 → 8e → w保存新分区建好后把它变成 PV再并入卷组# 创建新的物理卷 pvcreate /dev/sda3 # 扩展到卷组 vgextend centos /dev/sda3 # 查看卷组容量变化 vgdisplayvgdisplay里重点看 Free PE / Size 这一行这里显示的就是当前卷组里还没被分配给逻辑卷的空闲容量。如果这里没有容量剩余后面的 LV 扩展就无从谈起很多新手在这里卡住以为操作错了其实是前面的 vgextend 没生效或者分区类型没设对。2.3 逻辑卷扩展与文件系统在线扩容VG 里有空闲容量后就可以扩展 LV 了。假设根逻辑卷名字叫/dev/centos/root把容量扩大 60G# 扩展逻辑卷 lvextend -L 60G /dev/centos/root # 扩展文件系统xfs 和 ext4 命令不同 xfs_growfs /dev/centos/root # xfs 文件系统 resize2fs /dev/centos/root # ext4 文件系统这里有一个很容易踩的坑lvextend只是扩大了逻辑卷的容量边界文件系统本身并不知道这个变化。如果不执行xfs_growfs或resize2fsdf -h看到的容量依然不变等于白扩。反向操作也一样每次都有人说我 lvextend 了为什么 df 没变化十有八九就是漏了文件系统扩展这一步。另外xfs 文件系统在挥动xfs_growfs的魔杖时其实可以挂载状态下直接执行根本不需要卸载。只要逻辑卷的设备映射存在命令就能在线完成扩展。ext4 也同样支持在线扩容现在的生产环境基本都能做到不停机扩容。注意resize2fs是老牌的 ext 系列工具xfs_growfs是 xfs 专用工具两者不要混用。如果你不确定当前文件系统是什么类型执行blkid /dev/centos/root就能看到 TYPE 字段。3. 非 LVM 场景的分区扩容实操3.1 物理分区直挂的场景如何扩展Centos 如果安装时选择的是标准分区而不是 LVM比如/dev/sda1是/boot/dev/sda2是根分区直接格式化成了 xfs那么扩容路径就没有 LVM 那么优雅了。核心思路是调整分区表 → 让内核重新读取分区大小 → 扩展文件系统。虚拟机场景下一般先把虚拟磁盘大小加大。VMware 里在虚拟机设置中扩展磁盘容量VirtualBox 用命令行VBoxManage modifymedium disk /path/to/disk.vdi --resize 102400宿主机层面扩展完进入 Centos 后先执行lsblk确认磁盘空间是否已经识别。如果磁盘容量识别了但分区大小没变用fdisk删除旧分区再重建。这里是最危险的一步因为重建分区的起始扇区必须和原来完全一致否则分区数据直接丢失。我的建议是进入fdisk交互界面后先按p查看分区表并截图记录下 Start 列的值。删除分区时按d删掉目标分区然后按n重建起始扇区必须填入记录下来的原始值结束扇区默认是磁盘末尾就行。确认无误后按w写入分区表然后执行partprobe /dev/sda如果提示设备忙可能是分区正在使用可以重启系统让内核重新读取分区表。3.2 文件系统层面如何扩大 xfs/ext4分区表更新后现在的分区已经变大但文件系统还是老样子。此时执行df -h会发现容量没变因为文件系统的元数据还记录着旧的大小。需要用对应工具把它撑满到整个分区# xfs 文件系统 xfs_growfs /mount/point # ext4 文件系统 resize2fs /dev/sda2注意 xfs 的参数是挂载点而不是设备文件路径ext4 的 resize2fs 参数是设备文件路径。两个命令的传参方式不一样我一开始也经常记混后来总结了个记忆方法xfs_growfs 里的 growfs 后面跟的是文件系统能看到的地方也就是挂载点resize2fs 操作的对象是块设备本身。这里需要特别提一下 GPT 分区表的情况。如果磁盘超过 2TB 或者用的是 UEFI 引导分区表往往不是 MBR 而是 GPT操作时用gdisk或者parted更合适。fdisk新版也支持 GPT但老版本可能识别异常操作前先确认工具版本和分区表格式。对于parted常用的是resizepart命令parted /dev/sda # 交互界面中执行 # resizepart 2 100% # quit这种操作方式比 fdisk 的删分区重建更安全因为它允许直接调整现有分区的结束位置不会动起始扇区极大降低了误操作风险。在新版 Centos 上我反而更推荐用parted的 resizepart 来做整盘扩容。提示如果根分区直接处于挂载状态partprobe会提示 Device or resource busy这时可以尝试partprobe -s查看状态或者直接重启。生产环境在业务低峰期操作千万不要在数据盘读写频繁时强行重读分区表。3.3 数据备份与回滚方案的兜底非 LVM 的分区扩容本质上是一次修改元数据的操作虽然工具已经非常成熟但任何意外断电、参数填写错误都可能造成数据损坏。所以操作前强制做好备份非常必要。最简单的做法是用dd备份分区表区域注意不要备份整个磁盘那太耗时了# 备份 MBR 前 512 字节包含分区表 dd if/dev/sda of/tmp/mbr_backup.bin bs512 count1 # 恢复时执行 dd if/tmp/mbr_backup.bin of/dev/sda bs512 count1如果是 GPT 分区表分区表信息会分布在磁盘头部和尾部用sgdisk命令更可靠# 备份分区表 sgdisk --backup/tmp/gpt_backup.sgdisk /dev/sda # 恢复分区表 sgdisk --load-backup/tmp/gpt_backup.sgdisk /dev/sdadd备份只覆盖 MBR 场景GPT 用户千万别只靠 dd 备份那 512 字节因为 GPT 的备份分区表是存在磁盘末尾的单靠前 512 字节恢复不完整。这类细节只有在真正操作过大量机器之后才会注意得到。当然最稳妥的方案还是对关键数据做文件级别的备份比如用rsync同步到独立目录或者远程机器。分区扩容本质是低风险高影响的动作备份的意义不在于常用而在于万一出问题时能兜底。4. 开机自动挂载与常见问题排查4.1 配置 fstab 实现自动挂载扩容完成、文件系统扩展完毕之后还有一个重要问题不能忽视——重启后新增分区或数据盘能不能自动挂载回来。很多人以为扩容完整个流程就结束了重启后才发现数据盘没挂载业务直接报错。这个问题的根源在于/etc/fstab文件里根本没有新增分区的挂载记录系统启动时自然不知道要挂载它。编辑/etc/fstab时不要直接用设备名如/dev/sda1因为在多块磁盘场景下设备名可能会因为内核识别顺序不同而漂移今天 sda 明天可能变成 sdb挂载就会错乱。推荐用 UUID 的方式# 查询分区或逻辑卷的 UUID blkid /dev/sda3拿到 UUID 后在/etc/fstab添加一行UUIDxxxx-xxxx-xxxx /data xfs defaults 0 0四个字段的含义分别是设备标识、挂载点、文件系统类型、挂载参数。最后的两个数字第一个是 dump 备份标志一般写 0第二个是 fsck 检查顺序根分区写 1其他分区写 2 或 0。很多人直接写成defaults 1 1结果开机时系统对非根分区执行 fsck反而可能拖慢启动甚至报错所以非根分区写0 0是更稳妥的选择。编辑完 fstab 后一定要执行一次验证mount -a这条命令会按照 fstab 的配置重新挂载所有条目如果配置错误会立即报错而不是等到重启才暴露。我见过不少人改完 fstab 就直接重启结果起不来最后只能进救援模式修改非常折腾。4.2 扩容后常见报错的排查思路扩容过程中最典型的报错我整理成一张排查表基本覆盖了 90% 的现场问题症状可能原因排查与解决方案df -h容量没变执行了 lvextend 或分区调整但没执行文件系统扩展命令根据文件系统类型执行xfs_growfs或resize2fspartprobe报设备忙分区正被系统使用无法重读分区表重启系统或确认没有进程占用后再次执行xfs_growfs报错 not found系统未安装 xfsprogs 工具包yum install -y xfsprogs或dnf install -y xfsprogs挂载时报 wrong fs type文件系统类型写错了用blkid确认实际类型修正 fstab 第三列开机后进入紧急模式fstab 配置错误输入 root 密码修复 fstab执行mount -a验证vgextend原卷组不存在系统没有使用 LVM重新评估是否走物理分区扩容路径LVM 卷组显示没有空闲空间物理卷没成功加入卷组确认分区类型为 8e重新执行vgextendfdisk 只能识别 2TB 以下MBR 分区表限制需要在 GPT 下操作使用gdisk配合扩容这里挑几个高频问题展开说一下。第一个是设备忙的问题。只要分区处于 mounted 状态内核不会允许重新读写它的分区表这是为了保护数据一致性。如果操作的是根分区或者/var等关键路径重启是几乎唯一的办法。如果是数据盘可以先umount再执行partprobe操作完再挂载回来。第二个是 xfs_growfs 报 not found。Centos 7 最小化安装时可能没有装 xfsprogs但奇怪的是系统却是 xfs 文件系统这时候需要先装工具包。这个坑在精简安装的机器上很常见提前装好能省去临场解决问题的麻烦。第三个是 fstab 写错导致进不了系统这个情况比较严重。如果启动时提示 Failed to mount /data 然后进入 emergency mode输入 root 密码登录后先以只读方式检查/etc/fstabmount -o remount,rw /然后用blkid检查实际 UUID修正 fstab执行mount -a验证确认无误后重启即可恢复。千万不要在原系统盘 fstab 混乱的时候直接重启那可能会让问题变得更复杂。4.3 关于 swap 分区和数据盘挂载的特殊情况扩容过程还可能遇到 swap 分区和数据盘两个特殊场景。先说 swap。如果 swap 放在独立分区或独立逻辑卷上想要扩大 swap 空间流程和根分区扩容类似。如果是 swap 文件方式Centos 7 之后常用可以直接新建一个更大的 swap 文件切换掉旧的# 创建一个 4G 的 swap 文件 fallocate -l 4G /swapfile chmod 600 /swapfile mkswap /swapfile swapon /swapfile为了让重启后依然生效还需要在 fstab 中加一行/swapfile none swap defaults 0 0这种方法比调整分区方便很多特别是遇到磁盘剩余空间分散在尾部、不方便划区的情况时。再说数据盘。很多生产机器加装新磁盘后系统已经能识别/dev/sdb但需要手动分区、格式化、挂载。这套流程做完后千万别忘了前面说的 fstab 配置。另外如果数据盘走的是 LVM可以直接vgextend到已有卷组把新盘容量并进根分区所在卷组再扩展逻辑卷实现统一管理。这种方式比新增一个独立数据盘更利于后续容量调配。关于 LVM 场景还有一个值得注意的点vgextend加入的 PV 可以来自不同的物理磁盘这也意味着只要 VG 里还有空间LV 的扩展就不一定需要在同一块盘上进行。所以在虚拟化平台上扩容虚拟机硬盘后先vgextend再lvextend步骤并不会有太多变化无非是多了一次卷组扩展。5. 分区扩容的规划建议与操作心得5.1 不同磁盘管理方案怎么选操作过几次扩容后我对不同磁盘管理方案的使用场景有了比较清晰的认识。这里给准备做分区规划或者打算调整存储架构的朋友一些参考。如果是刚接手一台旧机器建议保持原有方案尽量不跨方案迁移。比如原来是 LVM 就继续 LVM原来是物理分区就继续物理分区不要一边扩容一边想把物理分区改成 LVM那等于重复踩坑两遍。如果是新装系统我是强烈推荐 LVM 方案的。Centos 安装时选择 Automatically configure partitioning 后再点 I will configure partitioning然后在分区策略里选 LVM创建卷组时留出一定的未分配空间。这样后续需要扩容时只需要新加磁盘或者在虚拟化平台上扩大磁盘再通过 pvcreate、vgextend、lvextend 三步搞定不需要碰分区表安全性高很多。如果是云服务器很多云厂商提供了在线扩容云盘的入口控制台上扩完容量后系统内的操作其实就是本文前面讲的那套流程。不同云厂商可能有一个 扩展分区和文件系统 的引导文档但底层原理都是通用的掌握了命令切到任何一家的控制台都心里有底。5.2 扩容操作顺序的黄金法则所有扩容操作我总结出一个四步法则先备份关键数据和分区表再扩大底层虚拟磁盘、物理磁盘、云盘然后扩大逻辑层分区、PV、VG、LV最后扩大文件系统层resize2fs 或 xfs_growfs这个顺序不能乱一旦乱了很容易出现底层空间已经加了但上层文件系统识别不到的尴尬局面。相反的顺序更是大忌比如在磁盘本身没扩大的情况下直接对文件系统执行resize2fs想扩大容量那是不会成功的因为文件系统大小不能超过分区大小分区不能超过磁盘大小。每一层都有硬边界上层容量必须小于等于下层容量这个物理约束在任何存储架构下都成立。还有个细节很多人不在乎扩容操作尽量选在业务低峰期。虽然 xfs 和 ext4 都支持在线扩容但在数据写入很频繁的时段执行万一遇到断电或者 IO 错误出现文件系统损坏的概率会显著增加。稳妥的办法是先sync同步一次缓存数据再执行扩容命令减少数据不一致的风险。5.3 用 df 和 lsblk 联合验证扩容结果扩容结束后很多人习惯只看df -h发现容量变了就完事。我的建议是要多花 10 秒做一次完整验证# 查看文件系统容量是否扩展成功 df -hT # 查看底层块设备和分区关系 lsblk # 查看逻辑卷容量变化 lvs三个命令交叉对比基本可以确认扩容在每个层级都生效了。比如df -h显示根分区 95Glsblk显示 sda 100Glvs显示 root 逻辑卷 95G这三个数字对得上说明磁盘、分区、文件系统三个层级都同步了。如果发现df显示容量依然偏小先检查lsblk里磁盘总容量是否已经扩大再检查分区大小是否同步再检查逻辑卷大小最后检查文件系统。逐层排查定位是哪一层没扩散到位再针对性地处理。扩容完成后还有一个容易被忽视的动作就是用df -i查看 inode 使用率。有些场景下文件系统容量还有剩余但 inode 不够了也会导致无法创建新文件。扩容前如果 inode 已经接近上限扩容时可以考虑重新调整 inode 数量策略不过这属于比较高级的调优范畴一般场景下默认值就够用。最后分享一个小习惯操作完任何分区有关的事情我都会顺手把blkid的输出保存一份到本地这样下次维护或者上线新的监控脚本时随时能查到每个设备对应的 UUID而不必重新扫描系统。这种小细节在故障处理和备份恢复时能省下不少时间建议你也试试。
返回列表