资讯详情

非LVM根分区爆满怎么办?四步救急与迁移实战指南

📅 2026/10/11 16:58:33 | 华诺云谱 👁 阅读
非LVM根分区爆满怎么办?四步救急与迁移实战指南
半夜两点被电话叫醒登录服务器敲命令结果连 history 都写不了满屏 “No space left on device”这种感觉干运维的都懂。而更尴尬的是这台机器的根分区当初装系统时就是默认分区不是 LVM也没有独立的卷组可以躺着就把容量拉大想在线扩根分区基本等于做梦。这篇文章就是我在这种“根分区不是 LVM、不能直接扩充”的前提下用实测踩坑攒下来的处理思路。内容按“先救急、再转移、后换根、最后防复发”的顺序来适合正在被根分区爆满困扰的同学参考也适合刚接手运维的新手提前存一份应急流程。1. 先别急着删文件把症状和边界搞清楚很多人一看到磁盘满了就马上rm -rf这是大忌。先花两三分钟把问题定性清楚后面能少走很多弯路。1.1 容量满了还是 inode 满了要分清根分区报错 “No space left on device”不一定就是磁盘容量用完也可能是 inode 耗尽。这是个非常经典的坑。容量满显示的是df -h100%而 inode 满要看df -i通常不会在df -h里体现出来。判断命令很简单df -h / df -i /如果df -i显示/的 IUse% 到了 100%那就算你删掉几个大文件也没用因为文件系统没法再创建新文件了。inode 满一般是因为小文件太多比如邮件队列、Docker 容器里的临时文件、或者某个程序的缓存目录疯狂生成零零碎碎的缓存。这个场景下要重点找那种“文件数量巨大但体积不大”的目录典型的是/var/spool、/tmp、/var/lib/docker/overlay2之类的。我之前处理过一台机器df -h明明才用了 60%但所有服务全在报磁盘满查了半天才发现是/var/spool/postfix/maildrop里有几十万个邮件小文件直接把 inode 吃完了。删掉这些队列文件后一切恢复。1.2 确认根分区是不是真的没有 LVM 能力题目里说根分区不是 LVM不能直接扩充但实际操作中我还是建议先验证一下别凭记忆判断。有些系统虽然根分区是普通分区但系统盘本身还有空闲空间未分配这种情况下有些分区工具是可以在线扩的如果连空闲空间都没有才真的只能靠“腾挪”。验证命令lsblk blkid pvs vgs lvsblkid能看到根分区的 TYPE如果是ext4或xfs那基本就是普通分区。pvs、vgs、lvs三条命令如果有输出说明系统里存在物理卷、卷组或逻辑卷但还需要确认根文件系统是不是挂在逻辑卷上。判断方法很简单df -h /显示的设备名如果是/dev/mapper/xxx-xxx这种路径说明根在 LVM 上如果是/dev/sda1、/dev/vda1这种那就是普通分区。确认了根分区就是普通分区同时整块磁盘又没有剩余空间比如lsblk里 sda 已满那就别浪费时间研究在线扩容了直接把目标定为“怎么把根目录里的东西转移到别处”。1.3 先给根目录做个体检找出哪些目录能“搬家”在动任何手之前我习惯先看一下根目录下各大目录的体积分布。这一步是后续所有操作的决策依据。du -xhd1 / 2/dev/null | sort -rh | head -20这个命令只统计根文件系统上的目录不会跑到其他挂载点里去所有输出按大小倒序前 20 条就是主要“体重”来源。正常情况下根分区里体积最大的通常是/usr、/var、/home、/opt这几个目录。但是这里要区分清楚/usr系统软件和库动它风险极高一般不建议迁移特殊情况下可以但那是大工程。/var日志、缓存、临时文件这是重灾区也是优先清理和迁移的对象。/home用户数据很多时候这个目录占了好几十 G但从业务角度看它又不是那么“紧急”适合迁移。/opt第三方软件数据量也不小迁移时需要配套修改服务配置。把这张目录地图做出来之后心里就有谱了哪些东西能删哪些东西能搬哪些东西只能硬扛。2. 救急三板斧从根分区内部挤出救命空间确认问题性质后第一步不是扩容而是“止血”。哪怕是暂时腾出几百 MB 空间都好过机器完全不可用。下面这几招是我实测最有效的按优先级来。2.1 先清日志journald 和 logrotate 是主要目标几乎所有根分区爆满的机器日志都占了大头。很多系统用 systemd-journald 记录日志默认情况下日志可能积累好几个 G这是第一个要处理的地方。查看 journal 占了多少journalctl --disk-usage强制收缩到 200MBjournalctl --vacuum-size200M这条命令会立马释放空间不用重启服务。但注意一点--vacuum-size的判定是基于 journal 文件的大小不是按天数所以如果机器日志特别多日志轮转很快可能需要配合天数限制journalctl --vacuum-time7d清完 journal 之后再手动触发一次 logrotate。传统日志都在/var/log下由 logrotate 定期压缩轮转但因为根分区满了logrotate 可能已经很久没跑成功过了。手动执行一轮logrotate -f /etc/logrotate.conf执行完再看/var/log的体积通常能清出来不少空间。这里有个小经验/var/log里像syslog、messages、kern.log这些文件如果体积异常大可以直接清空前提是你确认不需要历史日志了truncate -s 0 /var/log/messages truncate -s 0 /var/log/syslog但我一般不推荐直接把整个日志文件删掉再重建因为有些服务持有旧文件句柄删除后日志写入会出问题用truncate把文件清空才是正规做法。2.2 清包管理器缓存和临时文件包管理器装过的软件包、更新过的缓存躺在/var/cache下面常年不清理累计起来也是几个 G。不同发行版命令不一样# CentOS / RHEL 7/8/9 yum clean all # Fedora / RHEL 9 dnf clean all # Debian / Ubuntu apt-get autoclean apt-get clean/tmp目录也要看一眼但清理时要小心。find /tmp -type f -atime 7 -delete这类按访问时间删的写法相对安全不要直接rm -rf /tmp/*因为可能有一些服务正在使用的 socket 文件或临时文件挂在/tmp下一刀切容易出事。另外别忘了清 core dump。程序崩溃产生的核心转储文件有时候一个就好几个 G都在/var/lib/systemd/coredump 或 /var/crash 下面。可以清空rm -rf /var/lib/systemd/coredump/* rm -rf /var/crash/*2.3 Docker 容器日志是大户如果这台机器跑 Docker那/var/lib/docker/containers下的容器日志很可能才是根分区爆满的真正“元凶”。Docker 默认不限制容器日志大小很多容器跑几个月后 json.log 能到几十 G。先看 Docker 占用总览docker system df看单独容器日志大小find /var/lib/docker/containers -name *-json.log -exec ls -lh {} \; | awk {print $5, $9}清理单个容器日志最稳妥的方式是先把容器日志文件 truncatetruncate -s 0 /var/lib/docker/containers/容器ID/*-json.log根分区告急时这是最立竿见影的一招。但更重要的是治本在 docker-compose或容器启动参数里加上日志轮转限制例如 max-size100m。这里敲个重点不重启容器直接 truncate 日志文件不会影响容器运行但如果直接把文件删了Docker 进程持有了旧句柄磁盘空间不会释放这点跟上一节说的一样。2.4 用 find 精准定位大于几百 M 的“钉子户”前面几招做完空间通常已经松动了。如果还不够那就得用 find 把根目录下大于一定体积的文件翻出来看看还有什么漏网之鱼find / -xdev -type f -size 500M -exec ls -lh {} \; 2/dev/null | sort -k5 -rh-xdev这个参数很重要它限制 find 只在根文件系统内找不会跑到挂载的其他磁盘里避免结果太杂。实际工作中我在这步找出来的东西五花八门几百 M 的邮件附件临时文件、应用生成的超大 dump 文件、某个开发同学故意丢在 /root 下的安装包、甚至有几个 G 的数据库备份 sql 文件。遇到这种文件先判断能不能删不能删就考虑挪到别的磁盘。3. 转移大目录把根分区里的“硬骨头”迁到别的盘清完之后如果根分区使用率还在 80% 以上那说明这台机器本身的“骨架”就放在根分区上单纯靠删东西解决不了长期问题。这时候就得用“搬家”的思路把根分区下的大目录迁到独立的数据盘上去用挂载点替换目录实体。3.1 思路让根分区只保留系统把数据目录挂出去最经典的搬迁对象是/var/log、/var/lib/docker、/home、/opt。这就像你把房间里的衣柜整个搬到另一个储藏间房间里只留一个门牌挂载点柜子里的东西还在只是物理位置变了。具体目标怎么选才合理我给个优先级/var/log或/var/lib/docker占用大、增长快、对系统启动不是最关键适合第一个迁。/home如果是用户数据盘迁走对系统无感。/opt或者应用的data目录迁走后需要修改服务配置里的路径或挂载点。/usr不推荐除非你真的很清楚自己在做什么。3.2 实操把 /var/log 迁到新数据盘举例说明当前根分区/dev/vda1已经 98%数据盘/dev/vdb是整块空盘计划把根分区下的/var/log整体迁移到/dev/vdb1。第一步给数据盘分区并格式化。这一步我会用parted或者fdisk都行这里用最直观的方式fdisk /dev/vdb # n 新建分区一路默认w 保存 mkfs.ext4 /dev/vdb1第二步临时挂载新盘把原/var/log内容完整拷过去。这里必须用rsync而不是cp因为rsync可以保留权限、属主、时间戳mkdir -p /mnt/newlog mount /dev/vdb1 /mnt/newlog rsync -aXS /var/log/ /mnt/newlog/-a是归档模式保留权限-X保留扩展属性SELinux 上下文-S处理稀疏文件在迁移日志目录时这三件套基本是标配。第三步把原目录移走创建新的空挂载点mv /var/log /var/log.old mkdir /var/log第四步改/etc/fstab加入新盘的自动挂载echo UUID$(blkid -s UUID -o value /dev/vdb1) /var/log ext4 defaults 0 2 /etc/fstab注意这里有个常见的错误如果直接把UUIDxxx写进 fstab 而没有先测一下mount -a下次重启风险很大。正确做法是写完之后先验证mount -a df -h /var/log看到/var/log的容量变成了新盘的大小挂载成功那这个迁移就完成了。最后确认服务日志正常写入然后保留/var/log.old几天作为备份确认没问题后再删。3.3 软链接方案能应急但不能太依赖有些人图省事直接把目录迁走后在原位置建一个软链接mv /var/lib/docker /data/docker ln -s /data/docker /var/lib/docker这个方案能用但我不建议作为长期方案原因有两个一是很多系统服务在启动流程里加载挂载点如果某些服务在挂载数据盘之前就去读取/var/lib/docker软链接还没就绪就会失败。实际上 Docker 在启动时本身会处理软链接路径但确实有些依赖路径检查的守护进程对符号链接不友好。二是软链接只对单个用户访问有效如果应用通过容器、chroot 或特定 systemd 单元访问可能因为链接目标不可达而失败。“直接挂载”永远比“软链接”规范。软链接更适合应急场景过渡几天可以长期跑还是改成 fstab 挂载。3.4 迁 /home 时别忽略用户权限/home的迁移流程跟/var/log完全一样但有一个细节特别容易踩坑用户 UID/GID 的对应关系。如果你从一台旧机器 rsync 数据过来而新机器上用户的 UID 不一致用户登录后可能看到文件属主变成了数字。所以 rsync 的时候要带上--numeric-idsrsync -aXS --numeric-ids /home/ /mnt/newhome/生产环境里迁/home之前还要确认有没有服务在写用户目录比如 cron 任务、web 会话最好在低峰期操作或者先把相关服务停掉。4. 非 LVM 根的硬核扩容换根——把整个根分区搬到大盘上如果根分区里该清理的清理了、该转移的转移了但空间还是不够而且业务要求根分区必须变大那就只剩最后一个硬核方案把根分区“搬家”从旧的小盘换到一块更大的新盘上。这个方案的思路不是去“扩”旧分区而是把根文件系统的整个内容复制到新的大磁盘上然后把启动引导指向新盘。说白了就是“换根启动”。4.1 适用场景和准备工作先说清楚这一步操作有停机时间而且风险等级高适合在维护窗口做。第一种情况是物理机/云主机还有额外的数据盘或可挂载的新数据盘第二种情况是服务器根分区在旧盘上但系统里已经插了一块更大的新盘。两种情况都需要重启服务器。操作之前必须有的准备完整的备份至少要把/etc、数据库数据、应用配置备份出来。一台能随时介入的远程管理界面或本地终端防止系统起不来还能抢救。对 UEFI 和 BIOS 要有基本的判断能力不然照样翻车。4.2 实操用 rsync 把根迁到新磁盘我用一个实际案例来演示原根分区/dev/vda1只有 20G使用率 96%新增了一块 100G 的云盘/dev/vdb目标是让系统从新盘启动根分区变成 100G。第一步给新盘分区并格式化fdisk /dev/vdb # n 新建主分区p 指定为 /dev/vdb1 mkfs.ext4 /dev/vdb1第二步把新盘挂到临时目录然后用 rsync 把现有根目录整个复制过去mkdir -p /mnt/newroot mount /dev/vdb1 /mnt/newroot rsync -aAXv --exclude{/dev/*,/proc/*,/sys/*,/tmp/*,/run/*,/mnt/*,/media/*,/lostfound} / /mnt/newroot/这里解释一下参数-A保留 ACL-X保留扩展属性SELinux-v看同步进度。--exclude后面列的是运行时虚拟文件系统这些目录不能拷贝否则会把当前系统的内存数据复制过去。第三步在/mnt/newroot下重建必要的虚拟目录然后挂载系统运行时的文件系统准备 chrootmkdir -p /mnt/newroot/{proc,sys,dev,run,tmp} mount --bind /proc /mnt/newroot/proc mount --bind /sys /mnt/newroot/sys mount --bind /dev /mnt/newroot/dev mount --bind /run /mnt/newroot/run第四步进入新根环境重新安装引导程序。这一步是整个换根操作里最容易出问题的环节先说 BIOS/传统启动的场景chroot /mnt/newroot grub2-install /dev/vdb grub2-mkconfig -o /boot/grub2/grub.cfg exit如果是 UEFI 启动情况会复杂一些。需要在 chroot 前把 EFI 分区也挂载进去比如原来的/boot/efi挂载在/dev/vda15那也要 bind 到新根对应的路径然后重新生成 UEFI 引导项。第五步修改新根里的 fstab把/的 UUID 改成新分区的 UUIDblkid /dev/vdb1 vi /mnt/newroot/etc/fstab # 把 / 挂载行里的 UUID改成上面查到的第六步重启前最后确认一次。检查新盘的 grub 配置里内核的 root 参数指向的是否为新 UUIDgrep root /mnt/newroot/boot/grub2/grub.cfg确认无误后关机把旧盘拆下或调整启动顺序然后从新盘启动系统。启动后执行df -h /如果看到的是 100G说明换根成功。4.3 迁根成功后还有哪些收尾工作换根不是把系统跑起来就完事了还得检查这么几个点第一SELinux 可能要重新打标。如果你打开了 SELinuxrsync 虽然带上了属性但文件上下文可能对不上启动后可以先执行touch /.autorelabel reboot很多人在迁根之后卡在 SSH 连不上、服务起不来都是因为 SELinux 上下文乱了。第二网卡配置。如果你用的云主机网卡的设备名可能因为换了启动盘而改变比如从 eth0 变成了 ens3。这种情况下/etc/sysconfig/network-scripts/ifcfg-eth0可能匹配不上需要根据新环境重新生成网络配置。第三原来的旧盘不要急着格式化。保留一周作为回滚手段等确认系统稳定了再格式化把数据接回去。4.4 换根失败后的紧急恢复思路万一重启后系统进不去不要慌回滚方案也很清晰保留旧盘不动在管理界面把启动顺序改回旧盘或者直接拔掉新盘系统就回原样了。迁根方案最大的优点就是旧系统还在任何时候都能回头。如果旧盘已经被拆了只能从当前状态恢复那就需要手头准备一块 Linux Live 系统盘通过 live 环境把新盘挂载然后检查 fstab、grub 配置、内核参数逐项修复。这些排查方法跟后面的避坑章节是通用的。5. 监控与预防彻底告别“半夜被叫醒”说实话根分区爆满这种事处理一次是经验处理两次是教训要是每个月都来一次那就说明你的运维体系有问题。真正该做的是把“防爆”的机制建起来。5.1 写一个几分钟就能用上的根分区监控脚本我习惯在每台服务器放一个简单的巡检脚本跑在 cron 里不依赖额外的监控系统#!/bin/bash # /usr/local/bin/check_root_space.sh THRESHOLD80 CURRENT$(df -h / | awk NR2 {print $5} | tr -d %) if [ $CURRENT -ge $THRESHOLD ]; then echo $(date) root usage: ${CURRENT}% ${THRESHOLD}% | mail -s Disk Warning on $(hostname) opsexample.com fi然后加到 crontab*/30 * * * * /usr/local/bin/check_root_space.sh不一定非要用 mail也可以用 curl 打到企微/钉钉的 webhook关键是触发阈值后能通知到人。5.2 日志要有生命周期而不是“只增不减”很多根分区爆满的深层原因是日志策略没有配置。logrotate 不是默认就能限制所有日志的比如/var/log/syslog默认配置可能只是轮转但保留数量很大journald 更是默认不清理。至少要做的三件事第一journald 限制在 200MB 以内。编辑/etc/systemd/journald.confSystemMaxUse200M然后重启 systemd-journaldsystemctl restart systemd-journald第二确认系统 logrotate 真的在跑。cat /etc/cron.daily/logrotate是否存在以及手动执行logrotate -d /etc/logrotate.conf看有没有报错。第三Docker 默认日志限制一定要在编排里写清楚。docker run 通过--log-opt max-size100mcompose 文件里加logging: driver: json-file options: max-size: 100m max-file: 3这条配置能拦住绝大多数容器日志吃满根分区的情况。5.3 新装机的分区规划比任何技巧都重要最后说的是结硬寨、打呆仗的思路。我这些年踩过的坑总结下来就是一句话装系统时多花五分钟规划分区胜过日后半夜抢救两小时。新装机我基本遵循这些原则根分区只放系统给 40-50G 足够了单独分/home、/var、/opt甚至/var/lib/docker。能上 LVM 就上 LVM。LVM 的逻辑卷可以在线扩展遇到分区满时只需要卷组还有空闲空间一条lvextend就能解决省去今天这篇文章里所有麻烦事。如果因为历史原因没用 LVM那至少把容易膨胀的目录都独立分区这样就算/var满也大概率影响不到根分区。6. 实战避坑与排查实录这一节把我在处理根分区满时遇到过的几个典型问题和排查思路整理成速查表每一条都是真金白银踩出来的。症状可能原因排查与处置删除了大文件但df -h显示空间没变文件被进程占用删除后句柄未释放用lsof L1查已删除但被进程打开的文件找到对应进程重启或停掉journalctl --vacuum-size执行了但空间没降journal 文件被 systemd-journald 持续占用清空后空间可能没释放可以systemctl restart systemd-journald或systemctl stop systemd-journald后再清du -sh /var/log不大但 df 显示根已满可能是有大文件被删除但被进程占用或存在未挂载的分区掩盖了大空间df -h /看每个挂载点再用du -xhd1 /排除其他挂载点干扰迁移/home后用户登录看文件属主是数字UID/GID 不一致rsync 没有使用--numeric-ids下次迁移带上--numeric-ids已有问题用chown -R --from旧UID:旧GID 新UID:新GID修正改完 fstab 重启后进入 emergency modeUUID 写错或新盘挂载失败在维护界面输入 root 密码检查/etc/fstab先用blkid核对 UUID同时可以注释错误行后重启rsync 迁根后重启提示 “Kernel panic - not syncing: VFS”内核找不到根文件系统通常是 grub 里 root 参数没改成新 UUID进入 grub 编辑界面临时指定 rootUUID新盘UUID启动后重新 grub2-mkconfig迁根后 SSH 连不上可能是 SELinux 约束或网卡名变了迁移后执行touch /.autorelabel并检查网卡配置是否匹配新环境服务重启失败提示无法写日志日志目录迁移后属主错误或 SELinux 上下文不对/var/log目录执行restorecon -Rv /var/log属主改成对应服务用户如果df -h /显示 100% 但敲命令还能正常执行大概率是系统还能靠内存缓冲撑住。此时要抓住窗口期马上查不要犹豫。如果连命令都执行不了了尽量用绝对路径执行/usr/bin/df -h /、/usr/bin/du -xhd1 /有些命令在 PATH 里找不到是因为bash写不了环境文件但绝对路径依然能用。还有一个小技巧根分区完全写满时命令行提示符可能非常卡因为 bash 每次操作都尝试写 history 文件。打开一个新的子 shell清空 HISTFILEunset HISTFILE然后再执行命令体验会顺滑很多。迁移目录时我习惯先改名旧目录再建新目录原因很简单如果直接删旧目录中途 rsync 出问题就全没了。改名之后出问题还能 mv 回来只是多花几分钟而已。个人经验真遇到非 LVM 根分区爆满冷静是第一位的。先把能删的删掉把能搬的搬走轻易不要碰换根这种高级操作。换根是最后手段它需要维护窗口、完整备份和很强的排查能力如果只是 5% 的余量问题完全没有必要冒这个险。最后分享一个我长期保持的习惯每次处理完这类故障我都会把时间线、命令和结果整理成一份短文档放进服务器的/root/emergency_notes/目录。半年后再遇到类似问题翻一下就能直接照着操作比现查文档快得多。如果你也想少经历几次半夜惊魂不妨现在就给自己服务器补上一套监控和日志限制等到报警电话响起来的那天再动手就晚了。
📝

华诺云谱内容团队

资深建站顾问 · 行业研究员

10年+企业数字化服务经验,专注智能建站、SEO优化与品牌营销,持续输出建站技巧、行业洞察与营销干货,已帮助5000+企业实现数字化增长。

你可能需要的服务

订阅华诺云谱资讯周报

每周一封,精选建站技巧、SEO与营销干货,直达邮箱。已有 8,000+ 企业主订阅,助你少走弯路。

↑