日志目录磁盘写满导致Nginx崩溃的本质是写入阻塞、句柄卡死与缓存中断的连锁反应,需通过du查暴涨日志、lsof+L1找已删未释放句柄、iostat看%util和await判断I/O饱和,并结合error.log和access.log尾部分析定位暴增源头。

日志目录磁盘写满导致 Nginx 崩溃,本质不是“空间满了”那么简单,而是触发了写入阻塞、句柄卡死、缓存中断等连锁反应。排查必须跳过表象,直击进程级和 I/O 级真实瓶颈。
看磁盘占用只是第一步,别只盯 df -h
df -h 显示 /var/log/nginx 或 /usr/local/nginx/logs 占满,这只是故障信号灯,不是原因本身。重点要确认:是不是日志真在暴涨?有没有其他文件或临时文件在偷偷吃空间?
- 执行 du -sh /var/log/nginx/* 2>/dev/null | sort -hr | head -3,看 access.log、error.log 是否单个突破 GB 级(比如 >5GB);
- 再跑 du -sh /var/log/* | sort -hr | head -5,排除其他服务(如 auditd、journalctl)日志误占;
- 如果发现 /var/log/nginx 下没大文件,但 df 显示满,极可能有已删未释放的句柄——下一步必须查 lsof。
查 lsof 找“删了还在写的”日志句柄
Nginx 进程若仍持有已被 rm 删除的日志文件句柄,磁盘空间就永远不会释放。这是最常被忽略却最致命的一环。
- 运行 lsof +L1 | grep nginx(+L1 专查已删但未释放的文件),输出类似:
nginx 12345 nobody 7w REG 253,0 8567123456 10835682 /var/log/nginx/access.log (deleted) - 只要看到 (deleted) 字样,说明该进程还在往一个“不存在”的文件里狂写,空间被死锁;
- 注意 PID(如 12345),它就是卡住空间的 worker 进程,不能直接 kill -9,需配合 reopen 操作。
用 iostat 判断是不是 I/O 已彻底堵死
磁盘 100% 不等于“慢”,可能是完全卡死。I/O 阻塞会拖垮整个 Nginx 请求链路,甚至让 master 进程无法响应 reload。
- 执行 iostat -x 1 3,重点关注两列:
– %util:持续接近 100%,说明磁盘忙到没空闲时间;
– await:平均每次 I/O 等待毫秒数,>100ms 就属严重异常; - 如果 %util=100 且 await >200ms,基本可断定磁盘写入已饱和,Nginx 日志刷盘失败,进而引发 worker 进程僵死或请求超时堆积;
- 此时单纯清日志无效,必须先缓解 I/O 压力(如暂停非核心日志、切走流量),再释放空间。
结合 error.log 尾部内容定位日志暴增源头
日志暴涨从来不是随机的,大概率是某段代码或配置异常,导致高频、重复、无意义的日志刷屏。
- 执行 tail -n 100 /var/log/nginx/error.log,看是否有大量相同错误反复出现(如 “connect() failed (111: Connection refused) while connecting to upstream”);
- 再查 tail -n 100 /var/log/nginx/access.log | awk '{print $9}' | sort | uniq -c | sort -nr | head -5,统计 HTTP 状态码分布,若 502/503 占比极高,说明上游服务失联,Nginx 在不断重试并记错;
- 如果发现某类请求每秒数百条且返回固定状态(如 400 或 444),很可能是攻击或客户端 bug,需配合限流或过滤规则止血。


















