做服务器运维的,谁还没被磁盘打满吓过几回。我印象最深的是一次周五晚上,项目群里突然有人喊游戏登录不上,后台一查,磁盘直接100%,数据库写不进去,登录接口全线超时。排查了半天,罪魁祸首就是 /var/log 下面几个月没管的日志,光一个 access.log 就占了快 200G。从那次之后,我把日志清理这件事正经提上了日程,写了套删除脚本一直跑到现在,再没因为日志把磁盘塞满过。这篇就把我当时的完整思路、脚本解析和踩过的坑整理出来,给和我一样刚接触 Linux 运维、还处在“练气期”的朋友做个参考。
这篇文章适合谁看?简单说就是三类人:一是刚接手项目服务器、发现磁盘使用率天天告警的运维新手;二是想写个日志清理脚本但不知道从哪下手、怕写错把数据删了的同学;三是已经在用 logrotate 但遇到各种奇怪问题、想找个更可控方案的人。我会把脚本逐行拆开讲清楚,包括常用的 find 参数、脚本保护机制、定时任务配置和网上很少有人讲的坑,你照着抄基本就能用。
1. 日志是怎么一步步把磁盘吃满的
先说个很多人容易忽略的事实:日志不是“偶尔”把磁盘填满的,只要服务在线,它就在稳定增长。项目里的日志来源非常多,Nginx 访问日志、Java 应用的 log4j 输出、Python 进程的 print 重定向、数据库慢查询、系统自带的 /var/log/messages,哪个进程日志写疯了,都能在一夜之间把一块 100G 的数据盘塞得满满当当。
我那次事故的具体原因也很有代表性:某个后台服务改了日志级别,从 info 调成了 debug,结果线上用户一多,异常堆栈和调试信息像瀑布一样往日志文件里刷,一天写了 60G。这个场景你经历一次就永远忘不掉——半夜两点手机告警短信狂响,ssh 上去敲 df -h 一看,/ 分区已经 98% 了,再用 top 一查,所有依赖磁盘写入的服务都在卡死边缘。
1.1 磁盘告警后的第一波排查
遇到磁盘快满,我的排查顺序基本是固定的,这里也分享给各位:
df -h先看是哪个分区满了,是系统盘/还是数据盘/data。du -sh /var/log看日志目录总大小,如果项目有专门的日志盘/日志目录,直接du -h --max-depth=2 /var/log 2>/dev/null | sort -rh | head -20定位大目录。- 锁定到具体的大文件之后,再用
ls -lh看文件大小、stat看最后修改时间,判断这个文件是不是还在持续写入。 - 如果发现文件已经被删了但磁盘空间没释放,用
lsof +L1 | grep deleted找一下是哪个进程还持有句柄。这个场景很经典,后面我会单独讲。
这套排查三板斧看着简单,但关键时刻能救命。我建议每个运维都把这几个命令练熟,不要等到磁盘 100% 才慌慌张张去百度。
1.2 日志清理思路要在出问题之前定好
那次事故处理完,我做的第一件事不是去研究什么高深技术,而是坐下来想一个问题:日志到底要留多久、怎么删才安全?
这个问题的答案没有标准,跟业务类型强相关。游戏项目的日志,通常需要保留一段时间来排查玩家反馈的问题,但也不需要留一年,半个月到一个月的量级就足够了。我当时按磁盘容量倒推算了一笔账:项目一天产生大概 1G 日志(这是根据 nginx 访问量和应用日志量粗估的),磁盘剩余 100G,那保留 30 天大约占用 30G,完全可控,还能留出余量给数据库 binlog 和其他临时文件。于是我就把“保留 30 天”定成了清理阈值。
这里有个经验要说一下:不要等磁盘报警了才去清,更不要手动 rm -rf 一些看着不顺眼的日志文件。日志清理最好做成一个自动化的、可追溯的、安全兜底的机制,这就是我下面要说的脚本方案。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 日志清理方案选型:为什么最后用自研脚本
想解决日志清理,最“正规”的方案其实是 logrotate,但实际跑过生产的同学都知道,logrotate 配置说简单也简单,说麻烦也很麻烦。我在当时那
