用 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 的组合同样有这个问题;只有持有句柄的进程重新打开文件,空间才真正归还给文件系统。这类问题最好一次改到位,反复小改反而容易把原因搅混。