ls -lh文件大小比du -sh小的情况参考 IT虾米网
du显示的是文件占block大小,通常1byte的文件,du大小是4bytes,这个是可以理解的,可偏偏ls -lh的结果比du -sh的要大。
ls显示的是文件的逻辑大小,du显示的是磁盘占用情况,逻辑占用大于磁盘本身占用情况,这是为什么呢?
$ ls -lh xxx.log
-rw-rw-r-- 1 app app 152G Apr 25 09:44 xxx.log
$ du -sh xxx.log
228M xxx.log
#--apparent-size,效果与ll相同。因为--apparent-size查看的文件实际大小非占用block大小。
$ du --apparent-size -lh xxx.log
152G xxx.log
原因是文件所占磁盘被释放,但进程正在写入的文件的offset并咩有改变,从而形成了空洞文件,而ls显示大小是将空洞算在内的。 此时,我们用lsof(list open files)是看不到deleted状态的文件的,但用sudo lsof-check.sh 可以看到一些写入文件的offset。
$ df -h #重启后,磁盘大小已经恢复正常
Filesystem Size Used Avail Use% Mounted on
/dev/vda1 50G 3.3G 44G 7% /
/dev/vdb 197G 8.3G 189G 5% /data
总结:
清理有进程不停写入的文件,在不停进程情况下, 虽可以采用sudo bash -c "echo > /logs/xxx.log"方式有效避免打开句柄未正常关闭问题。但会偶现磁盘正常释放,但进程写入的offset并未更新的情况。这里有一个尝试的想法,有兴趣的可以尝试,类似于在线修改表结构的处理。