磁盘写满导致Nginx日志写入阻塞,引发请求卡顿、502/504及worker假死;需通过df、lsof、ps确认I/O阻塞,临时停日志或truncate恢复,并配置logrotate与监控预防。

当磁盘写满时,Nginx 可能因无法写入 access.log 或 error.log 而出现请求卡顿、502/504、worker 进程假死等现象——这并非 Nginx 崩溃,而是日志写入系统调用被阻塞(如 write() 陷入不可中断睡眠 D 状态),进而导致 worker 无法处理新请求。
确认是否为磁盘满引发的日志阻塞
先快速验证磁盘和日志状态:
- 运行
df -h查看根分区或 Nginx 日志所在分区(如/var/log)使用率是否 ≥95% - 执行
lsof +L1检查是否有被删除但仍被进程打开的大文件(常见于未 reload 的旧日志) - 用
ps aux | grep nginx观察 worker 进程状态列:若大量显示D(uninterruptible sleep),高度疑似 I/O 阻塞 - 临时停掉日志写入测试:
nginx -s stop && nginx -t && nginx -c /etc/nginx/nginx.conf(不加载 access_log/error_log 指令),再观察是否恢复响应
检查 Nginx 日志配置与实际写入路径
日志路径可能被 alias、symlink 或 mount 覆盖,需确认真实落盘位置:
- 查看主配置中
access_log和error_log指令,注意是否含变量(如$host)或相对路径 - 用
nginx -T 2>/dev/null | grep -E "(access_log|error_log)"输出所有生效日志路径 - 对每个日志路径执行
readlink -f /path/to/access.log,再df $(dirname [resolved-path])定位真实挂载点 - 特别留意
error_log /dev/stderr或syslog:等非文件目标,它们不会占磁盘但可能掩盖真正问题
紧急恢复与临时规避措施
在释放磁盘前,避免重启 Nginx(可能触发更多日志写入失败):
- 立即清空或轮转大日志:
truncate -s 0 /var/log/nginx/access.log(比> file更安全,不破坏 inode) - 若用 logrotate,手动触发:
logrotate -f /etc/logrotate.d/nginx,并确认 postrotate 中有nginx -s reload - 临时关闭访问日志(仅限应急):
access_log off;放入 http/server/location 块,然后nginx -s reload - 禁止新日志写入的同时,用
strace -p $(pgrep nginx | head -1) -e write观察是否仍有日志系统调用卡住
长期预防:日志管理与监控加固
避免重复发生,需从机制上约束:
- 为日志目录单独挂载小容量磁盘(如
/var/log/nginx),并设noatime,nobarrier减少开销 - logrotate 配置中强制添加
maxsize 100M和rotate 7,禁用copytruncate(改用create+reload) - 在 Nginx 配置中限制单个日志文件大小(虽原生不支持,但可通过外部脚本配合
open_log_file_cache off实现按大小 reload) - 部署基础监控:用
df检查 +inotifywait -m /var/log/nginx -e create,delete_self捕获异常轮转行为


















