du 看到 /var/log/nginx 占了 38G,access.log 单个文件 21G,df 已经 100%,写日志报 No space left on device,接口跟着 500。日志里能对上时间点,这种反而好排。
logrotate 里的 nginx 段缺 postrotate 或者没给 master 发 USR1,日志改名之后进程还握着旧 inode 继续写,新文件一直是 0 字节。这一点先确认清楚,后面就不用反复试。
logrotate -d /etc/logrotate.d/nginx ls -l /proc/$(cat /run/nginx.pid)/fd | grep access kill -USR1 $(cat /run/nginx.pid) : > /var/log/nginx/access.log
「Nginx 日志切割」改完先别急着全量,挑一台机器放半天,真有问题这段时间就能看出来。先做最小复现,能稳定跑出来的问题,排查成本会低一个数量级。
别只看报错的最后一行,往上看几行,真正的起因通常在上面。同类问题如果隔一段时间又出现,多半是某个定时任务或重启流程把改动冲掉了。
把这次用到的命令存进笔记,比记住结论有用,换个环境还能照着走。
处理上按这个顺序:先用 logrotate -d 确认这段规则有没有被匹配到;在 postrotate 里给 master 进程发 USR1 让它重开文件;已经删掉但被占用的空间用截断而不是 rm。
结果对不对很好判断,切割后旧文件被压缩,新的 access.log 马上有写入,df 可用空间明显回升。
