用 truncate 把一个大日志清成零字节,du 显示该文件已经是零,df 却还是满的,重启服务之后空间才回来。

把日志和配置对完,能解释这个现象的基本就这几处。文件句柄被进程持有,inode 仍然指向原来的数据块。少数情况下是文件存在硬链接,删掉一个名字空间并不会减少块。

不容易想到的是,文件系统延迟回收,统计数字刷新有滞后。

动手时先确认文件是否还有句柄

lsof /var/log/app.log

随后让写日志的进程重新打开文件

systemctl reload rsyslog

然后用 truncate 而不是 rm 处理

truncate -s 0 /var/log/app.log

等前面都确认过,再核对空间是否真的回收

df -h /var && du -sh /var/log

这台环境是别人交接的,不少默认值被动过,只能一项项核。

改完先别撤,确认这几项。df 的已用空间下降量与原文件大小相当,lsof 里该路径的句柄数归零。

这里还有个坑。rm 加 touch 的组合同样有这个问题;只有持有句柄的进程重新打开文件,空间才真正归还给文件系统。这类问题最好一次改到位,反复小改反而容易把原因搅混。

作者 9823189