应优先运行 df -i 检查 inode 使用率,因 inode 耗尽会导致磁盘空间未满(如仅 45%)却无法写入新文件,nginx 日志目录是高危区,需通过 df -h、df -i、find 统计和 ls -i 等命令交叉验证并定位问题。

直接看 df -i,别只盯着 df -h。inode 耗尽时磁盘空间可能还有 70%,但新文件一个都写不了——这是最典型的“假满”现象,Nginx 日志目录(尤其是轮转不及时的 /var/log/nginx/ 或宝塔的 /www/wwwlogs/)正是高危区。
确认是否真为 inode 耗尽
运行以下命令交叉验证:
-
df -h:查磁盘使用率,若远低于 100%(比如仅 45%),但服务报 “No space left on device”,就高度可疑; -
df -i:重点看根分区(/)或日志所在分区的IUse%,≥95% 即可锁定; -
find /var/log/nginx -type f | wc -l:统计 Nginx 日志文件总数,超 50 万份(尤其含大量access.log.1.gz、error.log.20260701等轮转碎片)是明确信号; -
ls -i /var/log/nginx/*.log*:观察 inode 编号是否密集连续,密集即说明小文件堆积严重。
定位 inode 消耗主力目录
Nginx 本身不生成海量小文件,但它的日志轮转机制若配置不当,会留下大量未压缩或未清理的旧日志碎片:
- 检查 logrotate 是否启用:
ls /etc/logrotate.d/nginx,缺失或内容为空则轮转失效; - 查看轮转后残留:
ls -la /var/log/nginx/ | grep "\.log\." | head -10,若看到几十个access.log.1~access.log.50,说明 rotate 数没设上限或 compress 失败; - 排查已删但句柄未释放的日志:
lsof +L1 | grep nginx,若输出含access.log (deleted),说明 worker 进程仍在写已被 rm 的文件,持续占用 inode 和空间。
快速释放 inode 并恢复写入
清理目标不是“删大文件”,而是“清小文件+释放句柄”:
- 安全清空当前日志(保留文件结构):
truncate -s 0 /var/log/nginx/access.log /var/log/nginx/error.log; - 批量删除过期轮转日志:
find /var/log/nginx -name "access.log.*" -mtime +30 -delete(保留 30 天内); - 强制 Nginx 重新打开日志文件:
nginx -s reopen或kill -USR1 $(cat /var/run/nginx.pid),释放所有(deleted)句柄; - 若 PHP-FPM 或其他进程也占用 session 小文件,一并执行:
systemctl restart php-fpm(低峰期操作)。
堵住源头:防止再次耗尽 inode
靠手动清理治标不治本,必须让日志管理自动化且克制:
- 在
/etc/logrotate.d/nginx中强制加入:rotate 15(最多存 15 份)、compress(自动 gzip)、delaycompress(避免刚轮转就压缩); - 禁用非必要日志:
access_log off;对静态资源路径,或全局改用access_log /dev/null;; - 精简日志格式:
log_format main '$remote_addr - $time_local "$request" $status $body_bytes_sent';,去掉$http_user_agent等易膨胀字段; - 启用缓冲写入:
access_log /var/log/nginx/access.log main buffer=128k flush=10s;,降低小文件生成频率。











