
做“CentOS 7 缩小 /home 分区扩展 root 分区”这个操作说白了就是当年装系统时LVM规划没做好/home 分大了、/ 分小了跑了一段时间后根分区被日志、缓存、容器镜像塞满而 /home 还剩一大半空间闲着。这种情况在运维日常里太常见了我最近在一台内部测试服务器上就完整做了一遍这个“缩 home 扩 root”的流程中间踩了几个坑也把整个原理彻底捋清楚了。这篇就把完整过程记录下来包括为什么能缩、怎么缩不丢数据、哪些步骤顺序不能乱、以及 xfs 和 ext4 的差别这个最容易忽略的坑。这篇内容不只是贴命令我会把每一步背后的逻辑讲明白适合装过 CentOS 7、磁盘规划不合理、想在不重装系统前提下调整分区大小的人参考。尤其是那种/快满、/home却空荡荡的场景这篇文章能直接帮你解决问题。1. 这个操作背后的 LVM 逻辑1.1 为什么 CentOS 7 默认分区规划经常出问题装 CentOS 7 的时候很多人图省事直接选默认自动分区。系统安装器给的方案通常会这样分配/boot单独分一个 1G 左右的小分区/给 50G 左右剩下的空间绝大部分都会划给/home。如果你的磁盘是 500G那么最终效果往往就是/只有 50G/home却有 430G。这种规划在刚装完系统时看不出问题因为系统本身只占几个 G。但跑起来之后就不一样了Docker 的数据目录默认在/var/lib/docker日志写在/var/log临时文件在/tmp这些全都归根分区管。几个月下来/蹭蹭涨到 90%以上而/home因为根本没人往里放东西一直保持在个位数的使用率。这时候你面临两个选择重装系统重新分区或者在 LVM 层面把空间重新分配。重装的成本谁都知道机器上跑的数据库、配置、脚本都要重新折腾一遍。所以只要当初装系统时用了 LVMCentOS 7 默认就是 LVM就有机会无损调整。1.2 缩小 /home 扩展 root 的总体思路LVM 的分层结构是这样的物理卷 PV 是底层的一块磁盘或分区卷组 VG 是把一个或多个 PV 合并成的大资源池逻辑卷 LV 是从 VG 里划分出来的“虚拟分区”文件系统就建在 LV 上。我们要做的操作本质上是三个层次之间的空间转移把/home逻辑卷对应的文件系统缩小把/home逻辑卷本身缩小把缩出来的空闲空间扩展给/逻辑卷这个顺序非常关键。缩小的时候必须先缩文件系统再缩逻辑卷扩大的时候则相反先扩逻辑卷再扩文件系统。用生活化的类比来说文件系统相当于一个抽屉里摆放整齐的物件逻辑卷是抽屉本身卷组是整个房间。你要把抽屉改小得先把抽屉里的物件按新尺寸重新排好才能把抽屉拆小而你要换一个大抽屉得先扩大抽屉的边框再把物件重新铺满。这套操作能不能做有一个硬性前提那就是文件系统类型。如果/home是 ext4 文件系统可以用 resize2fs 在线缩小但如果/home是 xfs 文件系统那不好意思xfs 支持扩大但不支持缩小这条常规路子直接走不通。CentOS 7 默认装的 root 区是 xfs而/home要看安装时的具体选项很多自动分区方案里/home也是 xfs。所以动手前第一件事就是确认文件系统类型这个我放到下一节详细说。2. 动手前的状态确认与风险评估2.1 先确认文件系统类型xfs 还是 ext4这是整个操作里最重要的前置检查。我遇到过有人没确认就直接执行 resize2fs结果 resize2fs 拒绝运行因为文件系统类型根本不支持缩容幸好没造成破坏。查文件系统类型用两招df -T blkiddf -T可以看到已经挂载的文件系统类型blkid则更加准确能直接显示分区的 UUID 和 TYPE 字段。这两个命令的结果对照着看稳一点。如果显示/dev/mapper/centos-home的 TYPE 是 ext4那恭喜你这篇文章里演示的完整流程可以直接照抄。如果是 xfs请直接跳到文章倒数第二节我会专门讲 xfs 情况下的替代方案。我的测试服务器上/home正好是 ext4原因很偶然——当初手动安装系统时特意指定了 ext4没想到这次派上了大用场。所以大家在做生产环境规划时如果预期到以后可能要缩容某个分区一开始就把它格式化成 ext4 会更灵活。2.2 梳理 LVM 结构看清空间分布确定文件系统没问题后接下来要把 LVM 的整体布局摸清楚。依次执行这三条命令pvdisplay vgdisplay lvdisplay重点看vgdisplay输出的 Total PE / Free PE以及lvdisplay里每个逻辑卷当前的 LV Size。比如我这边的情况就是这样对象大小说明/dev/mapper/centos-root50G根分区使用率 96%急需扩容/dev/mapper/centos-home430G家庭目录使用率不到 5%卷组 centos 总容量480G两块磁盘合并或单块磁盘单分区这种对比一摆出来思路就很清楚了把/home从 430G 缩到 20G释放出 410G 的空间然后全部加给/这样/能到 460G至少几年内不用再操心磁盘问题。如果卷组里有多个物理卷还可以用pvdisplay -m查看每个物理卷上的 PE 分布情况。这一步不是必须的但当你想删掉某块物理卷、或者想确认空间碎片情况时很有用。单物理卷的场景下默认安装顺序一般是 root 的 PE 在开头、home 的 PE 在末尾home 缩完后释放的空闲 PE 刚好在 root 尾部附近扩展非常顺畅。2.3 备份与维护窗口的选择缩容操作属于高风险动作。虽然 ext4 的 resize2fs 和 LVM 的 lvreduce 都有一定的容错能力但任何一步意外断电、误操作、文件系统异常都可能导致数据丢失。所以无论脚本多熟练备份这一步省不得。我当时的做法是因为/home里只有几个测试账号的临时文件内容不多直接打包拷到了另一个磁盘的分区下。如果/home里有重要数据建议至少做一次镜像级别或者文件级别的完整备份。备份时间不算在维护窗口里但心里有底多少比没底强。另外要规划维护窗口。因为缩/home需要先卸载它有用户正在使用的情况下不能直接卸载。一个小技巧是先检查哪些进程占用了/home确认无误后再进行。根分区本身不用担心卸载整个操作过程中/一直是挂载状态这反而方便我们实时查看进度。3. 分区调整的分步拆解3.1 卸载 /home 并检查文件系统状态第一步是让/home从系统中下线。为了保证重启后不会自动挂载回来先把/etc/fstab里对应的自动挂载行注释掉或者删除这一步很多人会漏掉。# 修改前先备份 cp /etc/fstab /etc/fstab.bak # 编辑 fstab把包含 /home 的那行前面加个 # vim /etc/fstab然后是卸载umount /home如果提示target is busy说明还有进程在访问/home。用lsof或者fuser找到占用进程处理掉后再卸载。我那次是因为某用户的测试脚本还在后台跑kill 掉就正常了。卸载完成后对/home对应的逻辑卷做强制文件系统检查。这一步很多人会跳过但 resize2fs 在缩容时会重写文件系统的关键元数据如果文件系统本身有异常强行缩容等于把问题放大。检查命令是e2fsck -f /dev/mapper/centos-home注意-f参数是强制检查因为文件系统可能直接被标记为 clean没有这个参数就会直接跳过检测。e2fsck 输出里如果出现clean字样说明文件系统状态正常可以继续。如果出现 error 信息先修复修复不了就别继续缩了数据安全第一。3.2 缩小文件系统再缩小逻辑卷文件系统检查通过后开始真正意义上的“缩容”。先把文件系统缩到你想要的目标大小。假设我要把/home从 430G 缩到 20Gresize2fs /dev/mapper/centos-home 20Gresize2fs 执行完后文件系统的可用空间就变成了 20G数据块已经全部收缩到最前面的一段区域。这个时候逻辑卷本身还是 430G后面那 410G 其实没有被文件系统占用属于“文件系统层面的空洞”空间还没有真正还给卷组。接下来缩小逻辑卷lvreduce -L 20G /dev/mapper/centos-home命令执行过程中会提示你确认因为这是不可逆的风险操作输入y确认即可。这一步做完卷组里就多了 410G 的空闲空间可以用vgdisplay验证。这里有个容易弄混的细节lvreduce的参数有两种写法。-L 20G表示把逻辑卷缩到 20G-L -410G表示减少 410G。我习惯用第一种直接指定目标大小理解起来不容易出错。如果是用-l小写参数那后面跟的是 PE 数量不是容量别搞混。3.3 物理卷空间重排pvmove 该不该用很多教程在这个位置会插入pvmove命令搞得好像这是必选项。实际上如果卷组只有一个物理卷且 root 和 home 都在这个物理卷上那么 home 缩容释放出的空闲 PE 就在物理卷的末尾root 逻辑卷扩展时可以直接吃下这些空间不需要任何物理移动。那pvmove到底什么时候才需要两种典型场景第一卷组里有多个物理卷你想把某个物理卷彻底腾空并移除出卷组。此时要把这个 PV 上的数据段全部搬到其他 PV 上pvmove /dev/sdb1就是干这个的。第二你不想保留/home逻辑卷想直接删除它让整个物理卷末尾空间彻底空出来。这种情况下lvremove之后也不需要 pvmove。所以在我这次的场景里选择了保留下一个 20G 的/home逻辑卷而不是直接删掉这是更稳妥的运维习惯——万一以后某个用户真的需要放点东西在 home 目录呢。于是直接在 lvreduce 这一步就把空间释放完毕跳过了 pvmove。命令就变得很干净缩 home、扩 root。3.4 扩展 root 逻辑卷与文件系统空间释放出来后扩展 root 分区就是顺势而为的事了。先把卷组里所有空闲空间全部给 rootlvextend -l 100%FREE /dev/mapper/centos-root这里用-l 100%FREE表示把卷组里所有剩余空闲空间一次都给 root。如果不想全给可以指定-L 400G或者最终目标大小-L 460G。执行完lvextend后逻辑卷本身已经是新的大小了但文件系统还不知道这件事df -h看到的容量不变这是正常的。最后一步就是让文件系统感知扩容。这一步取决于 root 的文件系统类型如果是 xfs用xfs_growfs /它对挂载点操作不需要指定设备名如果是 ext4用resize2fs /dev/mapper/centos-root它直接对设备操作CentOS 7 默认 root 基本是 xfs所以大概率你会用到这个命令xfs_growfs /执行完后再看df -hroot 的大小已经扩展成功。如果需要恢复/home的挂载把刚才 fstab 里注释掉的那行恢复原样然后执行mount -a。因为刚才缩容后的/home只有 20G如果之前 fstab 里写入的挂载参数没问题直接就能挂上。4. 实操现场记录下面这段是我实际操作时敲的完整命令序列去掉了现场干扰因素整理成一份可以直接对照执行的顺序# 1. 确认文件系统类型 df -T blkid # 2. 备份 fstab 并注释 /home 挂载行 cp /etc/fstab /etc/fstab.bak vim /etc/fstab # 3. 卸载 /home umount /home # 4. 强制检查文件系统 e2fsck -f /dev/mapper/centos-home # 5. 缩小文件系统到 20G resize2fs /dev/mapper/centos-home 20G # 6. 缩小逻辑卷到 20G lvreduce -L 20G /dev/mapper/centos-home # 7. 确认卷组空闲空间 vgdisplay # 8. 把空闲空间全部扩展给 root 逻辑卷 lvextend -l 100%FREE /dev/mapper/centos-root # 9. 扩展 root 文件系统xfs 用这个ext4 用 resize2fs xfs_growfs / # 10. 恢复 fstab 并重新挂载 /home vim /etc/fstab mount -a # 11. 最终验证 df -h实际操作中我在第三步就卡了一下。umount /home报target is busy排查后发现是某个测试用户的服务进程还开着。处理完进程后再次卸载顺利通过。第五步到第六步之间我特意多等了几秒确认 resize2fs 完全落盘后才去执行 lvreduce。这是谨慎起见避免文件系统还在写缓冲时逻辑卷就缩了理论上 LVM 会处理这种并发但没必要赌。第八步的100%FREE写法有个小坑如果你之前决定保留一部分空间不分配那100%FREE会把所有空闲空间都交出去。如果想预留就用-L 400G指定具体容量。我当时想的是既然 home 都缩到 20G 了剩余空间留着也没价值直接全给 root 是最省心的。操作完成后的df -h输出root 从 50G 变成了 460Ghome 从 430G 变成了 20G和使用预期完全一致。期间没有出现数据损坏重启后系统正常运行fstab 挂载也正常。5. 常见问题与排查技巧实录调了这么多次分区我总结了一份问题速查表基本覆盖了这类操作里最常遇到的状况问题现象可能原因解决方法umount 提示 target is busy有进程占用 /homelsof /home或fuser -mv /home定位进程停止后重新 umountresize2fs 拒绝执行文件系统类型不支持先用blkid确认是否为 ext4xfs 不能这么缩e2fsck 报错无法修复文件系统存在坏块或严重异常停止操作从备份恢复数据不要强行缩容resize2fs 提示 nothing to do缩容目标大小不小于当前大小检查参数确认-L 20G写法正确lvreduce 确认后立即想反悔误操作数据没写回时可用 LVM 的 metadata 备份恢复但概率不大所以确认前一定要想清楚lvextend 后 df 大小没变化没执行文件系统扩展xfs 用xfs_growfsext4 用resize2fs别漏重启后 /home 挂载不上fstab 里的设备名或 UUID 变了用blkid更新 fstab 对应项或用vgchange -ay激活卷组-L 160G与-L 160G混淆一个表示增加量一个表示最终大小加法用目标大小不用加号操作前看清除了表格里的内容还有几个细节值得单独说第一不要把df -h显示的容量当成逻辑卷的真实大小。df -h显示的是文件系统大小lvdisplay显示的是逻辑卷大小两者在缩容过程中会出现短暂的不一致别被吓到。等到文件系统扩展完成后两边会重新对齐。第二LVM 默认的元数据备份存在/etc/lvm/archive目录里。如果你在某一步误操作后非常确定要回滚逻辑卷大小可以尝试vgcfgrestore --list查看历史版本然后用vgcfgrestore恢复。但这个过程非常复杂且有一定风险如果不是紧急救援场景我通常不推荐大家依赖它因为数据一致性没法保证。更靠谱的做法是操作前用vgcfgbackup -f /backup/vg_centOS7_bak.vg手动导出一份当时的元数据。第三多人共用的服务器操作前最好提前通知把/home下挂着的长任务、服务都处理干净。我当时遇到的那个 busy 进程就是一个反面教材。6. 补充如果 /home 是 xfs 文件系统怎么办文章前面反复提到xfs 不支持缩容。如果你的/home格式化成了 xfs那前面的 resize2fs 流程走不了但这不意味着没救。这里给出 xfs 情况下的替代方案。思路核心只有一个既然文件系统本身不让“缩”那就别缩了直接重建。xfs 的特点是删除逻辑卷后新建一个小的逻辑卷重新格式化再把数据拷回去。这样做的本质是绕开了缩容限制用“备份—重建—恢复”的流程实现空间转移。具体步骤# 1. 先备份全部 /home 数据 rsync -avzh /home/ /mnt/backup/home_backup/ # 2. 卸载并删除原 /home 逻辑卷 umount /home lvremove /dev/mapper/centos-home # 3. 删除后卷组自动释放全部空间 vgdisplay # 4. 把空闲空间扩给 root lvextend -l 100%FREE /dev/mapper/centos-root xfs_growfs / # 5. 重新创建小号的 home 逻辑卷 lvcreate -L 20G -n home centos mkfs.xfs /dev/mapper/centos-home # 6. 挂载并恢复数据 mount /home rsync -avzh /mnt/backup/home_backup/ /home/这个方案需要一台额外存放备份的位置比如另一块磁盘或者网络存储。如果/home数据非常大受限于备份时间和传输带宽可能要考虑维护窗口拉长或者直接选择其他方案。还有一个变体如果整个系统分区都不是 LVM而是传统裸分区比如/dev/sda1是 root、/dev/sda2是 home那这套流程全部作废。裸分区要调整大小必须移动分区边界这是极度危险的物理级操作唯一稳妥的工具是图形化的 GParted Live而且同样需要完整备份。除非实在没办法否则这种情况我建议你直接重装系统把分区规划一次做对。行政机构也好、个人博客也好我个人的运维习惯是装系统时最好干脆不单独分/home把根分区一次性给够。如果非要单独分就把它建成 ext4保留未来缩容的灵活性。只要底层是 LVM什么时候都能后调整但文件系统类型这个一锤子买卖装完就不好改了。用 LVM 的机器其实最值得庆幸的就是还能做这类空间腾挪要是当初用的是裸分区方案空间不够基本只能扩硬盘麻烦得多。希望这篇记录能帮你少走点弯路。