尧图网络科技YAOTU DIGITAL 获取报价
获取报价
首页 / 资讯中心 / 文章详情

Linux根目录空间告警排查:从df到inode到LVM扩容的完整指南

发布时间:2026/9/26 12:01:25

资讯中心
01
ARTICLE

Linux根目录空间告警排查:从df到inode到LVM扩容的完整指南

Linux根目录空间告警排查:从df到inode到LVM扩容的完整指南
服务器根目录空间又告警了进服务器一敲df -h /使用率直接顶到98%。这种情况做过运维或者自己折腾过Linux虚拟机的朋友应该都经历过根目录一旦被塞满服务起不来、日志写不进去甚至机器直接进不了系统特别被动。这篇文章就是围绕“检查根目录空间”这件事把从诊断、清理到扩容的完整套路理一遍同时也会聊几个和根目录授权沾边但经常被误会的场景比如Android设备上SD卡根目录授权失败、Word提示内存或磁盘空间不足这种它们背后其实都和根目录、磁盘空间有关。适合刚接手服务器的新手、自己做虚拟机的爱好者以及开发自测环境总是被磁盘撑爆的同学。1. “根目录空间满了”背后的真实原因1.1 先分清“空间”和“inode”两个概念排查根目录空间问题第一条要分清楚到底是磁盘空间满了还是inode满了。很多新手只知道用df -h看百分比却忽略了df -i。inode是文件系统管理文件元数据的索引节点每个文件和目录都要占用一个inode。如果小文件特别多比如缓存目录里堆了几十万个碎文件即使磁盘剩余空间还有几十GB也可能因为inode耗尽而无法新建文件。我碰到过一次挺典型的案例某台CentOS 7机器上跑了个数据采集程序每天写大量kb级别的临时文件结果根分区inode用光了应用报错说“磁盘空间不足”但df -h /看只有40%使用率。当时用df -i /一看才明白根分区的磁盘索引节点已经撑死了。所以排查时两条命令都得看df -h / # 空间使用率 df -i / # inode使用率如果inode满了处理思路上就和小文件数量有关通常是到某个目录下批量删除历史碎文件比如find /tmp -type f -name *.log -mtime 7 -delete或者调整程序不再产生这么多零碎小文件。如果空间满了那才走后面说的清理或扩容步骤。1.2 根目录盘符和其他分区的关系理解“根目录空间”之前还得先搞清楚根目录这个挂载点和你平时看到的几个常见目录的关系。Linux里/是根文件系统的挂载点但/boot、/home、/var、/tmp这些目录可能单独挂在独立分区也可能都放在同一个根分区里。如果是默认分区方案下装的系统比如很多云服务器或虚拟机安装时的默认自动分区往往/boot单独一个分区剩下的可用空间全给了/这时候/home、/var、/usr这些目录其实都在根分区下面。也就是说你往/home里放电影占的也是根目录空间。很多人习惯性认为“根目录满了”就是/下面某个直接子目录占满其实不一定下面任何一个挂载点内部目录装的东西都可能把根分区塞爆。这里有一个很容易误解的点du -sh /统计根目录下所有内容但如果你有网络盘或远程目录挂载到某个子目录du会默认跨文件系统去统计挂载点导致算出来的总占用比df显示的值大很多。正确做法是du -x避免跨文件系统统计du -xh --max-depth1 / | sort -hr | head -20加上-x之后du就不会去穿透挂载点统计出来的结果才和根分区的真实使用量对得上。1.3 文件删了但空间没释放的坑另一个特别迷惑人的现象删了一个大文件但df -h /显示的使用率一点没降。这通常不是删除失败而是这个文件还在被某个进程持有句柄。Linux删除文件时如果文件已经被打开进程仍然可以继续读写这个被标记为“已删除”的文件磁盘空间要等到进程关闭文件句柄或进程退出才会真正释放。定位方法用lsoflsof L1 | grep deletedL1表示列出link count小于1的已删除文件。找到进程PID后重启进程或杀掉该进程就能释放空间。但操作前要思考一下如果那个进程是数据库或者业务核心进程重启可能导致服务中断建议先看它是哪个服务评估再动手。曾在生产环境遇到过nginx写入access.log日志被 /var/log/nginx/access.log清空了但空间没变一查发现nginx worker进程还握着已删除的文件句柄结果是kill -USR1重开日志文件才释放直接重启也行但优雅重载更安全。2. 快速诊断5分钟内定位空间占用大头2.1 一套组合命令直接看穿分布根目录空间告警的时候最紧张的是不知道什么东西占的空间。我的固定排查套路是先看整体再逐层深入df -hT / df -i / du -x --max-depth1 / 2/dev/null | sort -hr | head -30第一条看文件系统类型和整体使用率第二条看inode第三条把根目录下第一层子目录的占用列出来按从大到小排。这一步基本就能确定“元凶”是/var、/usr、/opt、/home还是/root。然后继续往占用最大的目录里看比如确认是/var就再执行du -xh --max-depth1 /var 2/dev/null | sort -hr | head -20一层层往下递推直到找出具体的日志文件、缓存目录或数据文件。这是最笨但最可靠的方法。如果机器上有其他磁盘挂载点比如/data是独立磁盘那根目录本身一般不会因为它爆满。但需要注意/data里如果有什么目录被误放到了根分区比如/data/log因为这个挂载点失效导致写入其实落在根分区某个空目录里这种隐藏问题在容器或启动脚本出错时蛮常见。所以检查时不要只看名字要用mountpoint或df确认目录到底是独立挂载还是实际落在根分区。2.2 找出持续增长的进程占用光靠du找出大文件还不够原因是有些大文件是刚刚生成的比如日志、数据库的临时文件如果不定位到具体进程清理完还会再涨。可以用lsof或ls -l /proc/pid/fd/看某个进程打开了哪些大文件lsof -nP | awk {if ($7 104857600) print $1, $2, $7, $9} | sort -k3 -n -r | head上面是看大于100MB的文件句柄简单暴力的方法。或者lsof | grep /var看看日志目录下被谁占用。如果只是系统日志直接restart systemd-journald或者把journal清理一下就可以。另外推荐保留一个空间监控习惯定期执行一次“根目录空间Top目录扫描”把结果输出到日志这样以后复盘就知道空间是什么时候涨上来的。我自己用脚本把每天的 du 结果存到文件保留30天调优环境的时候很方便。3. 清理根目录空间能删的和不能删的3.1 日志和缓存类清理一旦定位到根目录下的日志或缓存占用了大量空间清理前务必先确认哪些能删。首当其冲的是systemd日志默认情况下systemd-journal日志会持续写入/var/log/journal而且默认不限制大小。CentOS 7还有Ubuntu 18.04以后很多系统都在用journal时间久了动辄几个GB。清理journal日志安全又直接的方法是journalctl --vacuum-size200M journalctl --vacuum-time7d--vacuum-size200M表示把journal总大小压缩到200MB以内--vacuum-time7d表示只保留7天内的日志。这是官方支持的操作比直接删journal目录安全得多也避免在服务运行中删除正在写入的日志文件引发句柄问题。还有一块大空间是包管理器缓存。CentOS/RHEL上执行yum clean allUbuntu上执行apt clean这些命令只是清理下载的软件包缓存不会影响已安装软件。长期不清理的话/var/cache/yum或/var/lib/apt/lists确实能占掉好几个GB尤其是经常做系统更新、装包测试的机器。Docker主机就更不用说了镜像、容器层、构建缓存都可能堆在/var/lib/docker。清理Docker日志时别暴力删/var/lib/docker/containers/id/*.log因为容器还在写这是我最开始踩过的坑。应该通过Docker来限制日志大小或者在运行时加--log-opt max-size100m已经很大的日志可以先truncate -s 0清空文件内容而不是删除文件。3.2 冗余内核和包残留清理CentOS/Ubuntu系统每次升级内核都会留下一个新的vmlinuz和initramfs镜像老内核如果不清理会在/boot分区堆积同时也占用根分区一部分。尤其在服务器上跑两年不管理/boot动不动就满。CentOS/RHEL下清理旧内核可用yum install -y yum-utils package-cleanup --oldkernels --count2这个命令保留最近2个内核其余删除。Ubuntu下更简单apt autoremove --purge它会自动移除不再使用的旧内核和依赖库。注意不要把当前正在运行的内核删掉删完记得看uname -r确认。另外很多系统还会残留python、node等语言包的缓存比如/root/.cache/pip可以清理pip cache purge这些缓存虽然不是系统必要的但在用户目录下面积少成多尤其测试过复杂项目之后几GB很常见。root用户的家目录同样属于根分区几GB的pip缓存删掉就是白捡的空间。3.3 根目录空间满了导致系统只读该怎么办当根分区空间彻底耗尽时文件系统可能被自动挂载为只读状态有些程序写入时直接报错“Read-only file system”。这时候首先不要慌也别直接强制重启可能连系统都进不去。处理思路是找一块可写空间然后对根分区进行清理。最稳妥的方法是重启进入单用户模式或rescue模式开机时在grub菜单里编辑启动项往内核命令行追加single或init/bin/bash进入root shell。此时大部分日志服务没起来临时文件也少可以先清理掉部分日志或临时目录然后mount -o remount,rw /重新让根分区可写再继续清理。如果连单用户模式都进不了也可以用Linux应急光盘如systemrescuecd启动到live环境挂载根分区后清理文件。这种情况我建议之后优先考虑扩容因为清理永远只是治标空间增长趋势如果本来就压不住迟早还要爆。4. 虚拟机根目录扩容实操从LVM到普通分区4.1 先判断分区类型LVM还是普通分区清理只能解决一时如果根分区长期空间不足扩容才是根治手段。虚拟机扩容根目录空间第一步是搞明白根分区是LVM还是普通分区。LVM的好处是可以在线扩展不需要卸载分区普通分区则麻烦一些遇到根分区无法卸载的情况往往需要借助live CD调整分区。用下面命令判断df -T / lsblk如果输出里有LVM字样或者设备路径是/dev/mapper/xxx-root那就是LVM。如果直接显示/dev/sda3、/dev/vda1加xfs/ext4那就是普通分区。CentOS 7默认安装时多采用LVM单独一个/boot分区根分区是一个逻辑卷。Ubuntu如果在安装阶段选择了“使用整个磁盘并配置LVM”也会用LVM默认标准分区方案则不是LVM。两种场景扩容方法不一样千万不要混着用命令否则分区表容易损坏。4.2 CentOS 7 根目录扩容完整步骤LVM方案假设在VMware/VirtualBox环境里根分区是LVM文件系统是xfsCentOS 7最常见。扩容步骤大概是先在虚拟机设置里给当前磁盘增加容量或者额外加一块虚拟磁盘。这里我以“加一块新虚拟磁盘 /dev/sdb”为例。在虚拟机管理界面添加的磁盘大小比如20GB进入系统后确认新盘是否识别lsblk应该能看到sdb设备。然后依次执行# 1. 初始化物理卷 pvcreate /dev/sdb # 2. 把物理卷加入虚拟卷组卷组名称从vgdisplay里确认 vgextend centos /dev/sdb # 3. 查看逻辑卷路径和剩余空间 vgdisplay -v centos # 4. 扩展根逻辑卷。注意-r参数会自动扩展文件系统xfs要用xfs_growfsext4用resize2fs lvextend -r -L 20G /dev/mapper/centos-root如果用的是4.x以上的LVM命令lvextend -r会自动调用对应的文件系统扩容命令非常方便。如果没带-r对于xfs文件系统还要手动执行xfs_growfs /对于ext4文件系统则执行resize2fs /dev/mapper/centos-root最后df -h /确认扩容结果。整个过程在线操作不需要重启不影响跑在上面的服务。不过网上很多教程会把“增加磁盘空间”和“新增一块磁盘”混在一起。如果你的虚拟机管理器允许在现有磁盘上直接扩容比如VMware里扩展虚拟磁盘大小到60GB那进入Linux后的操作又不一样。此时要先用fdisk或parted扩展分区这涉及分区表操作要非常小心。CentOS 7里如果是LVM且位于MBR分区表可以用growpart或fdisk删除重建扩展分区再保存但这步风险大建议先备份或者干脆采用加新盘vgextend的办法安全得多。4.3 Ubuntu 虚拟机扩展磁盘空间实操Ubuntu 20.04下如果根分区是普通分区又直接在虚拟机层面把虚拟磁盘从原先的50GB扩到了80GB那么需要执行sudo apt install cloud-guest-utils -y sudo growpart /dev/sda 1 sudo resize2fs /dev/sda1growpart的作用是调整分区表让分区占用到整个磁盘空间。注意/dev/sda后面的编号必须和实际分区号对应。如果根分区是/dev/sda3就写sudo growpart /dev/sda 3。分区表调整完成后用sudo resize2fs /dev/sda3扩展文件系统。Ubuntu 18.04的云镜像默认没有装cloud-guest-utils不装的话会提示找不到growpart命令。先装包再执行顺序别反了。如果根分区是LVM那么套路和CentOS差不多先把磁盘扩容或加新盘pvcreate、vgextend、lvextend然后看文件系统类型执行对应命令。这里一定要先用df -T /看清文件系统Ubuntu默认ext4没有xfs的话不能执行xfs_growfs。4.4 非LVM分区的扩容替代方案如果根分区正好是非LVM而且系统里没有空间继续扩展根分区了大部分人第一反应是用GParted Live引导盘调整分区。这个方法理论可行实操中有一个致命问题要从另一个系统启动并卸载根分区才能改分区大小。如果你在物理机上操作当时又没办法停机那基本只能约维护窗口。虚拟机里倒是简单一些直接挂载GParted ISO但步骤繁琐不慎容易写到分区表。我的建议是如果根分区不是LVM且数据量不大干脆迁移系统数据到带LVM的新磁盘上去。常见思路是把新磁盘做成LVM卷组然后把根分区数据打包复制过去再修改引导配置。这样比在线调整分区表更稳妥也避免分区操作导致整块盘损坏。不过这个操作步骤长适合能接受停机维护的场景不是一句两句说得清这里点到为止目的就是提醒“别照着LVM教程硬改普通分区”。5. 你以为的“根目录授权”问题其实也是空间解析5.1 Android Studio无法对SD卡根目录授权热词里有几个和SD卡根目录授权相关的问题比如“documentscontract.extra_initial_uri无法获得sd根目录授权”和“android studio无法对sd卡根目录授权”。这几个问题名字里有“根目录”但和服务器根目录膨胀不是一回事只是很多人搜“根目录”时总会碰到所以单独讲讲。Android 5.0以后应用不能随意访问整张SD卡根目录尤其是Android 8.0之后SAFStorage Access Framework成为标准路径。系统不再把“SD卡根目录写权限”直接授权给普通App而是让用户通过系统自带的文件选择器选取目录App只能拿到用户选中的某个Uri树。Android Studio里常见的报错是因为开发者在代码里直接拼装content://com.android.externalstorage.documents/document/primary/这类Uri而未经历ACTION_OPEN_DOCUMENT_TREE的用户授权流程所以系统拒绝授权。解决办法是引导用户点击“选择文件夹”用Intent.ACTION_OPEN_DOCUMENT_TREE启动系统文件选择器用户选中SD卡根目录后代码里再getActivity().getContentResolver().takePersistableUriPermission持久化权限之后才能真正读写。这里说这些是想告诉大家这类“根目录授权失败”不是磁盘故障是Android的权限模型和开发路径不匹配别跑到系统设置里反复开关存储权限浪费时间。5.2 Word“内存或磁盘空间不足”根因排查另一个热词是“内存或磁盘空间不足word无法显示所请求字体”和“microsoft word x 内存或磁盘空间不足”。Windows环境下Word经常弹这个提示原因五花八门但八成和系统盘剩余空间不足有关。Word的临时文件默认写在用户Temp目录Temp目录一般位于C盘如果C盘空间快满了哪怕你正在编辑的文档在D盘Word也会因为这个临时写入失败而提示“内存或磁盘空间不足”。修法也简单清理C盘空间特别是C:\Users\用户名\AppData\Local\Temp下的历史临时文件清理完成后重启Word基本恢复。如果清理完依旧不足再检查Word的“位置”设置里的默认文件位置和自动恢复文件保存路径是不是已被设置到了一个不存在的目录或一个内存盘上。这类问题提示词里都有“确定 帮助(h)”的弹窗属于用户在文档保存时遇到的磁盘空间不足本质还是根目录那套某一块存储池耗尽了。5.3 站长部署验证文件的根目录误区热词里还有“部署验证文件并提交证明材料适合站长或管理员选择。需在网站根目录部署文件”。这个场景里站长和管理员需要往“网站根目录”放一个验证文件这里说的“根目录”是Web服务器的DocumentRoot比如Nginx的/usr/share/nginx/html或Apache的/var/www/html。如果网站根目录所在的分区正好是系统根分区而且你发现网站根目录写不进文件往往也源于根分区空间不足——毕竟/usr/share/nginx/html在根分区下。这种情况扩分区和清理的思路一样适用只是还要检查目录权限和selinux上下文。放验证文件时建议先确认df -h /再touch一个测试文件验证写入权限不要直接大文件传上去省得到时候半天传完了发现根分区满了白折腾。6. 空间误判速查表与排错心得6.1 典型根目录空间问题速查把平时遇到的情况整理成一张表排查时可以对照着来现象可能原因处理方式df -h /显示满但du -sh /不大已删除文件被进程占用lsof L1重启/清理对应进程df -h /正常但无法创建文件inode耗尽df -i /删除小文件/碎片目录/boot分区满了旧内核过多package-cleanup --oldkernels或apt autoremove --purgeLVM扩容完成df没变化没有扩展文件系统xfs用xfs_growfsext4用resize2fs根目录变只读空间耗尽或文件系统异常进入rescue模式清理再mount -o remount,rw /根目录明明很小使用率却高其他子目录有隐藏大文件du -x --max-depth1 /逐层排查虚拟机加了磁盘lsblk看不到虚拟控制器未刷新partprobe或重启虚拟机等待识别/var/log下日志不停涨journal或服务日志未轮转限制journal大小配置logrotate这张表是我平时排查时的浓缩经验拿去直接能用。6.2 清理时最应该小心的两类文件清理根目录空间时最容易出问题的是两类一类是正在被服务使用的日志文件一类是看似无用但实际是开机流程依赖的文件。先说日志。/var/log/messages或access.log直接用rm删除服务还会继续往同名文件写但因为inode已经变了很多时候并不会自动创建新文件导致服务记录不到新日志。最好用truncate或logrotate即把文件内容清空但保留文件句柄truncate -s 0 /var/log/messages这个命令比rm安全得多。另一类是/tmp和/var/tmp下的文件看似都能清但有些程序安装包实际依赖/tmp里的共享对象文件删早了程序启动就报动态库找不到虽然概率低但清理前先du别做到“见文件就删”。6.3 监控与预防的经验“检查根目录空间”不应该等报警了才做。我的做法是写一个小脚本每天定时跑一遍#!/bin/bash df -h / | tail -1 | awk {print $5} | grep -o [0-9]* /tmp/root_usage if [ $(cat /tmp/root_usage) -gt 85 ]; then echo root usage 85% | mail -s root disk alert opsexample.com fi有条件可以接告警平台没条件就放到cron里每天发邮件或写监控日志。同时在日志模块里给journal设置上限日志服务配置SystemMaxUse500M这样就算服务异常疯狂打日志也不会把根分区写满。6.4 扩容操作里吃过亏的细节最后分享两条亲手踩过的教训。第一次给CentOS 7扩展根分区时新盘加到了卷组里lvextend也执行成功了但df -h /依旧没变。当时很纳闷查了半天发现是因为文件系统是xfs而lvextend时没带-r又没手动执行xfs_growfs /。从此以后我记住了看清文件系统类型再决定后续命令。第二次是给Ubuntu虚拟机扩容磁盘直接在虚拟机层面把磁盘容量增加了20GB然后进系统执行growpart结果提示找不到分区重启后连boot都进不去。后来复盘是分区表类型是GPT当时用的growpart命令参数指向了错误的磁盘号。从那以后凡是要动分区表我先用lsblk和sgdisk打印一份分区表备份再操作宁慢勿错。“检查根目录空间”这件事说白了就是一套“看、清、扩”的流程。看要看到子目录和inode清要清得够稳不伤服务扩要扩对文件系统类型。把这些细节刻进操作习惯里再碰上根目录爆满就不会手忙脚乱了。
02
RELATED NEWS

相关资讯

更多网站建设与数字化升级内容

03
WHY YAOTU

想打造同款高转化官网?

懂行业、懂生意,从建站到增长一站式陪跑

◈

场景化定制

不做模板站,围绕你的业务场景量身设计,小众不撞款。

◐

营销型架构

以转化目标组织内容与路径,让官网真正带来询盘。

▲

全周期服务

设计、开发、运营、运维一体,上线只是开始。

免费获取你的建站方案

留下需求,专属顾问 24 小时内为你输出方案建议。