做运维的朋友对这类告警短信肯定不陌生半夜里的“物理机根分区磁盘空间不足当前使用率95%”紧接着业务日志报错某张表写不进去了某服务的临时文件落不下来。等第二天早上登上机器df -h一看根分区确实只剩几个G而上面跑着的东西又不能随便停。这时候如果能用LVM在线扩容直接把根分区救活大概率能避免一次大半夜的停机维护。这篇文章就围绕“物理机根分区/磁盘空间不足LVM在线扩容”这个场景展开把完整流程、坑点、判断方式和排查思路全部讲清楚。内容主要面向系统运维、服务器管理员以及那些刚接触Linux磁盘管理、被根分区打爆折腾过的新人。我会用实际操作的视角来还原整个处理过程尽量少讲空泛概念多讲能直接“抄作业”的命令和步骤。1. 扩容前的判断你的根分区到底在哪里1.1 为什么物理机的根分区总是容易被打满虚拟机扩容相对简单因为虚拟化平台通常允许你在不关机的情况下把虚拟磁盘“热加”一块出来。物理机则麻烦得多盘位有限、硬盘采购周期长、RAID阵列配置有讲究很多时候磁盘在一开始规划时就留得比较紧张。根分区被打满最常见的几个原因大概是这样的系统日志长期未清理。/var/log下的核心转储、历史日志一年下来几十G很常见。数据库、容器、中间件的数据目录被放在了根分区下面比如/var/lib/mysql、/var/lib/docker、/home下的应用数据只要业务一增长空间消耗非常快。临时文件、回收站、Yum缓存、应用程序的备份文件都堆在磁盘上没人清理。物理机上根分区满了以后最烦人的不是“不能写文件”而是很多服务在写日志时会出现奇怪的间歇性故障比如数据库先进入只读模式、Java进程无响应。处理这类问题快速扩容往往比清理空间来得更稳因为清理动作本身可能在业务高峰期引入额外IO压力。1.2 先用三张表看清磁盘现状拿到一台根分区告警的物理机我不建议直接执行扩容命令。先把现状看清再说用三组命令半个小时基本能确定方向。第一组是df -h确认根分区的挂载点和文件系统类型df -hT /-T能看到文件系统类型。这一步很重要因为XFS和EXT4在后续扩展文件系统的命令上完全不同。第二组是lsblk看清磁盘和分区拓扑lsblk这一步能确认根分区是否落在LVM逻辑卷上。如果根分区的设备名类似/dev/mapper/centos-root说明这个根是通过LVM管理的那就可以走“LVM在线扩容”路线。如果你看到的根分区是/dev/sda2这种直接指向物理分区的路径说明当初安装时用的是标准分区没有LVM那情况就复杂一些。第三组是pvs、vgs、lvs查看物理卷、卷组、逻辑卷的分布情况pvs vgs lvsvgs里有意思的一个字段是VFree它描述卷组里还没分配给逻辑卷的空间。如果VFree已经有几十G那整个扩容动作就非常简单只要把自由空间划给根分区对应的逻辑卷再扩展文件系统即可如果VFree是0那就得想办法给卷组“加料”了。1.3 四条扩容路径先想清楚走哪条根据观察到的现状实际处理时有几种不同的路径场景扩容动作风险等级是否需要关机卷组VFree还有剩余空间直接lvextend 扩展文件系统低不需要有空闲的物理磁盘或盘位创建物理卷PV并入卷组VG再扩展LV低不需要但注意热插拔是否被硬件支持根分区所在磁盘还有未分配空间用这些空间创建新分区再把PV扩展进去中通常不需要但分区表刷新时可能有小风险根分区根本不是LVM标准分区只能做文件系统在线扩展受限或在条件允许时迁移数据重建高很可能需要停机维护关于物理机“在线扩容”有一点必须说透虚拟机可以相对随意地“在线加盘”物理机的“在线”是有前提的。首先服务器的主板、HBA卡、硬盘背板要支持热插拔其次如果你用的是硬件RAID卡新插入的磁盘还需要在RAID卡的Web管理界面里先配置成热备盘、直通盘或加入现有阵列组否则操作系统层面根本看不到这块盘。很多所谓“加盘后没识别”的问题实际上根本不是系统问题而是RAID卡层面没有把磁盘放出来。那什么时候需要关机只有当服务器不支持磁盘热插拔或者RAID卡不支持在线配置新盘或原有磁盘阵列组已经无法在线扩展时才需要考虑停业务、关机加盘。绝大多数现代服务器尤其是机架式物理机支持硬盘热插拔这是在线扩容的大前提。2. LVM扩容的核心细节与前置检查2.1 把LVM的四个对象理顺PV、VG、LV、文件系统LVM这套东西很多刚接触Linux的同事总觉得它很玄乎其实可以类比成“仓库管理”。整个根分区LVM在线扩容本质上就四步物理卷PV相当于一块块真实的仓库库房卷组VG相当于把这些库房统一管理起来的仓储管理中心逻辑卷LV相当于从仓储中心划给某个业务部门的一块区域文件系统相当于在这个区域上做的货架规划和摆放规则。当根分区空间不足时你要做的事就是要么把一个新库房新磁盘/新分区并入仓储中心创建PV并加入VG要么把库房里闲置的空间激活然后从仓储中心多划一块区域给业务部门lvextend最后让业务部门知道区域变大了扩展文件系统。很多人执行扩容失败或者扩错位置往往是因为没有先理清这个层级关系。比如直接在物理分区上扩展文件系统或者明明已经lvextend了却忘了执行文件系统扩展那一步导致df -h毫无变化。2.2 物理机扩容前必须确认的四个条件第一个条件文件系统类型。这个不确定后续命令可能直接报错或者没有任何效果。目前物理机上最常见的根文件系统是XFS和EXT4。两者在扩展时的命令差别很大文件系统扩展命令参数对象是否可以缩容XFSxfs_growfs /挂载点不支持EXT4resize2fs /dev/mapper/xxx-root设备路径可以缩容但风险较高有些新同事把xfs_growfs /dev/mapper/centos-root写成设备路径命令直接报“not a mount point”这是因为xfs_growfs接受的是挂载点而不是设备文件。第二个条件确认根分区确实在LVM上。用lsblk看根分区的依赖关系。如果根是/dev/mapper/xxx-root下面挂着vg-root再下面才是物理分区即可走LVM扩容如果根就是/dev/sda2你在物理分区层面做在线扩展文件系统非常受限除非底层分区本来就支持扩容。第三个条件明确空间从哪里来。是卷组VFree有空间还是需要加一块新磁盘还是根所在磁盘还有未分配空间三种来源的操作方式不一样。比如根所在磁盘上还有空闲分区你可以在同盘上新建一个分区塞进去这对只有单块盘、没有额外盘位的机器很有用如果你需要新加一块盘那么还牵扯到识别和RAID卡配置。第四个条件数据安全和业务影响面。在线扩容虽然理论上不需要停机但是任何写盘操作都有风险。物理机不比打快照虚拟机可以随便做快照回滚物理机一旦中间某一步出问题恢复代价远高于虚拟机。稳妥的做法是至少确认备份策略有效如果机器上有数据库等关键业务最好在业务低峰期操作并在带外管理界面IPMI/BMC开着以备意外时远程切换。2.3 给卷组“加料”的两种磁盘准备方式假设我们需要新增加一块物理磁盘来扩容操作上通常有两种做法第一种做法是直接整盘作为PV。也就是说新盘/dev/sdb不划分区直接执行pvcreate /dev/sdb这样做的好处是简单、省去分区步骤不会遇到分区表刷新问题。缺点是如果之后想用这块盘做别的用途灵活性会差一些。很多运维老手其实很喜欢整盘PV因为生产环境里加一块盘就是为了扩一个VG没必要再分一个区。第二种做法是创建分区后再作为PV。有些服务器管理规范要求每个磁盘必须有分区表或者你希望后续还能把盘分给多个用途那就用fdisk或parted创建一个LVM分区。分区类型代码在MBR分区表下是8eLinux LVM在GPT分区表下LVM使用特定GUID。fdisk /dev/sdb进入交互界面后输入n新建分区一路回车用默认大小然后输入t改分区类型为8e最后w写盘退出。这里有一个职场上很常见的坑fdisk写盘时提示“Device or resource busy”或者partprobe刷新后看不到新分区。这是因为内核还在使用旧的磁盘分区表。针对这种情况可以试试partprobe /dev/sdb # 或者用 partx 强制让内核读取新分区 partx -a /dev/sdb如果都搞不定某些老内核环境下就只能重启机器让分区表生效。物理机重启代价比较大这也是为什么很多运维会选择整盘PV绕开这个问题。3. 实操一步步完成根分区在线扩容3.1 新盘或空闲空间就位后先让系统识别磁盘我现在假设一个最常见的场景物理机上还有空闲盘位你插入了一块新的企业级SATA或SSD硬盘想把它并入现有根所在的卷组。系统开机状态下插入硬盘后第一步是确认操作系统是否识别到了这块盘。lsblk fdisk -l如果看不到新盘先检查RAID卡配置如果确认磁盘在RAID卡上已经作为直通盘或独立卷存在大多数服务器支持在线识别。很多HBA卡和RAID卡在系统运行时不自动扫描新设备需要手动触发SCSI扫描echo - - - /sys/class/scsi_host/host0/scan或者使用系统自带的重扫工具比如rescan-scsi-bus.sh把host0、host1都扫一遍。这一步在物理机上非常常见也是虚拟机环境里根本不用考虑的操作。新盘识别后把文件系统类型和VG信息再确认一遍blkid /dev/sdb pvs vgs正常来说这块新盘现在是没有任何文件系统的blkid不会有输出。接下来我们决定用整盘PV方式还是分区方式。为了绕开分区表刷新问题简化流程我个人在只有“加盘扩容”这一个目标时习惯直接用整盘PV。pvcreate /dev/sdb vgextend centos /dev/sdb vgsvgextend把新PV加入到根分区所在的卷组之后vgs里能看到VFree从原来的不满变成了新盘的全部容量比如新盘2TVFree就是2T。这里有一个细节值得展开如果磁盘比较大比如8T、10T直接整盘PV完全没问题。但如果你后续想把这块盘拆成多个用途那显然不适合整盘PV。权衡的核心在于分区表刷新带来的“Device or resource busy”风险对于在线扩容来说把风险降到最低是第一原则。3.2 把逻辑卷LV扩出来卷组里有了自由空间接下来要做的就是把自由空间分配给根分区所在的逻辑卷。先搞清楚根逻辑卷的设备名lvs假设输出显示/dev/centos/root对应根挂载点/那么执行lvextend -L 100G /dev/centos/root100G表示在原有基础上增加100G。如果你想直接把所有剩余空间都分给根执行lvextend -l 100%FREE /dev/centos/root但这里我要提醒一下只有当这台机器上没有其他逻辑卷需要预留空间时才建议100%FREE。如果卷组下面还有home、var等逻辑卷一次性把所有空间都塞给根分区将来扩其他分区时又得折腾。实际生产中我倾向于先按需分配比如日志和业务数据长得快就给根扩100G留一部分空间在卷组里备用。lvextend执行完以后用lvs再看一眼确认LV Size已经变大。到这一步千万别急着看df -h因为文件系统还没有感知到逻辑卷的变化df必然还是老样子。3.3 文件系统在线感知扩容这一步是整条流程的分水岭文件系统类型决定命令。根分区是EXT4时执行resize2fs /dev/centos/root这里可以直接写设备路径不需要指定大小ext系列文件系统会自动扩展到逻辑卷的最大容量。如果是XFS执行xfs_growfs /注意XFS必须传挂载点而且XFS文件系统本身就支持在线扩大所以不需要卸载根分区。很多初学者第一次做XFS扩根时容易写成xfs_growfs /dev/centos/root然后得到一个“is not a mount point”的错误。这不是什么大问题但会吓一跳以为操作失败了。其实改成挂载点重跑一次就行。执行完文件系统扩展后再用df -h验证根分区容量应该已经变大。这里再补充一个知识XFS和EXT4在文件系统扩展能力上最大的区别是缩容。EXT4理论上有resize2fs缩容功能但因为有一定的风险在生产环境里基本没人用XFS则是完全不能缩容。所以规划空间时宁可在卷组里留点余量也不要随随便便“全部塞给根”。3.4 另一种常见情况同磁盘未分配空间的扩容如果没有额外盘位但根分区所在磁盘本身还有未分配空间比如当初分区时用了整块磁盘的一半剩下的都空着那么也可以用类似思路“自给自足”。先看磁盘分区fdisk -l /dev/sda假设/dev/sda2是LVM的PV而磁盘尾部还有几百G未分配空间。此时不要直接去对根分区进行分区调整正确做法是在空闲空间上再建一个分区把新分区并入原有LVM。fdisk /dev/sda在fdisk交互界面中新建分区起始扇区默认结束扇区默认然后改分区类型为8e写盘退出。如果提示“Device or resource busy”尝试partprobe或partx -a /dev/sda。分区表刷新成功后pvresize /dev/sda2pvresize会扫描同一个PV所在磁盘上的分区变化自动把这个新分区并入同一个物理卷这里有一个容易混淆的点同一个磁盘上有两个LVM分区时新分区通常不能被自动并入已有的/dev/sda2物理卷而是需要新建一个PV再并入VG。pvresize适用于对“同一个分区”本身的大小扩展比如在虚拟化环境里把虚拟磁盘扩大后执行。物理机同盘未分配空间新建分区更稳妥pvcreate /dev/sda3 vgextend centos /dev/sda3 vgs lvextend -L 200G /dev/centos/root后面文件系统扩展步骤就和前面完全一致了。这种“同盘复制扩容”方式的最大优点是单块盘就能解决根分区空间不足而且在物理机场景中非常实用——很多服务器根本没有第二个盘位但当初分区时给根所在磁盘留了余量。3.5 扩容实操命令流程速查我给这套标准流程做一个收敛方便你后续照着做。以“新磁盘 /dev/sdb 整盘PV扩容根分区”为例# 1. 确认现状 df -hT / lsblk vgs # 2. 识别新盘物理机需注意RAID卡/分区表 lsblk pvcreate /dev/sdb # 3. 并入卷组 vgextend centos /dev/sdb vgs # 4. 扩展逻辑卷 lvextend -L 100G /dev/centos/root lvs # 5. 扩展文件系统二选一 # ext4: resize2fs /dev/centos/root # xfs: xfs_growfs / # 6. 验证 df -h /整个流程里最需要耐心的是第一步和第二步之间的“等待识别”环节。物理机上插入硬盘到系统能看到设备有时会有几十秒到几分钟的延迟特别是RAID卡后台还在做初始化扫描的情况下。不要急着狂刷命令给硬件一点时间。4. 常见问题与排查技巧实录4.1 为什么 lvextend 之后 df -h 还是老样子这是遇到频率最高的一个“故障”严格来说它不是故障是操作顺序问题。LVM扩容有逻辑卷层和文件系统层两个环节。lvextend只改了逻辑卷大小没有动文件系统文件系统只有在执行resize2fs或xfs_growfs之后才真正把新空间纳入可用范围。如果lvextend后执行文件系统扩展出现报错先确认文件系统类型和根分区挂载状态。XFS的xfs_growfs要求挂载点参数并且文件系统必须处于挂载状态EXT4的resize2fs在挂载状态下也支持在线扩展但在某些老内核版本上可能会提示文件系统已挂载让你先卸载再执行。如果你遇到这种情况先确认根分区是否可以卸载——显然不能卸载。老内核上处理方式是用resize2fs增加“在线扩展”相关选项或者检查该ext4文件系统是否启用了online resize支持。4.2 新创建的分区内核识别不了Device or resource busy真的比较让人头疼的是这个。执行fdisk写分区表时一切看起来正常写盘结束时提示Device or resource busy系统还在用这块磁盘的旧分区表所以内核不允许直接重写。常见处理方法partprobe /dev/sda # 如果partprobe没有反应 partx -a /dev/sdapartx -a有时能强制内核重新读取分区。如果仍然无效看看是不是有进程在使用这块磁盘比如LVM还在尝试扫描、某个服务还占着磁盘常用lsof或fuser查一下。物理机场景下还可能是有老的内核版本完全不支持在线识别分区表那就只能等维护窗口重启。正是因为这个原因我在给物理机加盘扩容时优先选择直接把整块盘作为PV完全不创建分区彻底绕开分区表刷新。如果必须创建分区也建议优先使用parted在GPT模式下操作某些环境里它比fdisk更顺滑。4.3 物理机加盘后操作系统里看不到新磁盘这个问题在物理机上比虚拟机上常见得多。第一件事不是查Linux而是进RAID卡管理界面或带外管理面板确认新盘是否已经被RAID卡启用。很多HBA卡默认新盘状态是“未配置”需要把磁盘设为JBOD、直通盘或者加入一个已有的磁盘组。RAID卡层面没有放出来操作系统层面无论如何扫描设备都看不到它。确认RAID卡放盘之后再执行SCSI设备重扫。不同的服务器/存储配置路径不太一样通用的做法是for host in /sys/class/scsi_host/host*; do echo - - - $host/scan; done lsblk这套命令会把所有SCSI总线的设备重新扫一遍。理论上热插拔的盘都会被识别出来。如果系统里已经能看到盘符但容量不对那就要看RAID卡是否还在后台做初始化或重建。4.4 卷组VFree为0有没有办法不关机扩根分区有但只能靠上面提到的同盘未分配空间方案或者靠清理腾空间。假如根所在磁盘整个都分完了没有空闲盘位也没有卷组自由空间那办法就有限了。清理空间常常比扩容更快看看/var/log、/tmp、/var/lib/docker、/home下的临时文件删掉日志和过期备份回收几十G并不难。也可以考虑把大目录移到其他分区或外部存储再做一个软链接。如果清理之后短时间内空间又满了那说明磁盘规划本身就有问题。根分区独立规划太小、数据目录没有单独挂载运维上的教训就是“永远不要把业务数据放在根分区除非你做好了随时扩容的准备”。这种时候即便能在线扩容也只是把问题推后了。4.5 常见问题速查表现象可能原因处理方式lvextend后df无变化未执行文件系统扩展命令根据ext4/xfs执行resize2fs或xfs_growfsxfs_growfs提示not a mount point参数写成了设备路径改成挂载点比如 xfs_growfs /fdisk写分区表提示busy内核还在用旧分区表partprobe、partx -a必要时重启新盘系统不识别RAID卡未放盘或未扫描总线进RAID卡配置或执行SCSI重扫命令vgextend报错找不到设备磁盘设备未就绪lsblk确认存在或检查盘符是否改变xfs文件系统想缩容XFS不支持缩容备份后重新格式化或另找空间4.6 一个容易忽略的细节确认盘符变化物理机加盘或重启后磁盘设备名可能会变化。比如原来根分区用的/dev/sda重启后变成/dev/sdb或者新盘占了/dev/sda导致原PV对应关系变化。如果你在扩容时只记得盘符而不依赖UUID就容易把新盘搞到错误的位置上甚至把数据盘当成空盘重新创建PV。生产环境中比较稳妥的做法是lsblk -f pvs -o pv_name,pv_uuid,vg_name通过UUID确认PV和VG的对应关系而不是仅凭“/dev/sdb看起来是块新盘”来判断。5. 在线扩容之后需要留神的几件事扩容完成后大多数人的第一反应是“搞定了收工”。但根据我处理过的物理机故障后续半小时内还有几件事值得做。第一观察日志目录和业务写入是否恢复正常。根分区打满时很多进程会一直处于“写失败重试”状态扩完空间后它们不一定能自动恢复。有些服务需要重启才能重新拉起正常的文件句柄。建议扩容后重点看一下数据库和容器日志有没有恢复写入如果有异常该重启的服务还是要重启。第二确认卷组和逻辑卷现在的真实布局。记录一下扩容后的vgs、lvs输出最好贴到内部运维知识库里。这台机器下次再出空间问题后面接手的人能一眼看出还有多少余量。第三有条件的话做一次文件系统完整性检查。XFS在线扩容通常很安全但物理机硬件不稳时扩容过程可能会触发文件系统错误。趁着业务低峰跑一次xfs_repair -n或fsck -n只做检测不修复能提前发现问题避免后续故障扩大。第四在容量规划上做“复盘”。这次根分区打满到底是日志控量没做好还是数据目录规划不合理如果是前者配置日志轮转和日志压缩就能解决如果是后者重新规划第三方数据目录的挂载点才是根治方案。LVM在线扩容是很好的应急手段但不能每次都靠它兜底。说一个我个人的经验物理机扩容根分区的整体风险和压力往往大于虚拟机环境。虚拟机出问题可以做快照回滚物理机每一步操作都不可逆所以在线上执行pvcreate或lvextend之前我会强制自己在终端里先跑一遍“只读确认”流程——看blkid、看pvs、看df -h、看lsblk把所有设备名和挂载点核对无误后才动手。同时操作过程中的终端会话最好用长时间不断线的连接方式避免中途意外断开导致命令状态未知。LVM在线扩容是一项非常成熟的Linux运维技能但“成熟”不代表“没有风险”。把判断放在命令之前把检查放在操作之后这个过程本身就是运维经验的价值所在。