凌晨三点,监控告警声划破夜空:“/ 分区使用率 100%!”你登录服务器,df -h 一看,根分区红得发紫。更可怕的是,当你删掉几个日志文件后,df -h 显示空间一点都没释放!系统开始报错 No space left on device,新服务起不来,数据库连不上,业务直接瘫痪。

别慌。磁盘空间不足就像衣柜塞满了衣服——不是没地方了,是该扔的没扔,该叠好的乱堆着。本文将带你从快速诊断到深度清理,再到预防措施,系统性地解决Linux磁盘空间问题。

一、快速诊断:先搞清楚“谁吃了我的空间”

在动手清理之前,你需要像医生问诊一样,先诊断病因。

1.1 查看磁盘整体使用情况

df 命令是诊断的起点:

df -h

输出示例:

[root@ansible-controller ~]# df -h
Filesystem           Size  Used Avail Use% Mounted on
devtmpfs             4.0M     0  4.0M   0% /dev
tmpfs                1.8G     0  1.8G   0% /dev/shm
tmpfs                724M  9.1M  715M   2% /run
/dev/mapper/rl-root   17G   17G  453M  98% /
/dev/nvme0n1p1       960M  223M  738M  24% /boot
tmpfs                362M     0  362M   0% /run/user/0

Use% 接近100%,说明磁盘空间确实不足。但这里有个坑:有时候 Avail 显示还有空间,系统却报 No space left,那很可能是 inode 耗尽了。

1.2 检查 inode 使用情况

磁盘空间有两个维度:一个是存储空间(blocks),另一个是 inode 数量。每个文件都会占用一个 inode,如果磁盘上存在大量小文件,即使存储空间还有剩余,inode 也可能被耗尽,导致无法创建新文件。

df -i

输出示例:

Filesystem     Inodes IUsed IFree IUse% Mounted on
/dev/sda1     3276800 3276800     0  100% /

如果 IUse% 达到100%,说明 inode 资源已耗尽。此时删除大文件毫无意义,正确的动作是找到那些巨量小文件所在的目录进行清理。

1.3 定位大文件/大目录

df 是卫星云图,告诉你暴风雨在哪个区域聚集;du 是地面侦察,告诉你具体哪栋楼的哪个房间漏水了。

方法一:逐层排查(通用)

