0%

文件删除空间未释放的例子

背景

在删除文件后,有时会遇到磁盘空间并未被释放的场景。这里自己尝试复现,并去做相关的说明。

删除后空间未释放

根目录下当前占用空间是626G。

创建的文件/tmp/safedog_windows_2012_new.img占了15G。(ls和du的区别留到后面讲)
![image](文件已删除空间未释放的例子/2_ 文件占用空间.png)

这里用vim打开文件,让有个进程一直在使用这个文件。

删除文件后,空间并未释放。

原因分析:

一个文件在文件系统中的存放分为两个部分:数据部分和指针部分,指针位于文件系统的meta-data中,数据被删除后,这个指针就从meta-data中清除了,而数据部分存储在磁盘中,数据对应的指针从meta-data中清除后,文件数据部分占用的空间就可以被覆盖并写入新的内容,之所以出现删除文件后,空间还没释放,就是因为有进程还在一直向这个文件写入内容,导致虽然删除了文件,但文件对应的指针部分由于进程锁定,并未从meta-data中清除,而由于指针并未被删除,那么系统内核就认为文件并未被删除,因此通过df命令查询空间并未释放也就不足为奇了。

释放的解决措施

停掉或重启占用文件的进程

重启或停止进程后,系统会自动回收

Truncate File Size

Alternatively, it is possible to force the system to de-allocate the space consumed by an in-use file by forcing the system to truncate the file via the proc file system. This is an advanced technique and should only be carried out when the administrator is certain that this will cause no adverse effects to running processes. Applications may not be designed to deal elegantly with this situation and may produce inconsistent or undefined behavior when files that are in use are abruptly truncated in this manner.

1
2
3
> /proc/$pid/fd/$fd_number   
echo > /proc/$pid/fd/$fd_number
echo "" > /proc/$pid/fd/$fd_number

// 以上截断命令的区别

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
> /proc/$pid/fd/$fd_number   //截断后占据空间为0 

[root@xxg-uhost1683 2018-01-09]# > /proc/21780/fd/4
[root@xxg-uhost1683 2018-01-09]# lsof -p 21780 | grep delete
less 21780 root 4r REG 253,0 0 171442340 /opt/data/delay_delete/2018-01-09/1356f3f2-1c93-4c9e-9f9f-0a4cee57f5b7.img_1515479993 (deleted)

echo > /proc/$pid/fd/$fd_number //截断后占据空间为1个字节

[root@xxg-uhost1683 2018-01-09]# echo > /proc/27052/fd/4
[root@xxg-uhost1683 2018-01-09]# lsof -p 27052 | grep delete
less 27052 root cwd DIR 253,0 4096 7995395 /opt/data/delay_delete/2018-01-09
less 27052 root 4r REG 253,0 1 171442356 /opt/data/delay_delete/2018-01-09/1ede93ec-4424-413f-ad24-9781038abdf7.img_1515479994 (deleted)

echo "" > /proc/$pid/fd/$fd_number // 占据空间为1个字节

[root@xxg-uhost1683 2018-01-09]# echo "" > /proc/7706/fd/4
[root@xxg-uhost1683 2018-01-09]# lsof -p 7706 | grep delete
less 7706 root cwd DIR 253,0 4096 7995395 /opt/data/delay_delete/2018-01-09
less 7706 root 4r REG 253,0 1 284164259 /opt/data/delay_delete/2018-01-09/439e3eb3-0272-44ad-b1ee-5ad248ca2db8.disk_1515479994 (deleted)

echo "" > /proc/$pid/fd/$fd_number // 占据空间为2个字节

[root@xxg-uhost1683 2018-01-09]# echo " " > /proc/7706/fd/4
[root@xxg-uhost1683 2018-01-09]# lsof -p 7706 | grep delete
less 7706 root cwd DIR 253,0 4096 7995395 /opt/data/delay_delete/2018-01-09
less 7706 root 4r REG 253,0 2 284164259 /opt/data/delay_delete/2018-01-09/439e3eb3-0272-44ad-b1ee-5ad248ca2db8.disk_1515479994 (deleted)

以下直接操作文件名均不起作用

1
2
3
> /tmp/safedog_windows_2012.img //不起作用
echo > /tmp/safedog_windows_2012.img //不起作用
echo "" > /tmp/safedog_windows_2012.img不起作用

删除后文件未释放的恢复

1
2
cp /proc/44848/fd/4 /tmp/safedog_windows_2012_new.img1    //方法1
cat /proc/44848/fd/4 > /tmp/safedog_windows_2012_new.img2 //方法2

恢复的文件占用空间还会更大,是否恢复出来的已经不是稀疏的了?后面待解释

比较文件的一致性

1
diff /tmp/safedog_windows_2012_new.img1 /tmp/safedog_windows_2012_new.img2

参考链接

由一次磁盘告警引发的血案 – du 和 ls 的区别

Why is space not being freed from disk after deleting a file in Red Hat Enterprise Linux?