删除文件后也未释放磁盘空间问题

今天服务器遇到根分区空间不够,赶紧把根分区的一些大文件 link 到了其他分区。再用 df 命令查看分区大小,发现根分区使用率还是 100%,但根分区中所有文件大小加上是不会占满磁盘的。

研究了一下,这是因为进程在占用文件句柄,文件删除后是没有释放磁盘空间的,可以通过 lsof | fgrep deleted 查看:

java      30619 30692         xx   52r      REG              202,1     408133   181052 /opt/hadoop/share/hadoop/common/lib/jasper-compiler-5.5.23.jar (deleted)
java      30619 30692         xx   53r      REG              202,1      62050   181079 /opt/hadoop/share/hadoop/common/lib/commons-logging-1.1.3.jar (deleted)
java      30619 30692         xx   54r      REG              202,1      41123   181093 /opt/hadoop/share/hadoop/common/lib/commons-cli-1.2.jar (deleted)

要解决这个问题,必须重启这些服务的进程才可以。

因为进程退出最终会调用 do_exit 函数(kernel/exit.c),该函数会在进程基本上结束差不多后才开始清理进程占用的资源:

exit_sem(tsk);
exit_shm(tsk);
exit_files(tsk);
exit_fs(tsk);
if (group_dead)
  disassociate_ctty(1);
exit_task_namespaces(tsk);
exit_task_work(tsk);
exit_thread();

服务启动后再看磁盘空间,正常了。