df显示满但找不到大文件,可能是已删除但仍被进程写入的日志文件;用lsof +l1查找del条目,重启服务或kill -usr1释放句柄;检查logrotate配置、php临时文件、mysql binlog等隐藏空间占用源。

df显示满但找不到大文件?可能是已删除但进程还在写入
Linux下用rm删掉的log文件,如果仍有进程(比如php-fpm、nginx或自定义脚本)在持续fopen(..., 'a')写入,该文件的inode不会立即释放,df仍会计入已用空间,但ls和du都看不见它。
实操建议:
立即学习“PHP免费学习笔记(深入)”;
- 运行
lsof +L1,列出所有“已删除但仍被打开的文件”,重点关注php-fpm、apache2、tail等进程的DEL条目 - 找到对应PID后,用
lsof -p <pid></pid>确认具体文件路径和写入状态 - 稳妥做法是重启相关服务:
systemctl restart php-fpm(或nginx),释放句柄;若不能重启,可尝试kill -USR1 <pid></pid>(部分PHP-FPM配置支持平滑重载日志)
logrotate没生效?检查配置与权限是否匹配
很多PHP项目依赖logrotate自动轮转error.log或laravel.log,但配置错一条就可能失效——比如日志路径写错、create权限不对、或postrotate里没发信号给PHP进程重开文件。
实操建议:
立即学习“PHP免费学习笔记(深入)”;
- 确认logrotate实际加载的配置:
logrotate -d /etc/logrotate.conf(加-d调试模式看是否匹配到你的日志路径) - 检查日志文件属主是否和
logrotate配置中create指定的用户一致,例如PHP-FPM以www-data运行,但create 0644 root root会导致轮转后新文件无法写入,旧文件越积越大 - 若使用
copytruncate,注意它不移动原文件,只是清空内容,适合无法中断写入的场景;但频繁清空可能掩盖突发错误,建议配合监控
PHP自身缓存/临时文件占满/var/tmp或/opcache?
除了应用日志,PHP运行时也会产生大量临时数据:上传临时文件(upload_tmp_dir)、OPcache内存映射文件(某些配置下会落盘)、或Composer缓存(~/.composer/cache)。这些常被忽略,但单个可超GB。
实操建议:
立即学习“PHP免费学习笔记(深入)”;
- 查PHP实际使用的临时目录:
php -i | grep 'upload_tmp_dir\|sys_temp_dir',然后du -sh /var/tmp/* | sort -hr | head -5定位大户 - 检查OPcache是否启用了
opcache.file_cache(非内存模式),路径通常在/tmp/opcache/,里面一堆.bin文件可能残留数月 - 清理Composer缓存:
composer clear-cache(注意不是dump-autoload);若用Docker,确认/tmp是否挂载为tmpfs,否则容器退出后文件仍留在宿主机
MySQL慢查询日志或binlog也在吃空间?别只盯PHP
PHP应用常搭配MySQL,而slow_query_log_file默认可能写到/var/lib/mysql/同分区,且expire_logs_days未设或设得过大,binlog一天就能吃掉几十GB。
实操建议:
立即学习“PHP免费学习笔记(深入)”;
- 进MySQL执行:
SHOW VARIABLES LIKE 'slow_query_log%';和SHOW VARIABLES LIKE 'log_bin%';,确认日志开关与路径 - 查binlog数量和大小:
SHOW BINARY LOGS;,再用PURGE BINARY LOGS BEFORE '2024-01-01 00:00:00';清理(生产环境先备份) - 临时关慢日志(如非必要):
SET GLOBAL slow_query_log = 'OFF';,并修改my.cnf中slow_query_log = 0防止重启恢复
真正卡住的往往不是“删不掉的文件”,而是“删了还回来”的机制——比如定时任务每分钟追加日志却从不轮转,或者PHP-FPM子进程崩溃后残留句柄。排查时优先用lsof +L1和logrotate -d,比盲目du -sh /*高效得多。











