Linux的du和df命令
这是4月18号的流水账
今天如往常一样完成一个功能后,把代码推到测试环境,结果 response 有点跟往常不一样:
1 | |
No space left on device. 意思是测试服务器上没空了呗,上去看一下:
1 | |
果不其然,那应该是缓存文件太多了,去缓存目录看一下:
1 | |
那清一清吧。
1 | |
清完然后就好使了。
可是清完后跟之前的数有点对不大上:
1 | |
我猜可能是虚拟机的存储管理机制的缘故,物理机出现这种情况的话那才奇了怪了,不过我也没兴趣继续深究这个问题。
就是记一次流水账,非科普。
需要科普可以去查 Linux命令大全。
以下是4月19号的补充
本以为今天和往常一样,结果跟昨天一样。
测试服务器磁盘又满了。
隐约觉得应该是哪儿溢出了,top 一下果然 php 进程始终99%,又看了下php进程,有一个执行后台计算的脚本,从4月17号下午就已经存在了,sudo kill -9 了之后,结果 df -h 对上了!
1 | |
然后把那个“溢出”的进程在本地复现了之后,想起了昨天的那句:
物理机出现这种情况的话那才奇了怪了。
所以说,还是看看怎么给虚拟机平反吧。毕竟,真相只有一个!
果不其然,一查就找到了真相,有以下三种情况:
1.预留空间
为了预防紧急情况,linux ext文件系统会预留部分硬盘空间,具体预留的数值可以通过
tune2fs -l [dev_name] | grep "Reserved block count"查看到(dev_name是设备名),这里预留的空间会被df计算到已用空间中,从而导致df和du统计不一致。如果需要调整预留空间大小,我们可以使用tune2fs -m [size] [dev_name]来进行调整。
2.幻影文件(phantom file)
du是统计被文件系统记录到的每个文件的大小,然后进行累加得到的大小,这是通过文件系统获取到的。而df主要是从超级块(superblock)中读入硬盘使用信息,df获取到的是磁盘块被使用的情况。当一个文件被删除时,如果有别的进程正在使用它(占有句柄),
这个文件将不会被du统计到,但是这个文件被占用的磁盘空间却依然会被df统计到。这些文件,以及正在使用这些文件的进程可以通过lsof | grep deleted查到。当进程停止或者被 kill 时,这些空间将被释放。
3.未统计到的文件
如果上面两种情况都排除了,但是数据还是不一致,那是怎么回事?这里隐藏着一种情况:当我们将一个目录挂在到一个新的设备(硬盘)上之前,如果这个目录里面已经有数据,那么这一部分数据不会被
du感知,在文件系统中也看不到这些数据,但是这些数据又是确实占用了磁盘空间,是能够被df所统计到的。这时候通过du/df统计原设备的空间使用情况,就会发现df统计到的比du要多。遇到这样的情况时,使用fuser -km [directory]杀死占用该目录的所有进程(小心操作!),然后使用umount [directory]将该目录挂载的设备卸载,这时,目录里面原来已有的数据就会出现,我们将其删除之后,再重新挂载设备(mount -t [type] [dev] [directory])即可。
而发生在我这里的就是第二种情况,文件被删除后,句柄还在被进程占用着,所以导致 du 和 df 意见不统一,kill 掉占用进程后,统计结果就一致了。
本想写篇流水账凑数,结果还是被强行 push 到探索真相的道路上。
题外话
上面说那个“溢出”的进程加引号的原因是,表面上看起来像是溢出的进程,其实是产品经理那天添加了一个计算结果超过100亿行的计算任务,可能等了半天也没见出结果,就把那条记录给删掉了… 然后测试机就一两核 cpu & 2G 内存的虚拟机,两天也没运行完,所以就造成了看似溢出的假象。
本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!