发布时间:2026-09-11 05:00 更新时间:2026-09-11 05:00 阅读量:0
网站突然打不开、后台报数据库写入失败、SSH 登录后提示磁盘空间不足,这类故障十有八九是根分区被写满了。磁盘满不像 CPU 飙高那样能靠重启缓解,它会让 MySQL 拒绝写入、Nginx 无法记录日志、面板服务直接崩溃。处理思路其实很固定:先用 df 确认是哪个分区、再去 du 找出是谁占的空间,然后用日志切割把源头控制住,最后才动手清理。
df 看的是文件系统层面的余量,加上 -h 便于阅读,加 -i 则能看出 inode 是否耗尽。inode 满的表现很有意思:df -h 显示还有剩余空间,但系统就是提示“No space left on device”。
df -h
df -i确认了是哪个挂载点满了之后,用 du 从根目录往下逐层剥。加 -x 表示不跨越其他文件系统,避免把挂载的数据盘也算进来;-d 1 表示只统计一层目录,这样出结果快。
du -xhd1 / | sort -rh | head -20
du -xhd1 /var | sort -rh | head -20
du -xhd1 /var/log | sort -rh | head -20如果目录层级很深,比如某个上传目录塞了几十万张图片,可以再用 find 直接抓大文件。下面的 -printf 是 GNU find 的写法,BSD 系系统上参数不同,具体以实际环境为准。
find / -xdev -type f -size +200M -printf '%s\t%p\n' 2>/dev/null | sort -rn | head -20还有一种容易掉进去的坑:df 显示分区满了,du 逐层统计却怎么也对不上号。这通常是文件已经被删除,但某个进程仍持有文件句柄,空间没有真正释放。用 lsof 可以确认,处理方式是重启对应的服务让句柄释放,而不是继续删文件。
lsof +L1 | head -20绝大多数“磁盘慢慢变满”的站点,元凶都是日志。系统侧是 systemd-journald,应用侧是 Nginx、PHP、MySQL 的日志。
journald 可以先看当前占用,再按时间或体积做一次清理。这只是应急手段,真正管用的是在配置文件里设定上限,改完重启 systemd-journald 生效。
journalctl --disk-usage
journalctl --vacuum-time=7d
journalctl --vacuum-size=500M# /etc/systemd/journald.conf
SystemMaxUse=500M
SystemMaxFileSize=50MNginx 的访问日志如果一直往单个文件里追加,流量稍大的站点几个月就能堆到几十 GB。logrotate 是发行版自带的标准方案,在 /etc/logrotate.d/ 下新建一个 nginx 配置文件即可。下面这份配置按天切割、保留 14 份、压缩旧文件,并通过 USR1 信号让 Nginx 重新打开日志句柄,整个过程不会中断服务。
/var/log/nginx/*.log {
daily
missingok
rotate 14
compress
delaycompress
notifempty
create 0640 www-data adm
sharedscripts
postrotate
if [ -f /run/nginx.pid ]; then
kill -USR1 $(cat /run/nginx.pid)
fi
endscript
}这里的 www-data 是 Debian/Ubuntu 下的 Web 用户,CentOS 系一般是 nginx,日志与 pid 路径也各发行版略有差异,以实际环境为准。日志量特别大的站点,可以把 daily 换成 size 100M,或者用 maxsize 100M 配合 daily,避免单日之内就撑满磁盘。配置写好别直接上线,先用 -d 做一次演练,确认没有语法问题:
logrotate -d /etc/logrotate.d/nginx
logrotate -f /etc/logrotate.d/nginx宝塔面板等管理面板也提供日志切割与清理的开关,原理是一样的,开启后同样要检查保留份数和保留天数是否合理。
清理是风险最高的环节,删错一个目录可能直接导致数据丢失。几条原则值得记住。
正在被进程写入的日志,不要直接 rm。文件被删除后句柄仍在,空间不会立刻释放,运维会看到 df 毫无变化而一头雾水。正确做法是把文件内容清空,比如 truncate -s 0,或者用冒号重定向写入。其次是别碰数据目录,/var/lib/mysql、/var/lib/docker、/var/lib/redis 这些路径下放着真实业务数据,删除或移动都可能造成不可恢复的损失。使用通配符之前先 ls 看一眼匹配结果,确认无误再执行。
truncate -s 0 /var/log/nginx/access.log
apt-get clean
yum clean all可以安全清理的通常是:包管理器的缓存、/tmp 与 /var/tmp 下的陈旧临时文件、早期的手工备份压缩包、以及已确认无人使用的旧站点目录。清理完成后重新执行一次 df -h 和 df -i,确认空间确实回落。
把这次的排查过程变成长期机制,才算真正解决问题:给日志目录单独划一个分区,避免日志写满拖垮系统盘;配置磁盘使用率告警,在 80% 就收到通知;定期检查 logrotate 是否正常执行,某些环境下它依赖 cron 或 systemd timer,具体以发行版实际配置为准。做到这几点,磁盘写满就会从一个突发故障,变成一个提前很久就能处理的日常提醒。
| 📑 | 📅 |
|---|---|
| 宝塔面板安全加固:面板端口、安全入口、SSL与登录告警设置 | 2026-09-11 |
| Nginx 502/504 排查:从错误日志到PHP-FPM进程池状态 | 2026-09-10 |
| MySQL慢查询日志开启与参数分析:用mysqldumpslow定位拖慢网站的SQL | 2026-09-10 |
| 自建网站状态监控:Uptime Kuma部署与告警配置 | 2026-09-10 |
| 带宽跑满找元凶:iftop、nethogs与tcpdump排查详解 | 2026-09-10 |
| HTTPS证书有效却提示不安全:混合内容的定位与批量修复 | 2026-09-12 |
| phpMyAdmin导入大SQL超时:参数调整与命令行导入 | 2026-09-12 |
| 大文件上传总失败:php.ini与Nginx三处限制如何协调放行 | 2026-09-14 |
| Nginx反向代理缓存实战:proxy_cache_path配置与命中率排查 | 2026-09-15 |
| Let's Encrypt证书自动续期失败排查:certbot renew定时任务与webroot验证 | 2026-09-15 |