
Linux服务器磁盘空间不足时,可能出现网站无法上传文件、数据库写入失败、Docker容器异常退出,甚至系统服务无法正常启动等问题。
遇到这种情况,不要直接删除 /var/log、Docker目录或数据库文件。正确的处理顺序应当是:
- 确认哪个分区已满;
- 判断是磁盘容量还是inode耗尽;
- 找出占用空间最大的目录;
- 确认文件用途;
- 采用对应方式清理;
- 验证空间是否释放;
- 设置日志轮换和磁盘监控。
本文主要适用于使用GNU工具的Ubuntu、Debian、CentOS、Rocky Linux和AlmaLinux等常见Linux发行版。部分命令需要使用root用户,普通用户可以在命令前添加 sudo。
操作生产服务器前,请先确认重要数据已有可用备份。不要在不了解目录用途的情况下直接执行删除命令。
一、确认哪个磁盘分区已满
首先执行:
df -h
df 用于查看文件系统的总容量、已用空间和剩余空间,-h 会将结果转换为GB、MB等易读单位。
示例输出:
Filesystem Size Used Avail Use% Mounted on
/dev/vda1 40G 38G 1.1G 98% /
tmpfs 1.9G 0 1.9G 0% /dev/shm
/dev/vdb1 100G 32G 68G 33% /data
重点查看以下两列:
Use%:磁盘使用率;Mounted on:文件系统的挂载位置。
上面的结果表示根分区 / 已使用98%,需要优先排查根分区。
在生产环境中,可以将80%作为预警阈值、90%作为紧急阈值,但具体数值应根据磁盘容量、业务类型和数据增长速度调整。不能只看使用率百分比,还要同时关注剩余容量。
二、检查inode是否耗尽
有时磁盘还有剩余容量,却依然无法创建文件。这种情况可能不是容量不足,而是inode已经耗尽。
执行:
df -i
示例输出:
Filesystem Inodes IUsed IFree IUse% Mounted on
/dev/vda1 2621440 2621200 240 100% /
如果 IUse% 接近100%,说明服务器中可能存在大量小文件。
常见来源包括:
- PHP Session文件;
- 网站缓存;
- 邮件队列;
- 临时文件;
- 程序生成的小日志;
- Docker存储层;
- WordPress缓存目录。
inode不足时,即使磁盘还有数GB空间,也可能无法创建新文件。此时应定位文件数量异常的目录,而不是只寻找大文件。
三、找出占用空间最大的一级目录
确认根分区已满后,执行:
du -xh --max-depth=1 / 2>/dev/null | sort -h
参数含义:
-x:只检查当前文件系统,避免扫描其他挂载盘;-h:以易读格式显示容量;--max-depth=1:只统计一级目录;2>/dev/null:隐藏无权限访问的提示;sort -h:按照容量排序。
示例输出:
120M /boot
950M /opt
2.4G /usr
8.6G /home
24G /var
38G /
可以看出,主要空间集中在 /var。继续向下排查:
du -xh --max-depth=1 /var 2>/dev/null | sort -h
如果 /var/lib 最大,再执行:
du -xh --max-depth=1 /var/lib 2>/dev/null | sort -h
按照这种方式逐层检查,直到找到具体目录。
常见的大目录包括:
| 目录 | 常见内容 |
|---|---|
/var/log | 系统及应用日志 |
/var/lib/docker | Docker镜像、容器和缓存 |
/var/lib/mysql | MySQL数据库文件 |
/var/cache | 软件包及程序缓存 |
/home | 用户文件和网站备份 |
/www | 宝塔面板网站及备份 |
/tmp | 临时文件 |
/var/tmp | 长期临时文件 |
四、查找服务器中的大文件
在采用GNU Findutils和Coreutils的常见Linux系统中,可以使用下面的命令查找当前分区中超过500MB的文件:
find / -xdev -type f -size +500M -printf '%s %p\n' 2>/dev/null \
| sort -n \
| numfmt --field=1 --to=iec
可能得到:
620M /var/log/nginx/access.log
1.4G /home/backup/site-backup.tar.gz
3.8G /var/log/mysql/slow.log
8.1G /swapfile
如果系统不支持 -printf 或 numfmt,可以使用兼容性更好的简化命令:
find / -xdev -type f -size +500M -ls 2>/dev/null
注意:/swapfile 是交换文件,不应因为容量较大就直接删除。数据库文件、Docker数据和正在写入的日志,也不能仅凭文件大小判断是否可以删除。
五、安全清理systemd日志
1. 查看日志占用
执行:
journalctl --disk-usage
2. 轮换并清理归档日志
如果日志占用过大,可以先轮换当前日志:
journalctl --rotate
然后只保留最近7天的归档日志:
journalctl --vacuum-time=7d
也可以将归档日志限制在500MB以内:
journalctl --vacuum-size=500M
--vacuum-time 和 --vacuum-size 主要清理已经归档的journal文件,并不等同于直接清空当前正在写入的活动日志。先执行 --rotate,可以让活动日志完成轮换,再清理归档文件。
清理后重新检查:
journalctl --disk-usage
df -h
六、检查普通日志文件
查看 /var/log 中占用较大的项目:
du -h /var/log/* 2>/dev/null | sort -h | tail -n 20
常见的大日志包括:
/var/log/syslog
/var/log/messages
/var/log/auth.log
/var/log/nginx/access.log
/var/log/nginx/error.log
/var/log/mysql/slow.log
不要直接执行:
rm -rf /var/log/*
这种操作可能删除服务正在使用的日志、子目录和权限结构。
如果某个日志异常增长,应先确认产生日志的服务,并检查日志轮换配置:
logrotate -d /etc/logrotate.conf
-d 用于调试配置,不会真正执行日志轮换。确认配置无误后,再根据服务器环境执行日志轮换或调整保留策略。
七、清理软件包缓存
Ubuntu和Debian
查看APT缓存:
du -sh /var/cache/apt
清理已经下载的软件包:
apt clean
删除不再需要的依赖前,先预览待删除列表:
apt autoremove --dry-run
确认列表中不包含当前内核、数据库、服务器面板或业务依赖后,再执行:
apt autoremove
CentOS、Rocky Linux和AlmaLinux
使用DNF的系统可以执行:
dnf clean all
较旧的系统可能使用:
yum clean all
软件包缓存通常可以重新下载,但仍应先确认服务器使用的包管理器,不要混用APT、DNF和YUM命令。
八、清理Docker占用
如果服务器运行Docker,/var/lib/docker 可能占用大量空间。
首先查看Docker磁盘使用情况:
docker system df
查看详细信息:
docker system df -v
继续查看容器、镜像和数据卷:
docker ps -a
docker images
docker volume ls
确认无用资源后,可以执行:
docker system prune
默认情况下,该命令会清理停止的容器、未使用的网络、悬空镜像和构建缓存,并在执行前要求确认。
不要在不了解影响的情况下直接运行:
docker system prune -a --volumes
其中:
-a会扩大镜像清理范围;--volumes会将符合条件的未使用卷纳入清理;- 卷中可能保存数据库或应用数据。
生产服务器应先完成备份,并逐项确认容器、镜像和数据卷用途,再决定是否清理。
不要通过直接删除 /var/lib/docker 解决空间问题,这可能导致容器、镜像和业务数据损坏。
九、文件删除后空间没有释放怎么办
有时已经删除了大日志,但 df -h 显示空间没有变化。这通常是因为某个进程仍然打开着已经删除的文件。
先确认系统是否安装了 lsof:
command -v lsof
如果没有安装,可以根据发行版执行:
# Ubuntu或Debian
apt install lsof
# Rocky Linux、AlmaLinux或CentOS
dnf install lsof
然后查找已经删除但仍被进程占用的文件:
lsof +L1
如果Nginx仍占用已经删除的日志,可以先检查配置,再要求Nginx重新打开日志:
nginx -t && nginx -s reopen
执行后再次检查:
lsof +L1
df -h
不同服务重新打开文件的方式不同。不要看到文件被占用就直接强制结束进程,数据库、存储和核心业务进程被强制终止可能造成服务中断或数据损坏。
十、检查网站和面板备份
服务器磁盘被占满的常见原因之一,是控制面板持续生成本地备份。
可以检查:
du -h --max-depth=2 /www/backup 2>/dev/null | sort -h
du -h --max-depth=2 /home 2>/dev/null | sort -h
常见备份文件格式包括:
.tar
.tar.gz
.zip
.sql
.sql.gz
不要默认删除所有旧备份。建议至少保留:
- 一个最近的完整备份;
- 一个经过验证、能够恢复的异地备份;
- 数据库和网站文件的独立备份。
确认备份已经上传到对象存储或其他服务器,并完成恢复验证后,再删除本地重复文件。
十一、磁盘空间达到100%时的处理顺序
第一步:定位异常分区
df -h
df -i
第二步:定位大目录
du -xh --max-depth=1 / 2>/dev/null | sort -h
第三步:优先处理低风险内容
优先检查:
- 软件包缓存;
- 已归档的systemd日志;
- 已确认无用的旧备份;
- Docker构建缓存;
- 明确不再使用的停止容器。
不要优先删除数据库、系统文件或用途不明的业务文件。
第四步:重新检查空间
df -h
df -i
第五步:检查服务状态
systemctl --failed
根据服务器环境检查关键服务:
systemctl status nginx
systemctl status mysql
systemctl status docker
实际服务名称可能是 mysqld、mariadb、php-fpm 或带版本号的PHP服务,需要根据系统配置调整。
十二、这些目录不要直接删除
以下目录通常涉及系统或业务数据:
/var/lib/mysql
/var/lib/postgresql
/var/lib/docker
/etc
/boot
/usr
下面这些操作也不应直接执行:
rm -rf /var/lib/mysql/*
rm -rf /var/lib/docker/*
rm -rf /var/log/*
rm -rf /tmp/*
特别是数据库目录和Docker目录,直接删除可能造成不可恢复的数据丢失。即使是临时目录,也可能存在程序正在使用的套接字、锁文件或临时数据,应先确认文件用途和使用状态。
十三、如何防止磁盘再次被占满
1. 设置日志轮换
检查系统日志轮换配置:
cat /etc/logrotate.conf
ls -l /etc/logrotate.d/
确认Nginx、MySQL和应用程序日志存在合理的轮换、压缩和保留策略。
2. 限制systemd日志容量
可以编辑 /etc/systemd/journald.conf:
SystemMaxUse=500M
SystemKeepFree=1G
其中:
SystemMaxUse用于控制持久化日志允许使用的最大空间;SystemKeepFree用于为其他程序预留磁盘空间。
修改前先备份配置:
cp /etc/systemd/journald.conf /etc/systemd/journald.conf.bak
修改后重启日志服务:
systemctl restart systemd-journald
重启日志服务可能造成短暂的日志记录切换,生产环境应选择合适的操作时间。
3. 设置磁盘告警
可以根据业务情况设置以下告警:
- 使用率超过80%:预警;
- 使用率超过90%:紧急告警;
- inode使用率超过80%:预警;
- 剩余空间低于指定容量:紧急告警。
阈值应同时考虑百分比和剩余容量。例如大容量数据盘即使使用率较高,也可能仍有充足空间;小容量系统盘则可能在较低使用率时就需要处理。
总结
Linux磁盘空间不足时,最重要的不是立即删除文件,而是先确定空间被谁占用。
完整排查流程可以概括为:
df检查分区
→ df -i检查inode
→ du定位目录
→ find定位大文件
→ 确认文件用途
→ 分类清理
→ 检查服务
→ 设置日志轮换和监控
日志、缓存、旧备份和Docker资源是常见的空间占用来源,但数据库目录、Docker数据目录和系统目录不能直接删除。
完成清理后,还应通过日志轮换、备份保留策略和磁盘告警解决空间持续增长的问题,避免服务器再次因为磁盘不足而中断服务。
参考资料
- GNU Coreutils:
df和du官方文档 - GNU Findutils:
find官方文档 - systemd:
journalctl和journald.conf官方手册 - Docker Docs:
docker system df和docker system prune官方文档 - Nginx:日志重新打开及信号控制官方文档




