0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

Linux服务器磁盘空间告警的最佳应对策略

马哥Linux运维 来源:马哥Linux运维 2026-05-08 14:29 次阅读
加入交流群
微信小助手二维码

扫码添加小助手

加入工程师交流群

问题背景

磁盘空间告警是 Linux 服务器最常见的报警之一。很多人的第一反应是登录服务器直接rm -rf找大文件删掉。但实际场景中,"磁盘满"往往有三种不同情况:

磁盘空间真的满了(df -h 显示 100%)

inode 耗尽了(df -h 显示还有空间,但系统报 No space left on device)

文件已删除但空间未释放(df 显示满,但 du 统计不到大文件)

不分清楚这三种情况就盲目删文件,可能删了半小时空间也没释放,或者删了不该删的文件导致业务异常。

本文按排查顺序逐一讲解 8 个关键命令,覆盖空间排查、inode 排查、已删文件句柄排查、IO 性能排查,最后给出生产环境清理的标准流程。

一、排查前的准备工作

在开始删除任何文件前,先做两件事:

# 记录当前磁盘状态,以便事后回溯
$ df -h > /tmp/disk_before_$(date +%s).txt
$ df -i >> /tmp/disk_before_$(date +%s).txt

# 确认挂载点对应的业务
$ mount | grep <挂载点>
$ ls -la <挂载点> | head

如果有多块数据盘(如 /data、/var/log 独立分区),先确认哪个分区满了,再针对性排查。

二、8 个命令逐一详解

命令 1:df -h —— 查看各挂载点使用率

$ df -h
Filesystem   Size Used Avail Use% Mounted on
/dev/vda1    40G  38G  16M 100% /
/dev/vdb1    200G 120G  80G  60% /data

关键检查点:

**Use% = 100%**:该分区空间已满,需要立即处理

**Use% = 90~99%**:预警范围,需要排查哪些目录在持续增长

关注 Avail 列而非 Used 列:Avail 是实际可用空间(非 root 用户可用),Used 可能包含预留块(默认 5%)

预留块含义:mkfs.ext4默认保留 5% 给 root 用户,所以非 root 用户看到 Avail 会比预期少。数据盘可以用tune2fs -m 1 /dev/vdb1调低到 1%。

命令 2:df -i —— 检查 inode 是否耗尽

$ df -i
Filesystem   Inodes IUsed  IFree IUse% Mounted on
/dev/vda1   256000 255900   100 100% /

典型陷阱:df -h显示还有空间,但系统报No space left on device,此时df -i很可能显示 IUsed = 100%。

inode 耗尽的原因是小文件太多——每个文件(不管大小 1 字节还是 1GB)都需要一个 inode。一个 40GB 的分区如果满了 255 万个小文件,inode 就会耗尽,实际空间可能只用了 10%。

快速定位小文件目录:

# 统计各目录的文件数量(递归深度 1)
$fordirin/*/;doecho-n"$dir: "; find"$dir"-xdev -typef 2>/dev/null | wc -l;done
# -xdev 限制在同一文件系统,避免统计到挂载点内

# 更精确的方式——逐级排查
$ find / -xdev -typef | awk -F/'{$NF=""; print $0}'| sort | uniq -c | sort -rn | head -10

命令 3:du -sh —— 逐层定位大目录

# 查看根目录下各一级目录的大小
$ du -h --max-depth=1 / | sort -rh | head -10
6.2G  /usr
4.1G  /var
2.8G  /opt
1.5G  /home
1.2G  /root
...

# 发现 /var 大后,再深入
$ du -h --max-depth=1 /var/ | sort -rh | head -10
3.5G  /var/log
500M  /var/lib
...

# 直到定位到具体目录
$ du -sh /var/log/nginx/
1.2G  /var/log/nginx/

du递归统计所有子目录,大目录下逐层深入很快就能找到"罪魁祸首"。

常用变体:

# 只看当前目录下各子目录大小,不递归更深
$ du -sh */ .[!.]*/

