“home富得流油、var快要爆掉”这大概是每个Linux运维都会撞上的经典场面。我手头一台CentOS7测试服务器装系统时图省事给/home单独划了500G/var只给了50G。结果跑了不到两个月Nginx日志、yum缓存、数据库临时文件全往/var里塞df一看直接血压升高/var用了93%/home才用了5%。这台机器当初用的是LVM逻辑卷管理所以最优雅的解法不是重装系统也不是临时加一块硬盘而是直接在逻辑卷层面做“削峰填谷”——把home的容量压下来把空间补给var。这篇文章就是我完整走了一遍这个操作之后整理出来的流程会包含前置检查、命令细节、XFS和ext4两条路线的差异以及我踩过的好几个坑。适合对LVM只知道大概、想把home空间安全调给var的开发者或运维参考。1. 为什么home会富得流油var却见底先聊聊这个需求是怎么冒出来的。很多CentOS7服务器在安装阶段做自定义分区时都会习惯性把/home单独划分一个大分区理由是“以后用户数据会很多”。但现实往往是/home里根本没住几个人而/var却被日志、缓存、邮件、数据库临时文件这些东西迅速填满。尤其像Nginx的access_log、系统自带的yum缓存、某些中间件写进/var/lib或/var/tmp的数据增长速度快得出乎意料。如果这台机器在分区时没有用LVM用的是一整块磁盘的普通分区那么遇到这种“home大var小”的局面确实只能加盘或者重做系统。但CentOS7默认安装就推荐LVM布局安装器会把整块盘做成一个物理卷PV归入卷组VG再在VG上切出多个逻辑卷LV。逻辑卷的好处在于同一块VG里的LV之间容量可以互相调度。home用不完的空间完全可以拆出来给var不需要动到物理磁盘本身。不过这里要先给大家泼一盆冷水这个操作有一个前置条件就是home和var必须属于同一个卷组而且卷组里要存在可用的总容量。如果机器当时把/home和/var划成了两个独立的VG或者根本没有用LVM那这篇文章里的方案就不适用只能换思路。还有一个容易被忽略的点为什么var会不够用如果只是某一次日志暴涨那清日志比动分区更明智。假如var长期维持在高水位那才值得做真正的扩容。所以动手前先搞清楚var里的空间到底是被谁吃掉的——是/var/log、/var/lib还是/var/cache。这个判断直接影响后面“缩到多小、扩到多大”的目标数字。2. 操作前必须看懂的磁盘家底几条命令读出关键信息2.1 先跑四条基础命令正式开始调整之前我会先把下面这组命令跑一遍确认机器状态df -hT vgs lsblk blkiddf -hT是为了看挂载点、容量、使用率和文件系统类型。vgs看卷组重点看VFree这一列也就是卷组里还有多少空闲空间。如果VFree已经大到你计划给var增加的量那根本不用动home直接给var扩容就完事了。这一步经常被我忽略实际上也是最省事的一种情况。lsblk看块设备层级确认磁盘底层是不是lvm。如果输出里没有LVM字样说明当时装系统没选LVM后续方案作废。blkid看每个逻辑卷真实的文件系统类型和UUID这是判断接下来走哪条路的关键依据。2.2 从输出里读出关键信息一台典型机器的参考输出大概是这样的$ df -hT Filesystem Type Size Used Avail Use% Mounted on /dev/mapper/centos-root xfs 50G 20G 30G 40% / /dev/mapper/centos-home xfs 500G 10G 490G 2% /home /dev/mapper/centos-var xfs 50G 46G 4G 92% /var $ vgs VG #PV #LV #SN Attr VSize VFree centos 1 2 0 wz--n- 550.00g 0 $ lsblk NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT sda 8:0 0 550G 0 disk └─sda2 8:2 0 550G 0 part ├─centos-root 253:0 0 50G 0 lvm / ├─centos-home 253:1 0 500G 0 lvm /home └─centos-var 253:2 0 50G 0 lvm /var注意vgs输出的VFree是0说明整个VG的550G已经全分完了。这时要让var变大唯一的路就是调整home。而lsblk显示home和var都是lvm且属于同一个VG centos意思是物理基础没问题。2.3 文件系统类型决定路线CentOS7安装时默认使用的文件系统是XFS所以绝大多数人的home和var会是XFS。XFS有个非常硬的限制只能扩大不能缩小。后面要把home的容量吐出来就得先备份、删除旧LV、重建新LV再恢复数据。如果当初你在安装时把home手动指定成了ext4那恭喜你可以走“在线瘦身”路线用resize2fs先缩文件系统再让lvreduce把LV缩小。第4章和第5章分别讲这两条路。2.4 规划目标数字与备份方案动手之前把目标数字写下来。比如我当时的规划是home当前实际使用10G目标缩到30G留20G余量给未来用户数据var当前已用46G目标扩到120G对应未来两到三个月日志和缓存增长剩余空间留在VG里作为“机动池”谁满了给谁加。备份位置同样要提前想好。最忌讳的是把备份放到home自身或var自身因为后面这些LV本身会被改动。我一般临时挂一块数据盘到/backup或者rsync到另外一台服务器。即便你只是把home从500G缩到30G重建LV也相当于推倒重来不备份就是赌命。3. 关键岔路XFS与ext4对“缩小”的容忍度完全不同3.1 XFS为什么不能缩小XFS在设计上是专门冲着大文件、高并发、大容量去的它的元数据结构和空间管理逻辑都是为“增长”设计的官方从始至终没有提供缩小文件系统的能力。如果你在XFS的LV上直接执行lvreduceLVM会警告文件系统不支持shrink继续操作等于销毁文件系统。有人不信邪加个-y硬跑后果就是/home整个目录树直接消失。这个坑我见过不止一次属于这个操作里最经典的翻车原因。3.2 ext4的缩容机制ext4是支持缩容的但缩容动作必须在文件系统未挂载状态下做。先umount再用resize2fs把文件系统缩到目标大小最后才能lvreduce缩小LV。LVM其实提供了-r参数能自动调用resize2fs但在生产环境我第一次操作时还是选择手动分开执行每一步看输出出了问题也知道是哪一步。3.3 两条路线对比文件系统支持在线扩大支持缩小缩小方式推荐路线XFS支持用xfs_growfs不支持只能备份、删LV、重建LV、恢复第4章ext4支持用resize2fs支持但需先卸载先resize2fs缩文件系统再lvreduce缩LV第5章这里多提一句如果home和var都是XFS“减少home增加var”这个需求实际拆解动作是“拆掉旧home、重建一个新home、把拆出来的空间补给var”。表面看起来动静大但只要home里实际数据不多整个维护窗口也就十来分钟。最怕的是home里堆了几百G又没法快速备份那种情况就得评估是不是有其他路径比如直接给var加一块新盘、或者把部分应用数据目录软链到home去。但本文还是围绕最常见“home数据不多”的场景讲。4. XFS场景下的完整操作备份、拆home、重建home、扩容var4.1 准备维护窗口和备份选一个业务低峰期先停掉会往/home写数据的任务。比如这台机器上有几个用户的定时任务我都提前打了招呼让他们退出。然后建立备份目录并开始同步mkdir -p /backup rsync -a --delete /home/ /backup/home_bak/同步完成之后对比两个目录的大小du -sh /home du -sh /backup/home_bak两个数字一致就说明备份完整。如果/home里有正在被写入的日志文件rsync前最好先停掉相关进程实在停不了就做两次rsync第二次只同步增量也能保证一致性。4.2 卸载home并处理占用进程fuser -mv /home umount /homefuser -mv会列出来哪个进程正在使用/home目录。如果umount返回target is busy千万别用umount -l直接强制卸载应付了事——那只是表面卸载进程还卡在原地。正确做法是定位进程能优雅停就优雅停实在不行才用fuser -km /home。这台机器上有个screen会话没退出导致我卡了几分钟后来把会话结束才正常卸载。4.3 删除旧home逻辑卷lvremove /dev/centos/home执行后LVM会询问确认输入y。紧接着用vgs再看一眼VFree应该从0变回约500G。删除前我用lvdisplay把原来的LV大小、VG名、Profile都截图存了一份。这一步很多人不敢动其实只要备份在手删除本身不可怕真正的风险是后面忘了重建home就重启系统。4.4 重建一个合适大小的home并挂载lvcreate -L 30G -n home centos mkfs.xfs /dev/centos/home mkdir -p /home mount /dev/centos/home /homemkfs.xfs会创建一个全新的空文件系统。挂载时有个坑如果/etc/fstab里写的是/dev/mapper/centos-home这种路径直接能挂上如果写的是UUID会挂载失败因为新LV的UUID跟旧的不一样。所以这里建议先手动mount挂完再回头改fstab。改fstab的细节我在第6章专门讲。4.5 恢复home数据rsync -a --delete /backup/home_bak/ /home/rsync的-a参数很重要它会把文件权限、属主、属组、时间戳一并恢复。如果不用-a等你把数据同步回去用户会发现目录权限全乱了那种问题比磁盘空间更麻烦。4.6 给var扩容并放大XFS文件系统接下来是重头戏把拆出来的空间补给varlvextend -L 120G /dev/centos/var xfs_growfs /varlvextend -L 120G是把var逻辑卷直接设为120G。如果之前var已经是50G等价写法是lvextend -L 70G /dev/centos/var效果一样看个人习惯。重点在于逻辑卷LVM层扩大了还不够XFS文件系统层不会自动跟着变大必须执行xfs_growfs。通常直接给挂载点即可比如xfs_growfs /var也可以写设备路径。4.7 验证扩容结果df -hT /home /var mount | grep -E home|var此时应该看到home 30G、var 120G并且挂载状态正常。做完之后VG里通常还剩下一些未分配空间我的建议是先留着不要全部分完以后哪个分区紧张了直接lvextend非常方便。5. 如果你的home是ext4可以直接走“在线瘦身”5.1 为什么缩容顺序是铁律ext4缩容有两个动作先缩小文件系统再缩小LV。顺序千万不能反。你可以把文件系统想象成衣柜里的隔板LV想象成整面墙。必须先让隔板往左挪resize2fs再让整面墙往左挪lvreduce。万一先挪墙再挪隔板右边的衣服全被墙挤烂数据直接没。所以顺序就是umount - resize2fs缩小 - lvreduce缩小 - mount。5.2 完整命令序列假设home是ext4当前500G目标缩到30G# 1. 备份同一套备份逻辑 # 2. 卸载 umount /home # 3. 先缩小文件系统到30G resize2fs /dev/centos/home 30G # 4. 再缩小LV到30G lvreduce -L 30G /dev/centos/home # 5. 重新挂载 mount /dev/centos/home /homeresize2fs执行完会打印出新的文件系统大小确认跟目标数字一致再往下走。如果输出里有nothing to do字样多半是目标容量比当前文件系统还大检查一下是不是单位或者数值写错了。然后给var扩容# 如果var也是ext4 lvextend -L 120G /dev/centos/var resize2fs /dev/centos/var # 如果var是XFS则用 # xfs_growfs /var这里特别容易混。很多机器根和/var是XFS只有手工划出来的home是ext4所以扩容var时要先想清楚var本身是什么文件系统再去选对应命令。5.3 ext4路径的边界条件ext4缩容还有个现实约束目标容量不能小于home里的实际数据占用量。比如home已经用了40G你想缩到30Gresize2fs会直接拒绝。这时要做的不是硬缩而是先删数据、迁移数据或者干脆回到XFS那种“备份重建”路线。你自己选哪种完全看home里数据量大小和能接受的停机时间。6. 收尾最容易翻车的几个细节fstab、挂载验证与回滚预案6.1 fstab里到底要不要改UUIDXFS路线重建home之后这一步几乎必做。先查新UUIDblkid /dev/centos/home然后打开/etc/fstab把原来home那一行里的UUID替换成新的。改之前顺手备份一下cp /etc/fstab /etc/fstab.bak改完不急着重启先执行mount -a df -hT /homemount -a会把fstab里所有未挂载的项自动挂一遍有错当场报出来总比重启后卡在Emergency模式再进救援修fstab强一百倍。我认识的好几个人都在这里翻过车home LV删了重建fstab没改重启后系统起不来。6.2 var扩容后的挂载验证var从头到尾没有卸载fstab也没动理论上不用改。但我会习惯性检查一下mount | grep /var 能看到正常挂载往/var/tmp下写一个文件再删掉确认写权限正常重启后df输出依然保持新容量。有一点务必记住xfs_growfs改的是文件系统在线状态不需要改fstab重启后也不会丢。有人以为扩容完必须在fstab里写点什么纯属多虑。6.3 回滚预案怎么看只要备份还在回滚的核心就一句话把home重建回去把var扩大这事没法让XFS缩回去。所以做决策时要留后路我的做法是home的最终尺寸宁可先紧凑一点VG里保留一部分未分配空间。真到了home不够用就直接用剩余空间lvextend给home一分钟搞定。最怕的是把VG空间全部分完以后想动任何一个LV又得做一次备份重建循环。6.4 我踩过的几个坑第一个坑就是lvremove前没仔细看fstab。当时以为删掉home、重建home、更新fstab就行结果忘了改UUID重启后系统进紧急模式最后拿Live系统把fstab注释掉才救回来。从那以后我养成一个习惯调整LV前先把/etc/fstab备份一份改完立即用mount -a验证。第二个坑是umount /home一直报busy。排查后是有人在screen会话里挂着当前目录正好停在/home。以后每次操作前我都会先w看一下有没有用户挂机再fuser -mv确认占用进程。第三个坑是命令选错。给var扩容时随手敲了resize2fs /dev/centos/var结果报错提示文件系统不是ext4我才反应过来这台机器var是XFS应该用xfs_growfs。命令敲错了不会马上毁数据但会把自己吓个半死所以现在我会先df -hT看清楚类型再选命令。第四个坑涉及容量精度。lvreduce -L 30G之后实际df看到的大小偶尔会是29.99G或者30.01G这是LVM按PE取整的结果属于正常现象。不要为此反复调整浪费精力。真正要注意的是在目标值后面多留1G左右余量给文件系统元数据留点空间别抠到小数点。6.5 我现在的操作习惯最后说一个我自己的习惯整套操作开始前把lvs、vgs、df -hT、blkid的输出全部存到/root/lvm_plan_before.txt操作完成后再存一份after文件。这不算什么高深技巧纯粹是为了复盘。磁盘扩容这个场景翻车往往不是命令本身复杂而是当时手上信息不全或者做完忘了当初给var定的目标容量。有了前后对照下次再碰到类似的home/var空间失衡问题十分钟就能定位并处理完。这台机器后来var很快涨到了100G我直接拿VG剩余空间lvextend又加了20G全程没有动home一下那种顺手的感觉才是LVM布局真正该有的体验。