# 查看根目录下各子目录的大小,从大到小排序
du -sh /* 2>/dev/null | sort -rh | head -20

找到最大的目录后,进入该目录继续执行相同命令,逐层下钻。

方法二:黄金组合命令(推荐)

# 切换到问题挂载点
cd /
# 只统计当前目录下一级子目录,按大小排序取前10
du -h --max-depth=1 | sort -hr | head -n 10

方法三:查找大文件

# 查找全盘大于100MB的文件
find / -type f -size +100M -exec ls -lh {} \; 2>/dev/null

二、深度清理:对症下药

2.1 场景一:日志文件占满磁盘(最常见)

日志文件是磁盘空间的头号杀手

找到占用空间大的日志文件后,不要急着 rm。更稳妥的做法是清空文件内容,特别是对于没有做日志轮转一致持续写入的打日志文件:

# 将空内容重定向到日志文件中,无需重启服务
echo "" > var/log/nginx/access.log

如果确定要删除,请确保该文件没有被任何进程正在写入。如果日志文件一直持续写入,rm删除文件会导致句柄不会释放,一直占着存储空间。

2.2 场景二:inode 耗尽(小文件过多)

找到小文件最多的目录

# 查看指定目录下各子目录占用的 inode 数量
sudo du -sh --inodes /var/* | sort -rh | head -10

常见重灾区

  • /var/spool/mail —— 邮件队列堆积大量小文件
  • /tmp —— 临时文件碎片
  • /var/lib/docker/overlay2 —— Docker 容器层碎片文件

找到后,清理无用的缓存或临时文件即可释放 inode。

2.3 场景三:文件已删除但空间未释放(最隐蔽的坑)

这是很多新手的噩梦:明明用 rm 删除了 20G 的日志文件,df -h 一看,磁盘占用率还是 95%!,详见如下演示:
在这里插入图片描述
在这里插入图片描述
根本原因:该文件正在被某个进程打开。rm 命令只是移除了文件名到 inode 的链接,但只要文件描述符(fd)没有被关闭,内核就不会真正回收该文件占用的数据块。

排查方法

# 列出所有被删除但还被进程占用的文件,按大小排序
sudo lsof +L1 | grep deleted | awk '{print $7, $9}' | sort -rh

+L1 是关键参数,表示只列出链接数小于1(即已被删除)的文件。重点关注那些 GB 级别的文件。
在这里插入图片描述
如上图/var/log/nginx/access.log已经被删除,但是句柄没有释放,一直占着磁盘空间超15G。
解决方案

# 1. 从 lsof 输出中找到进程 PID(第一列)
sudo lsof +L1 | grep 'deleted'
# 输出示例:nginx     21446  root    5w   REG  253,0 15730335665     0 34462744 /var/log/nginx/access.log (deleted)
# 这里的 PID 是 21446
# 2. 重启或停止对应的服务进程
sudo kill -9 21446

在这里插入图片描述
进程终止后,内核会自动释放被占用的文件描述符,磁盘空间就会回来。
在这里插入图片描述

注意kill -9 是强制终止,**在生产环境操作前请评估业务影响**

2.4 场景四:其他可清理的空间

包管理器缓存

# Ubuntu/Debian
sudo apt-get clean          # 清理 /var/cache/apt/archives
sudo apt-get autoremove     # 删除不再需要的依赖包

# CentOS/RHEL
sudo yum clean all

Docker 清理

# 清理未使用的 Docker 资源
docker system prune -f
docker system prune -a -f   # 更激进,清理所有未使用的镜像

三、预防措施:别让问题再复发

3.1 配置 logrotate 自动轮转

logrotate 是 Linux 系统自带的日志轮转工具,能自动压缩、删除旧日志。

查看配置:

cat /etc/logrotate.conf          # 主配置文件
ls /etc/logrotate.d/             # 各服务的日志配置

以 Nginx 为例,配置 /etc/logrotate.d/nginx

/var/log/nginx/*.log {
    daily
    missingok
    rotate 7
    compress
    delaycompress
    notifempty
    create 644 nginx nginx
    postrotate
        [ -f /var/run/nginx.pid ] && kill -USR1 `cat /var/run/nginx.pid`
    endscript
}

3.2 建立监控告警

建议在磁盘使用率达到 80% 时就发出预警,而不是等到 100% 才被动响应。可以使用 Prometheus + Grafana 或云厂商自带的监控服务。

3.3 编写清理脚本自动化

可以将日常清理工作写成脚本,定期执行。例如每周日凌晨执行一次日志清理和缓存清理。

3.4 终极方案:扩容

如果清理后空间仍然不足,或者业务数据持续增长无法删除,那就需要考虑扩容云盘。在云环境下,这通常是最快的解决方案。

3.5 什么数据可以清理

一般来说/var/log/目录下*.log之类的日志是可以清理的,这些日志一般是纯文本形式;或者对应应用目录下的log或者logs目录下的存文本日志可以清理,但这只是一般情况,清理日志一定要特别谨慎,不能确认是否可以清理不要盲目的动数据,以免影响业务运行。

四、总结

遇到 Linux 磁盘 100% 的问题,记住这个流程:

  1. 先诊断df -h 看空间,df -i 看 inode
  2. 再定位du 逐层排查,find 找大文件
  3. 查幽灵lsof +L1 | grep deleted 找已删未释放的文件
  4. 安全清理:日志用 echo "" > 清空
  5. 固化配置:配置 logrotate ,防止复发
  6. 终极方案:空间实在不够就扩容

核心原则就一条:不盲删,先诊断;找对因,再下手。希望这篇文章能帮你在下一次磁盘告警时,从一个手忙脚乱的“删库跑路”预备役,变成一个冷静专业的 SRE。


如果你有更好的清理技巧,欢迎在评论区分享交流!

Logo

openEuler 是由开放原子开源基金会孵化的全场景开源操作系统项目,面向数字基础设施四大核心场景(服务器、云计算、边缘计算、嵌入式),全面支持 ARM、x86、RISC-V、loongArch、PowerPC、SW-64 等多样性计算架构

更多推荐