☰
磁盘不足告警排查全攻略:从告警链路到空间释放
2026/9/30 3:06:09 网站建设 项目流程

凌晨两点半,手机震了一下,监控平台弹出一条告警:华东某网点的数据服务器磁盘使用率超过85%阈值。说实话,这种告警我已经见得太多,但每一次都不敢掉以轻心,因为磁盘告警一旦处理不及时,要么业务写入直接报错,要么系统日志丢得一干二净,最后背锅的还是运维。

这次排查过程不算复杂,但把“磁盘不足阈值告警”背后涉及的知识点全部串了一遍:从告警链路怎么产生的,到阈值怎么定才合理,再到登录服务器之后用什么指令快速定位,最后到文件删除但空间不释放这种经典坑。这篇就完整记录一下整个排查思路和实操过程,顺带聊聊告警降噪和监控闭环的问题,希望能给同样被磁盘告警烦过的运维朋友一点参考。

1. 磁盘告警链路与阈值设定:先弄懂告警是怎么来的

很多刚入门的运维看到磁盘告警,第一反应就是登录服务器执行df -h,看看是不是真的满了。这个动作没问题,但如果你不了解告警是怎么产生、怎么传递、怎么触发的,就很容易被假告警带偏节奏,或者漏掉真正需要关注的隐患。

1.1 告警产生与传递的完整数据链路

一次标准的磁盘告警,背后通常是这样的链路:

  1. 被监控主机上部署了Agent(比如Prometheus的node_exporter、Zabbix Agent、夜莺的categraf),定时采集磁盘使用率指标。
  2. 采集到的指标被推送到监控服务端,按照预设的数据模型打上标签,比如主机IP、挂载点、文件系统类型。
  3. 监控服务端的告警规则引擎对指标做计算,比如磁盘使用率大于85%,持续触发5分钟后才判定为告警。
  4. 满足条件后生成告警事件,再通过通知渠道推送出去,常见的有企业微信机器人、钉钉、短信、邮件。

这里有个容易被忽略的点:告警规则里的“持续触发时间”很重要。运维新手配置规则的时候经常只填阈值,不填持续时长,结果磁盘使用率一抖动,告警短信就轰炸一遍,十分钟后又恢复,十分钟后又触发,夜里的睡眠质量直接被毁掉。后来我养成的习惯是,磁盘类告警至少持续300秒以上才触发通知,这个参数能过滤掉大量临时波动。

监听到告警事件之后,我一般不会立刻上手处理,而是先看一眼告警面板上的指标曲线。如果曲线是从79%突然跳到85%,说明有大批数据写入;如果是缓慢爬坡爬到85%,那就是日常积累没有清理机制。这两种情况的排查方向完全不同,前者要去看业务写入,后者要找历史垃圾文件。

1.2 磁盘告警阈值该设多少才合理

阈值定低了,告警频繁,狼来了效应会让团队麻木;阈值定高了,告警到达时往往已经回天乏术。根据我这几年管理几十台服务器的经验,磁盘使用率的阈值设置要分场景:

  • 普通业务数据盘:建议设置两级,85%为Warning,92%为Critical。低于85%的空间一般足够支撑写入缓冲,到85%开始排查即可。
  • 日志盘或频繁写盘的应用目录:建议下调到75%触发提醒,因为这类目录增长快,等到了85%再处理,可能几个小时内就彻底写满。
  • 根分区(/):这个要看环境,有些服务器根分区和系统盘共用,建议70%就提醒,因为系统日志、临时文件、包管理缓存都会在根分区积累。
  • 容量非常小的分区(比如独立挂载的/boot):这类分区容量小,百分比波动剧烈,建议用绝对值监控剩余空间,比如剩余空间低于500MB时告警。

还有一点值得注意:磁盘使用率不是唯一指标。inode使用率、磁盘读写延迟、IO队列长度,这三个指标往往能比“容量使用率”更早暴露问题。尤其是inode,很多人都忽略,等发现的时候文件已经创建不了了,这就是所谓的“磁盘没满但显示No space left on device”的经典场景。

2. 排查第一步:这些Linux排查指令帮你快速定位