# 用 time 限制范围(只看修改时间早于 N 天的文件)
# 统计 30 天前的日志总量
$ find /var/log-name"*.log"-mtime +30 -typef -execdu -ch {} + | tail -1

命令 4:lsof | grep deleted —— 查找已删除但未释放的文件

这是最容易被忽略但实际非常常见的场景。当一个文件被rm删除后,如果有进程仍然持有这个文件的句柄,磁盘空间不会立即释放。

# 检查所有已删除但仍有进程引用的文件
$ sudo lsof | grep deleted
COMMAND  PID  USER  FD  TYPE DEVICE SIZE/OFF  NODE NAME
java   3456  root  23w  REG 202,1 2147483648 12345 /var/log/app/access.log (deleted)
nginx   2321  www  5w  REG 202,1 1073741824 23456 /var/log/nginx/access.log (deleted)

关键信息解读:

SIZE/OFF列:文件的实际大小(单位字节),这里是 2GB 和 1GB

NAME列末尾的(deleted)标记说明文件已被删除但句柄未释放

FD(File Descriptor)列:23w表示第 23 号文件描述符,打开方式为写入

解决方法(按推荐顺序):

安全方式——通知进程重载文件句柄(大多数日志框架支持):

$kill-USR1   # Java / log4j / syslog-ng
$ nginx -s reopen   # Nginx
$ systemctl restart rsyslog

强制方式——如果进程不响应 USR1 信号或不是日志类文件:

# 确认进程是否可以重启
$ systemctl restart 

# 或直接 kill 进程(确认不影响业务后)
$kill-9 

临时释放——清空文件内容而非删除文件,不依赖信号:

$ : > /proc//fd/

这不会关闭进程的文件描述符,而是将文件内容截断为 0,立即释放磁盘空间。适用于不能重启进程的生产环境。

为什么会出现这种情况:

最常见的场景是 logrotate。很多默认的 logrotate 配置使用create指令,流程是:mv access.log access.log.1->create access.log(新建空文件)。新文件有了新 inode,但旧文件的句柄仍然被进程持有,旧文件的磁盘空间一直占用直到进程重启。

正确的做法是 logrotate 配置copytruncate:

