Linux系统文件删除原理
Linux系统上的文件名是存储在父目录的Block里面的,并指向了这个文件的Inode节点,这个文件的Inode节点再标记指向存放这个文件的Block的数据块。我们删除一个文件时,实际上并不会清除Inode节点和Block的数据。只是在这个文件的父目录中的Block里,删除这个文件的名字,从而使这个文件名消失,并且无法指向这个文件的Inode节点。当没有文件名指向这个Inode节点的时候,释放Inode节点和存放这个文件数据的Block块会同时进行,并且会更新Inode MAP和Block MAP,以便让这些位置用于放置其他文件数据。
Linux系统是通过Link的数量来控制文件是否被删除的,只有当一个文件不存在任何Link的时候,这个文件才会被删除。一般来说,每个文件都有2个Link计数器,既i_count和i_nlink。 i_nlink的意义就是硬链接的数量,i_nlink可以理解为磁盘的引用计数器;i_count的意义就是当前文件使用者(例如,被进程调用)的数量,i_count可以理解为内存的引用计数器。当为文件创建硬链接的时候,对应i_nlink的数量就会增加,而当一个文件被某个进程调用时,对应i_count的数量就会增加。
通过rm删除命令删除文件,实际上就是减少文件的磁盘引用计数i_nlink的数量(及硬链接的数量)。如果在执行rm删除命令之前有程序调用了该文件,调用还没有结束;此时执行rm命令后,i_nlink=0(硬链接数为0),但是i_count不为0,因为此时还有程序在调用该文件,该文件会继续占用磁盘空间。只能i_nlink和i_count同时为0时,该文件才是被成功删除。
总结,rm操作只是将文件的i_nlink减少了,或者说置0了,实际就是将文件名到Inode的链接删除了,此时,并没有删除文件的实体即Block数据块,如果及时停止机器工作,数据还是可以找回的,但如果此时继续写入数据,那么新的数据可能就会被分配到被删除数据的Block数据块了,此时,文件就是被真正地回收了。
案例:
1、使用dd创建一个文件
[root@node1 data]# df -h Filesystem Size Used Avail Use% Mounted on /dev/sda3 96G 2.0G 94G 3% / devtmpfs 476M 0 476M 0% /dev tmpfs 487M 0 487M 0% /dev/shm tmpfs 487M 7.6M 479M 2% /run tmpfs 487M 0 487M 0% /sys/fs/cgroup /dev/sda1 497M 120M 378M 25% /boot tmpfs 98M 0 98M 0% /run/user/0 /dev/sdb1 991M 2.6M 922M 1% /data [root@node1 ~]# cd /data [root@node1 data]# dd if=/dev/zero of=/data/test.log bs=1M count=1000 dd: error writing ‘/data/test.log’: No space left on device 973+0 records in 972+0 records out 1019625472 bytes (1.0 GB) copied, 1.41008 s, 723 MB/s [root@node1 data]# ls -ihl /data total 973M 11 drwx------ 2 root root 16K Sep 25 16:59 lost+found 12 -rw-r--r-- 1 root root 973M Sep 25 17:19 test.log
2、使用vim命令一直调用test.log文件
[root@node1 data]# vim test.log
3、在不中断vim调用test.log的情况下,另外开启一个终端来删除test.log文件
[root@node1 ~]# rm -f /data/test.log [root@node1 ~]# ls /data [root@node1 ~]# [root@node1 data]# df -h Filesystem Size Used Avail Use% Mounted on /dev/sda3 96G 2.0G 94G 3% / devtmpfs 476M 0 476M 0% /dev tmpfs 487M 0 487M 0% /dev/shm tmpfs 487M 7.7M 479M 2% /run tmpfs 487M 0 487M 0% /sys/fs/cgroup /dev/sda1 497M 120M 378M 25% /boot tmpfs 98M 0 98M 0% /run/user/0 /dev/sdb1 991M 975M 0 100% /data #/data的空间占用率任然为100% [root@node1 data]# lsof |grep delete vim 7503 root 3r REG 8,17 1019625472 12 /data/test.log (deleted) #可以发现test.log文件任然继续被vim命令调用,此时i_nlink=0,i_count不为0
4、停止vim继续调用test.log文件
[root@node1 data]# kill 7503 [root@node1 data]# lsof |grep delete [root@node1 data]# [root@node1 data]# df -h Filesystem Size Used Avail Use% Mounted on /dev/sda3 96G 2.0G 94G 3% / devtmpfs 476M 0 476M 0% /dev tmpfs 487M 0 487M 0% /dev/shm tmpfs 487M 7.7M 479M 2% /run tmpfs 487M 0 487M 0% /sys/fs/cgroup /dev/sda1 497M 120M 378M 25% /boot tmpfs 98M 0 98M 0% /run/user/0 /dev/sdb1 991M 2.6M 922M 1% /data [root@node1 data]# #data目录空间已经被释放
三、文件删除流程图