告警收到之后,第一件事当然是登录服务器。我习惯登录后先快速执行一组基础排查指令,把整体状况摸一遍再动手清理,避免在信息不全的情况下误删文件。

2.1 快速巡检的指令组合

我最常用的开场四连:

df -hT df -i dmesg | grep -i error | tail -20 uptime

df -hT看的是容量和使用率,-T参数会多显示一列文件系统类型,方便分辨是xfs还是ext4,不同的文件系统在后续处理上略有差异。df -i是看inode使用率的,这个千万别省。dmesg看一眼内核日志里有没有IO错误或文件系统报错,如果是磁盘硬件坏了,你再怎么清理空间也没用。uptime则是看负载,配合判断这台机器是不是在跑重任务。

网上流传的“Linux系统排查指令大全”看着很全,但实际排查时用到的核心指令就那么十来个。除了上面的,还会有du、lsof、find、iostat、ss。关键是理解每个指令输出的含义,而不是背一长串命令列表。比如df显示的是文件系统的统计,是基于文件系统超级块计算的;du显示的是目录树的实际文件大小累加。这两者统计口径不同,结果对不上才是常态。

2.2 df和du结果对不上,三种常见原因

这次排查网点服务器时,我先执行了df -h,看到/data分区使用率91%,但用du -sh /data/*加起来一算,总共才占了不到60%的空间。很多新手到这里就懵了,以为是命令用错了,其实这是非常典型的三种情况之一:

  1. 文件被进程占用但已删除:某个进程还在写一个已经删掉的文件,文件占用的数据块没有被系统回收。lsof +L1可以列出这类文件,找到对应进程后重启进程或kill掉,空间才会真正释放。
  2. 有挂载点重叠:某个目录被后续挂载的磁盘覆盖了,du从根目录扫的时候,扫到的是旧的挂载点内容;df显示的则是新挂载的容量。
  3. 稀疏文件或大文件被文件系统预分配:比如有些应用会创建稀疏文件,在文件系统层面占用了大量逻辑块,但du默认计算的是实际分配的块数,这种情况下表现不明显,需要结合ls -ls查看。

网点服务器恰好是第一种情况。后面我会详细说怎么定位和解决,这里先提一个经验:越是“df显示满但du算不出来的”场景,越要优先怀疑deleted文件。

2.3 inode耗尽:容量没满但写不进数据

inode的概念其实不复杂,每个文件和目录都会占用一个inode,里面记录文件属性、权限和数据块指针。一个分区能创建的inode数量是格式化时固定的,跟分区大小和数据容量没有绝对对应关系。很多场景下,分区容量还剩几百GB,但只要inode用光了,任何创建新文件的操作都会直接报错。

判断方法就一条命令:

df -i

Inode使用率和容量使用率是并列显示的。如果你看到/data的IUse%是100%,而Use%才50%,那问题就清楚了:这台机器上堆积了大量小文件,比如缓存目录、消息队列的持久化文件、未轮转的日志碎片。

处理思路也简单:找到文件数量最多的目录,批量删除过期文件。定位指令用:

find /data -type f | wc -l find /data -xdev -type f -size -1k | wc -l

第一条统计总文件数,第二条专门统计小于1KB的超小文件数量。如果超小文件占了大头,优先清它们,效率最高。我自己遇到过一次Tomcat应用生成大量小的session临时文件,一晚上生成了几十万个,最后就是用find /data/temp -type f -mtime +7 -delete清理掉的。

3. 磁盘清理实操:定位大头、安全删除、释放空间

前面是把问题定位清楚,到了这一步就该真正动手清理了。这个环节最考验经验,因为删错了就是生产事故,删对了就是预防性维护。我这次网点服务器的处理过程可以拆成四步,每一步都有明确的意图。

3.1 先找大目录,别急着扫全盘

登录之后先看一眼根目录下哪个一级目录最占空间,从大到小逐层往下找。这个操作有一个省时的技巧,就是用du -sh /*配合sort -hr排序:

du -sh /* 2>/dev/null | sort -hr | head -20

加2>/dev/null是为了过滤掉没有权限的目录的报错信息,不影响输出结果。如果你以普通用户身份执行,可能看不到所有目录的真实大小,最好直接用root或拥有sudo权限的账号。

逐层往下定位的逻辑很简单,比如第一层发现/var最大,就继续du -sh /var/* | sort -hr | head,直到找到最具体的大目录为止。这个过程不是漫无目的地翻找,而是在“目录树逐层收敛”,普通人看到/var/log占了30GB,基本就能猜出是日志积累问题。

但这里有个前提:先确认告警的挂载点,别把整个服务器的目录全扫一遍。比如这次网点服务器告警的是/data分区,/和/data是独立挂载,根本没必要扫/usr或者/opt。直接针对/data做逐层收敛,效率至少高一倍。

3.2 日志和临时文件的常规清理套路

排查结果不出所料,这个网点的/data下有个logs目录,里面躺着几十个.log文件,单个文件动不动几个GB,累计占了将近40GB空间。这种场景在网点服务器上太常见了:业务系统打印的日志没有配置轮转,也没有清理策略,日积月累就把磁盘撑爆了。

看日志目录大小、按修改时间排序,一条命令就够:

du -sh /data/logs/* 2>/dev/null | sort -rh | head -10 ls -lht /data/logs/ | head -20

确认是历史日志之后,不要直接rm了事,更好的做法是给这个目录配置logrotate轮转策略。比如每天生成一个日志文件,保留7天,超过7天的自动压缩或删除。配置路径一般是/etc/logrotate.d/,写一个这样的配置片段:

/data/logs/*.log { daily rotate 7 compress missingok notifempty copytruncate }

copytruncate这个参数值得单独说明。有些应用打开日志文件后一直持有文件句柄,普通的rename轮转会导致应用继续往旧文件里写,而用copytruncate方式,先把当前日志内容拷贝走,再清空原文件,应用持有的句柄不受影响,基本可以平滑轮转。代价是日志拷走的一瞬间会多占用一点点空间,但对业务影响最小。

如果是纯粹被日志占满又来不及配置轮转的紧急情况,可以直接用truncate -s 0 /data/logs/xxx.log清空文件,而不是rm。用truncate清空文件不会释放inode,但会让文件大小变成0,进程还在继续写入,也不会报错。如果用rm删掉文件,进程还持有旧文件句柄,空间依然不释放,反而容易出现“删了跟没删一样”的错觉。

3.3 文件明明删了,空间却没释放

前面提到过deleted文件的经典场景,这次网点服务器排查到最后10GB空间出不来,就是栽在这个坑上。当我把能删的历史日志和临时文件都删干净之后,df -h显示的使用率只降了四五个百分点,跟du算出来的结果还是差着一截。

这时候就该查deleted文件了:

lsof +L1 2>/dev/null | grep deleted

+L1的意思是列出link count为0的文件,也就是已经被删除但还被进程占用的文件。输出的内容会包含进程名、PID、文件路径,不过注意,路径后面会带一个(deleted)标记。

看到这里,解决办法就清楚了:定位到对应PID,要么重启这个进程,要么用kill让进程退出,系统才会真正回收它占用的数据块。如果你不确定这个进程能不能重启,可以先看下它是什么服务,比如ps -fp PID,再决定操作方式。

这次网点上是一个Java程序的日志文件被删了,但进程还开着,用kill -HUP PID让它重新加载日志配置之后,df -h立刻掉到了72%。这是一个顺手但非常典型的过程,很多运维新手在这里卡壳,误以为删文件没用,实际上只是没找到那个“还在占用旧文件的进程”。

4. 告警降噪实战:如何让磁盘告警不吵也不漏

这次排查本身花了不到半小时,但真正让我花时间反思的是告警策略的优化。因为这个网点之前已经被“假告警”折腾过好几次,管理员对告警已经有点麻木了。频繁误报的结果就是,等到真正出问题的时候,没人认真看了。

4.1 告警泛滥的根源

告警信息大量重复、缺乏关联上下文,是运维群里最常见的问题。磁盘告警这次触发了,下次恢复又通知一次,十分钟后再次触发,业务侧的同学被无关通知刷屏,真正的关键告警反而被淹没。

具体到磁盘告警,我总结出三个常见来源:

  • 阈值过低导致日常波动频繁触发。比如业务盘85%阈值设得不够合理,正常缓冲就能超过。
  • 缺少持续判断和抖动抑制条件。比如单次采集点超过阈值就立刻发,但实际上下一秒又降下来了。
  • 恢复了也发一次“恢复通知”,但恢复通知没有分级策略,跟触发通知同样优先级,信息量等同于噪声。

4.2 分级、分组、抑制:三步让告警变精简

我后来把磁盘告警调整成了三段式策略:分级通知、延迟触发、恢复静默。

分级通知很好理解:普通数据盘85%只发企业微信/邮件,92%才打电话。不同级别有不同的通知渠道。延迟触发就是设置持续时长,比如前面说的至少持续300秒。恢复静默则是指,如果告警恢复后的24小时内同类告警再次触发,就不再重复通知,只在监控面板上保留事件记录。这样可以有效阻断抖动重复轰炸。

还有一点很少人注意到:告警内容要带上上下文。比如“/data磁盘使用率91%(主机IP 10.1.2.3,已持续15分钟,当前最大占用目录为/data/logs)”。很多监控平台支持在告警模板里引用指标标签和变量,这样收到告警的人不用登录服务器就能看到大致问题方向,处理效率翻倍。这个网点的问题处理完,我顺手把告警模板里的变量加上了,后续值班的人再收到告警,至少知道先看哪个目录。

告警降噪不是简单地把告警关掉,而是让每一条告警都值得被看到、都带有足够信息。否则,就是纯粹的“狼来了”。

5. 常见问题速查表与排查心得

把这次排查的经验整理成速查笔记,方便下次遇到类似问题直接对照。这里面的每一条都是真金白银踩出来的,不是从手册里抄来的。

5.1 磁盘不足告警排查指令速查表

排查目标使用指令关键输出解读
查看文件系统容量和使用率df -hT看Use%和挂载点,确认告警分区
查看inode使用率df -iIUse%接近100时,要考虑小文件过多
查看目录大小(逐层定位)du -sh /路径/* 2>/dev/null | sort -rh | head -20从大到小逐层找大头目录
查找被删除但被占用的文件lsof +L1 2>/dev/null | grep deleted找到PID,重启或kill进程释放空间
查看目录中文件数量find /路径 -type f | wc -l判断是否出现文件数爆炸
清理指定日期前的文件find /路径 -type f -mtime +7 -delete按修改时间批量清理
清空大日志文件truncate -s 0 /路径/文件.log保留进程句柄,不删除inode
查看磁盘IO和负载iostat -dx 1 3%util过高说明磁盘存在IO瓶颈

这张表覆盖了从发现到清理再到确认的完整闭环。实际处理时不需要把所有指令都跑一遍,但每一条都可能在某个环节是救命稻草。

5.2 从这次告警延伸出来的三点日常建议

第一,给所有磁盘告警加上自动清理预案。比如日志目录每天凌晨跑一次find -mtime +30 -delete,临时目录定期清空,业务方再有计划地做增量备份。日常把垃圾清掉了,告警自然也就少了。这次网点如果早配置logrotate,可能根本不会有这次告警。

第二,监控里增加“趋势预测”指标。磁盘使用率这类线性增长的指标,完全可以根据历史数据预测未来多少天会达到阈值。很多监控平台都内置了简单的线性回归预测,提前一周就给出“预计6天后磁盘使用率达到90%”的提示,这比等触发告警再处理强太多。

第三,告警恢复后要有复盘习惯。每次磁盘告警处理完,花十分钟想一下:为什么空间会涨这么快?是日志没有轮转,还是业务数据量突然增大,还是临时文件没人清理?把根因记下来,该加自动化的加自动化,该同步给开发侧的同步给开发侧。如果只是清理完就当没事发生,下一个告警只是时间问题。

这次网点磁盘告警的处理,技术上不算复杂,但整个链路走下来,从告警产生、阈值设置、快速定位、安全清理到告警降噪,每一步都有值得琢磨的细节。我个人的体会是,磁盘排查看似是个体力活,实际上考验的是对系统底层机制的熟悉程度和对监控体系的整体把握。下次再收到磁盘不足的告警,希望你能一条条指令从容定位,一眼看出数据链路背后的真相,而不是复制一长串不知所谓的命令,最后把所有目录删一遍然后祈祷空间自己回来。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询