/var/log/nginx/*.log{
  daily
  rotate 30
  copytruncate  # 复制内容后截断原文件,不改变 inode
  compress
  delaycompress
  missingok
  notifempty
}

命令 5:find 查找大文件

# 查找根目录下大于 100MB 的文件
$ find / -xdev -typef -size +100M -execls -lh {} ; 2>/dev/null | sort -k5 -rh | head -20

# 查找特定目录下大于 1GB 的文件
$ find /var/log-typef -size +1G -execls -lh {} ; 2>/dev/null

# 查找最近 7 天内没有修改过的大文件(适合清理历史归档)
$ find /data/archive -typef -size +500M -mtime +7 -execls -lh {} ; 2>/dev/null

参数解释:

-xdev:限制在同一文件系统内,不搜索挂载的其他分区

-size +100M:大于 100MB 的文件(单位:k/M/G)

-exec ls -lh {} ;:对每个结果执行 ls

sort -k5 -rh:按第 5 列(文件大小)反向排序

2>/dev/null:过滤权限不足的错误信息

命令 6:ncdu —— 交互式磁盘分析

ncdu(NCurses Disk Usage)是du的交互式替代品,对逐层排查大目录效率更高:

# 安装
$ apt install ncdu   # Debian/Ubuntu
$ yum install ncdu   # CentOS/RHEL

# 使用
$ ncdu /

操作方式:

方向键上下移动

Enter 进入目录

d删除选中的文件/目录

q退出

ncdu 扫描速度比du快(尤其在大目录下),而且可以实时看到各目录大小排序,不需要反复敲命令。

命令 7:iostat -xz —— 分析磁盘 IO 性能

当磁盘使用率没有 100% 但业务响应仍然很慢时,可能是 IO 性能达到上限而非空间不足:

$ iostat -xz 1 5
Linux 5.15.0-91-generic ... 08/15/2025 _x86_64_ (32 CPU)

Device  r/s   w/s  rkB/s  wkB/s rrqm/s wrqm/s %rrqm %wrqm r_await w_await aqu-sz %util
vda  3200.0 4500.0 128000.0 360000.0  0.0   0.0  0.00  0.00  15.20 92.30 256.0 99.8

关键指标:

指标 含义 HDD 警戒线 SSD 警戒线
%util 磁盘忙碌百分比 > 80% 对 SSD 参考价值有限
r_await / w_await 读写平均延迟 > 20ms > 2ms
aqu-sz 平均队列长度 > 1 > N(并行度)
r/s + w/s IOPS 机械盘 ~200 取决于 SSD 型号

对 NVMe SSD 的说明:%util对多队列设备(NVMe)不准确,可能显示 100% 但仍能处理更多 IO。更可靠的指标是aqu-sz(平均队列长度)和r_await / w_await(IO 延迟)。

命令 8:journalctl --disk-usage —— 检查 systemd 日志占用

systemd-journald 的日志在不加限制的情况下可能占用数 GB 磁盘空间:

# 查看 journal 日志占用的磁盘空间
$ journalctl --disk-usage
Archived and active journals use 3.8G.

# 清理 7 天前的日志
$ journalctl --vacuum-time=7d

# 限制 journal 最大体积为 500MB
$ journalctl --vacuum-size=500M

# 永久限制(编辑配置文件)
$ cat /etc/systemd/journald.conf
[Journal]
SystemMaxUse=500M
MaxFileSec=7day

修改配置后重启 systemd-journald:

$ systemctl restart systemd-journald

三、按场景组合使用 8 个命令

场景 A:空间占比高,du 能正常定位

执行顺序:df -h→du逐级定位 →find查找大文件 →ncdu交互式确认

$ df -h          # 定位满的分区
$ du -h --max-depth=1 /  # 逐级深入
$ find /path -typef -size +500M -execls -lh {} ;
$ ncdu /path        # 交互式确认

场景 B:df 显示满,但 du 统计不到大文件

执行顺序:df -h→sudo lsof | grep deleted→ 确认后释放

$ sudo lsof | grep deleted | head -5
# 找到最大的(deleted)文件
$ sudo lsof | grep deleted | awk'{print $7, $NF, $2}'| sort -rn | head -10
# 对 PID 发送信号或重启服务

场景 C:No space left on device 但 df -h 有空间

执行顺序:df -i→find统计文件数 → 清理小文件

$ df -i           # 确认 inode 满
$ find /data -xdev -typef | wc -l       # 统计文件总数
$ find /data -xdev -typef -mtime +90 -delete # 清理 90 天前的旧文件

场景 D:磁盘性能差但空间充足

执行顺序:iostat -xz→iotop -o→pidstat -d

$ iostat -xz 1 5      # 确认 %util 高、await 高
$ iotop -o         # 定位 IO 密集进程
$ pidstat -d 1 5      # 按进程统计 IO

四、生产环境标准清理流程

不要在发现磁盘满时直接上手删文件,遵循以下流程:

记录现场 → 定位大目录 → 确认业务影响 → 备份 → 清理 → 验证

Step 1:记录现场

$ df -h > /tmp/disk_clean_$(date +%s).before
$ du -h --max-depth=1 /var/log| sort -rh > /tmp/disk_clean_$(date +%s).logdir

Step 2:定位并确认

# 找到大文件后确认其业务归属
$ ls -la /var/log/nginx/access.log.20250815.gz
# 与业务方确认是否可以清理

Step 3:备份后再清理

对于不确定的日志/数据文件,压缩备份到其他分区或存储后再清理:

# 备份到其他分区
$ gzip -c /var/log/nginx/access.log.20250815.gz > /backup/nginx/access.log.20250815.gz

# 确认备份成功后删除
$ rm /var/log/nginx/access.log.20250815.gz

Step 4:验证空间是否释放

$ df -h <挂载点>
$ df -i <挂载点> # 如果之前 inode 也高的话

Step 5:配置长期策略

根据排查结果配置日志轮转或周期性清理:

# logrotate 示例:按大小轮转
/var/log/nginx/*.log{
  size 500M
  rotate 14
  copytruncate
  compress
  missingok
  notifempty
}

# crontab 定期清理任务
0 3 * * 0 find /data/tmp -typef -mtime +30 -delete

五、预防措施

日志轮转必须配置——没有 logrotate 的服务器迟早会磁盘满。检查是否存在未被 logrotate 覆盖的日志文件。

监控与告警:不要等到 100% 再告警,分三级告警:

Warning: 使用率 > 80%

Critical: 使用率 > 90%

Emergency: 使用率 > 95%

独立分区:将 /var/log、/data 等容易写满的目录独立分区,避免写满根分区导致系统无法正常启动。

定期巡检:每周自动扫描各分区使用率和大文件增长趋势。

六、注意事项

不要在根分区满时重启服务器——根分区没有剩余空间可能导致重启后部分服务无法正常启动。

%util 100% 不等于磁盘损坏——可能是正常的高负载,先确认 aqu-sz 和 await 是否异常。

df 和 du 的统计差异:正常情况下差异在 5% 以内。如果差异显著,优先检查lsof | grep deleted。

挂载点覆盖:如果在非空目录上挂载新分区,原目录下的文件会被隐藏但仍占用空间。排查时注意mount输出。

**生产环境慎用rm -rf**——可能误删正在写入的日志文件,导致句柄未释放反而无法释放空间。建议优先用echo "" > file或truncate -s 0 file。

七、总结

磁盘满排查的核心路径:

先看 df -h确认空间耗尽的分区和挂载点

再看 df -i排除 inode 耗尽的情况

df 满但 du 找不到→ 执行lsof | grep deleted

逐层 du定位最大目录

find 和 ncdu查找具体大文件

检查 journalctl系统日志占用

配合 iostat排除 IO 性能问题

磁盘满的最佳应对策略不是"发现满了再删",而是通过 logrotate、分区规划、监控预警建立一个防止磁盘写满的体系。磁盘满了之后的每一次删除,都应该有记录、有备份、有确认、有总结。

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • Linux
    +关注

    关注

    88

    文章

    11829

    浏览量

    219630
  • 服务器
    +关注

    关注

    14

    文章

    10386

    浏览量

    91785
  • 磁盘
    +关注

    关注

    1

    文章

    402

    浏览量

    26598

原文标题:Linux 磁盘满了别急删文件:这 8 个排查命令先跑一遍

文章出处:【微信号:magedu-Linux,微信公众号:马哥Linux运维】欢迎添加关注!文章转载请注明出处。

收藏 人收藏
加入交流群
微信小助手二维码

扫码添加小助手

加入工程师交流群

    评论

    相关推荐
    热点推荐

    Linux磁盘空间异常爆满,该怎么查?

    服务器运维过程中,我们时常会遇到这样的情况,收到服务器磁盘空间告警
    发表于 11-29 09:00 1261次阅读

    Linux下增加磁盘空间的步骤

    在给Linux分区时,总是有那么一点吝啬,给的空间较小。在使用过程中,装上Matlab等大型软件后,才蓦然发现磁盘已没有空间,不过亡羊补牢为时不晚。Warning:对硬盘分区很危险,要
    发表于 07-11 08:42

    Linux下可以用df命令查看磁盘空间

    Linux下 df 命令查看磁盘空间
    发表于 07-12 11:07

    Linux的剩余磁盘空间利用技巧

    Linux利用剩余的磁盘空间
    发表于 07-30 14:28

    Linux中的可用磁盘空间如何检查?

    跟踪磁盘利用率信息是系统管理员(和其他人)的日常待办事项列表之一。Linux 有一些内置的使用程序来帮助提供这些信息。df 命令意思是 “disk-free”,显示 Linux 系统上可用和已使用的
    的头像 发表于 07-25 18:53 4108次阅读
    <b class='flag-5'>Linux</b>中的可用<b class='flag-5'>磁盘空间</b>如何检查?

    简单又快速看懂linux磁盘划分

    一个服务器是以虚拟机的形式提供的,通过df -h看服务器磁盘空间只有30多个G,但通过fdisk -l看发现有一个160G的磁盘空间 没有挂载,因此需要在不重启的前提下将160G的
    的头像 发表于 04-28 15:53 4252次阅读
    简单又快速看懂<b class='flag-5'>linux</b>的<b class='flag-5'>磁盘</b>划分

    详解Linux服务器的用户活动和命令

    如果您在管理Linux服务器,最好准备好使用用于检查用户活动的多个命令——用户何时登录及登录频率、属于哪些用户组、耗用多少磁盘空间、运行什么命令、占用多少磁盘空间、是否在阅读邮件等。
    的头像 发表于 07-03 15:30 6698次阅读

    Steam 客户端 Beta 版更新:针对分配磁盘空间性能优化

    今天,V 社发布了 Steam 客户端 Beta 版更新公告,此次更新主要针对分配磁盘空间的性能进行优化。 据悉,此次更新包括: 优化了安装或更新时预分配磁盘空间的性能。 改进了 Steam 覆盖
    的头像 发表于 11-06 16:43 2619次阅读

    通过df命令显示磁盘空间使用情况

    这 df 命令显示文件系统上的设备名称、总块数、总磁盘空间、已用磁盘空间、可用磁盘空间和挂载点信息。
    的头像 发表于 05-16 11:30 2265次阅读

    服务器运维过程收到磁盘空间告警怎么办

    服务器运维过程中,我们时常会遇到这样的情况,收到服务器磁盘空间告警
    的头像 发表于 11-03 10:30 2713次阅读

    linux磁盘空间满了怎么清理

    告警信息一致,接着我们就是要找到导致磁盘空间满的目录或文件 如何找到占用空间大的目录或文件? 一种比较笨的方法是,在根目录下,通过du -hs命令,列出各目录所占空间大小。
    的头像 发表于 11-09 11:46 2197次阅读
    <b class='flag-5'>linux</b><b class='flag-5'>磁盘空间</b>满了怎么清理

    Linux磁盘管理指令合集:从查看、分区到修复

    Linux 服务器运维或日常使用中,磁盘管理是高频操作 —— 无论是排查磁盘空间不足的问题,还是新增硬盘后的分区配置,都离不开一系列核心指令。今天就为大家整理一份「
    的头像 发表于 02-03 16:07 3625次阅读
    <b class='flag-5'>Linux</b><b class='flag-5'>磁盘</b>管理指令合集:从查看、分区到修复

    Linux磁盘空间告警的常见原因和诊断方法

    磁盘空间告警是运维工作中最常见的告警类型之一。当磁盘空间耗尽时,应用程序无法写入日志、数据库无法正常提交、容器无法创建新镜像,甚至系统日志写入失败会导致难以诊断的连锁故障。本文从实际运
    的头像 发表于 04-08 14:25 167次阅读

    MySQL磁盘空间问题的成因和排查方法

    运维工程师经常会遇到这样的场景:MySQL 服务器磁盘空间告警,但查看数据目录时发现数据库本身并不大。大量磁盘空间被未知文件消耗。通过排查发现,二进制日志(Binary Log)是主
    的头像 发表于 04-13 13:57 165次阅读

    Linux服务器磁盘管理机制和清理策略

    磁盘空间耗尽是服务器运维中最常见的问题之一。当磁盘写满后,应用无法写入日志、无法创建新文件、无法写入数据、数据库无法完成刷盘、SSH 可能无法建立新连接。表现为:写入文件报 "
    的头像 发表于 04-16 15:18 186次阅读