-
博文分类专栏
- Jquery基础教程
-
- 文章:(15)篇
- 阅读:46567
- shell命令
-
- 文章:(42)篇
- 阅读:154239
- Git教程
-
- 文章:(36)篇
- 阅读:234850
- leetCode刷题
-
- 文章:(76)篇
- 阅读:131794
-
Linux硬盘空间报警,但没有找到占用文件2018-06-15 23:46 阅读(5380) 评论(0)
一、概述
昨天磁盘空间报警了,登录机器后,使用df命令,根分区已经85%,如下:
dev 5.9G 0 5.9G 0% /dev run 5.9G 1.2M 5.9G 1% /run /dev/sda2 110G 45G 60G 85% /
但是通过du命令,一直找不到比较大的文件,什么鬼呢?明明磁盘空间都报警了,但是实际占用却很少。
如果文件被删除了,文件句柄没有释放就会导致这种情况,即僵尸文件。
赶紧使用lsof命令搞一下
lsof | grep deleted
确实有一波文件被删除,句柄没有释放,如下:
直接使用kill命令干死对应的进程,发现磁盘空间报警便恢复了。
二、linux文件创建和删除过程
1、linux是如何打开文件的
在了解文件如何打开之前,我们首先要清楚进程的文件描述符、进程打开的文件表以及i-node节点之间的关系,大致如下:
比如,我们在iterm2中,执行如下命令:
cat /tmp/a.log
首先,根据文件名,依据文件的映射关系找到对应的Inode number。
然后,根据Inode number读取到文件的Inode table,就可以做权限矫正了。
最后,根据Inode table中的Pointer读取到对应的Blocks,返回给对应的进程。
2、文件删了为什么文件占用空间就不释放
要理解不释放的原因,需要了解文件创建和文件删除过程,如下:
a、文件的创建过程
(1)首先从inode table中找一个空闲的inode分配给a.log,比如2230660,并将该inode节点标记为已使用。
(2)在/tmp目录文件的data block中添加一条a.log文件的记录,该记录中包括一个指向inode号的指针。
(3)在/tmp对应分区的data block map中找出空闲的data block,将a.log的数据写入到data block。
(4)设置inode table中2230660节点的data block指针,这样通过a.log的inode节点,可以指定其使用那些data block。
b、文件删除过程
(1)在inode table中删除文件a.log的data block 指针。一旦删除,外界就找不到a.log的数据了,但是这个文件的数据还是存在的,只是它被“损坏”了,因为没指针指向它。
(2)在inode节点(2230660)标记为未使用,这个时候,inode就释放了,可以被复用。
(3)删除父目录 /tmp的data block中a.log记录,这里一旦删除,外界就看不到也找不到这个文件了。
(4)在data block map中将a.log占用的block标记为未使用。一旦标记,data block就可以被重复使用了。
当文件被删除时,仍还有进程在使用这个文件,会发生什么呢?外界是看不到也找不到这个文件的,所以删除的过程已经进行到了上面的第(3)步。但进程还在使用这个文件的数据,也能找到这个文件的数据,是因为进程在加载这个文件的时候就已经获取到了该文件占用哪些data block,虽然删除了文件,但data block map中这些data block还没有标记为未使用。这就是为啥有时候文件删除了,占用空间不释放的原因。
三、关于df和du的区别
1、du是基于stat命令来统计每个文件(包括子目录)的空间占用总和,一般速度较慢。
2、df是读取每个分区的superblock来获取空闲数据块、已使用数据块,从而计算出空闲空间和已使用空间,速度较快。
3、针对已删除但仍有进程在使用的文件,统计大小的时候,df会算上,du会忽略。