磁盘又满了?是时候来一次“大扫除”了
💡 推荐阅读:WordPress 后台卡成幻灯片?数据库一直膨胀?清理修订版本和瞬态数据才是根治之道
作为站长,最怕半夜被监控告警吵醒。尤其是那种“Disk Usage 100%”的红色警报,比手机没电还让人焦虑。登录服务器一看,df -h 显示根分区 / 使用率已经飙到 100%,网站打不开,服务写不进日志,连 SSH 都卡成狗。这时候千万别慌,也别盲目去 rm -rf 碰运气,搞不好把数据库删了,那才是真正的“事故现场”。
笔者运维过上百台服务器,今天就把这套经过千锤百炼的“磁盘救火”流程分享出来。这篇文章不讲虚的,全是实操命令和排坑经验,看完你也能在五分钟内锁定元凶,安全腾出空间。
核心疑问:为什么删了大文件,磁盘空间还是满的?
💡 延伸阅读:别再纠结2核2G还是2核4G了!实测数据告诉你性能差距,钱花得明明白白
这是新手最容易踩的坑。你用 du -sh * 查了半天,发现某个大文件删了,但 df -h 一看,使用率纹丝不动。别急着怀疑人生,这大概率是“文件被进程占用”了。在 Linux 中,只要有一个进程打开了这个文件,即使你把它 rm 掉了,它占用的磁盘块也不会立刻释放,直到进程停止或重启。
所以,我们的排查思路必须清晰:先定位大文件,再检查是否有进程占用,最后才动手清理。 顺序错了,容易做无用功。
疑问一:如何快速找出那个“吃满”磁盘的罪魁祸首?
很多人上来就用 du -sh /,结果扫描整个根目录要等十分钟,急性子根本受不了。我们要的是“精准制导”,而不是“地毯式轰炸”。
推荐使用以下“递进式”定位法,效率极高:
# 第一步:查看哪个一级目录占用最大(限定深度为1,秒出结果)
du -h --max-depth=1 / 2>/dev/null | sort -hr | head -10
# 第二步:进入占用最大的目录(比如 /var),继续深挖
du -h --max-depth=1 /var 2>/dev/null | sort -hr | head -10
# 第三步:一直重复,直到找到具体的大文件
ls -lhS /var/log/ | head -5 # 按大小排序查看文件
实战技巧: 如果 du 命令卡住不动,可能是因为某些特殊文件(如 /proc)导致的。记得加上 2>/dev/null 把错误信息丢弃,并把 /proc、/sys 等虚拟目录排除在外。另外,用 find 命令直接找大于 500M 的文件也是绝招:
find / -type f -size +500M -exec ls -lh {} \; 2>/dev/null | sort -k5 -hr | head -20
这条命令会瞬间列出所有大于 500MB 的“大家伙”,通常日志文件(如 messages、syslog)和 MySQL 的 binlog 是重灾区。
疑问二:明明删除了文件,磁盘空间却不释放,怎么办?
这就是我们开头提到的“坑”。你找到了文件并执行了 rm -rf,但 df -h 依然显示 100%。此时,必须祭出 lsof 大法:
# 查看所有已删除但被进程占用的文件
lsof | grep deleted
输出解读: 你会看到类似 nginx 12345 root 11u REG 253,0 1024000 789456 /var/log/nginx/access.log (deleted) 的记录。这说明 Nginx 进程还在往这个已经被删除的 inode 里写数据。
解决方案: 最稳妥的方法是重启对应的服务,让进程重新打开文件描述符。
# 如果是 Nginx
nginx -s reload # 或者 systemctl restart nginx
# 如果是系统日志服务
systemctl restart rsyslog
# 如果是个别 Java 应用,必须重启应用进程
重启后,再执行 df -h,你会发现空间瞬间“变”回来了。这里要提醒一下:千万别为了省事直接 kill -9 进程,除非那是你确认可以随时重启的服务。对于数据库(MySQL/PostgreSQL),直接 kill 会导致数据损坏,必须走正常维护流程。
疑问三:根分区 / 满了,但 /home 和 /data 还有空间,能直接挂载过去吗?
很多程序默认把日志和数据写在 /var 或根目录,如果业务数据盘挂在 /data,我们完全可以用软链接把大目录迁过去,这是正规的运维操作,比盲目扩容省钱多了。
操作步骤(以迁移 Docker 数据目录为例):
# 1. 停止服务
systemctl stop docker
# 2. 移动数据目录到数据盘
mv /var/lib/docker /data/docker
# 3. 创建软链接
ln -s /data/docker /var/lib/docker
# 4. 启动服务并验证
systemctl start docker
df -h
这里有个细节:迁移前一定要用 du -sh 记录原目录大小,确保目标磁盘剩余空间足够。另外,mv 命令在跨文件系统时是“复制+删除”,如果数据量上百 G,建议用 rsync 同步,避免中断导致数据丢失。
根因剖析:磁盘空间到底被谁“吃”了?
💡 深度技术指南:别再手动发内容了!DeepSeek API + AI提示词接入网站全自动创作的保姆级教程
根据笔者的经验,90% 的磁盘爆满都逃不出以下三种情况:
- 日志文件失控: Nginx、Apache、Tomcat 的 access_log 和 error_log,如果没有配置 logrotate 轮转,几个月就能涨到几十 GB。特别是开启了 debug 级别的应用日志,写入量惊人。
- 系统包缓存与孤儿文件:
/var/cache/yum(CentOS)或/var/cache/apt(Ubuntu)里积攒的更新包,以及/tmp目录下的临时文件。 - 数据库 binlog 堆积: MySQL 的二进制日志(binlog)默认保留很长时间,如果主从同步中断,binlog 会一直累积不清理。
针对以上情况,给出对应的“药方”:
# 清理 yum 缓存
yum clean all
# 清理 apt 缓存
apt-get autoclean
# 手动清理 journal 日志(保留最近 3 天)
journalctl --vacuum-time=3d
# 查看 MySQL binlog 保留策略(需登录 MySQL)
SHOW BINARY LOGS;
# 手动清理到指定编号(谨慎操作,先备份)
PURGE BINARY LOGS BEFORE NOW();
安全清理的“黄金准则”与预防建议
清理磁盘不是“一锤子买卖”,我们要建立长效机制。笔者建议你做好以下三件事,从此告别“磁盘告警”焦虑:
- 配置 logrotate 轮转: 确保所有应用日志都纳入 logrotate 管理。配置示例:
/etc/logrotate.d/nginx中设置daily(按天轮转)、rotate 30(保留 30 份)、compress(压缩旧日志)。 - 定时任务巡检: 写一个简单的 Shell 脚本,每天凌晨检查磁盘使用率,超过 80% 就自动清理
/tmp和过期日志,并发送告警到钉钉或微信。 - 监控与扩容预案: 使用 Zabbix 或 Prometheus 监控磁盘 inode 和空间。同时,对于业务增长较快的站点,建议选择支持在线扩容的云盘服务。这里多说一句,在购买服务器时,建议选择正规云厂商的 SSD 数据盘,不仅 IO 性能好,而且快照备份功能能让你在误删数据时“后悔药”可吃,千万别为了省几块钱买那种没有售后保障的小机房机器,关键时刻掉链子真的会崩溃。
写在最后
磁盘满并不可怕,可怕的是没有章法的乱删。记住今天的核心三步:du 定位大文件 → lsof 排查占用 → 针对性清理或迁移。只要按这个思路来,五分钟内解决战斗不是问题。希望这篇实战笔记能帮你省下一些半夜加班的宝贵时间。如果你有其他独门秘籍,欢迎在评论区交流讨论,咱们下期见!
相关技术专题与延伸阅读
- WordPress 后台卡成幻灯片?数据库一直膨胀?清理修订版本和瞬态数据才是根治之道
- 别再纠结2核2G还是2核4G了!实测数据告诉你性能差距,钱花得明明白白
- 别再手动发内容了!DeepSeek API + AI提示词接入网站全自动创作的保姆级教程
- Nginx 反向代理总报 502?HTTPS 证书续签又失败?这份排坑实战笔记请收好
📦 【资源免费领】本文全套实操配置文件与避坑手册下载
本文涉及的全套 Docker Compose 配置文件、服务器运维避坑清单及 AI 提效指令库已完整打包,可免费极速转存:
💡 提示:推荐使用手机【夸克网盘 App】打开保存,新用户首月免费赠送 1TB 超大空间与免流量极速下载特权。