从保持打开状态的已删除文件中释放磁盘空间的最佳方法


28

嗨,我有许多文件已被删除,但是由于某种原因,与删除的文件相关联的磁盘空间无法利用,直到我明确杀死占用磁盘空间的文件的过程为止

$ lsof /tmp/
COMMAND   PID USER   FD   TYPE DEVICE SIZE/OFF      NODE NAME
cron     1623 root    5u   REG   0,21        0 395919638 /tmp/tmpfPagTZ4 (deleted)

上面已删除的文件占用的磁盘空间会引起问题,例如尝试使用Tab键自动完成文件路径时出现错误 bash: cannot create temp file for here-document: No space left on device

但是,在我运行kill -9 1623该PID的空间后,就不再释放该错误。

我的问题是:

  • 为什么第一次删除文件时没有立即释放此空间?
  • 找回与已删除文件关联的文件空间的最佳方法是什么?

并且请让我知道我使用的任何错误术语或有关此情况的其他任何相关信息。

Answers:


26

在unices上,文件名只是指向文件所在的内存(可以是硬盘驱动器,甚至是RAM支持的文件系统)的指针(索引)。每个文件记录到它的链接数:链接可以是文件名(复数,如果有多个硬链接指向同一个文件),并且每次打开文件时,该过程实际上都将“链接”保存为相同的空间。

仅在没有链接时才释放该空间(因此,无法访问该空间)。那是唯一明智的选择:在使用文件时,其他人无法再访问它并不重要:您正在使用它,直到关闭它,您仍然可以控制它-您甚至都不会注意到文件名不见了或感动了。甚至用于tempfile:某些实现会创建一个文件并立即取消链接,因此该文件在文件系统中不可见,但是创建该文件的进程通常在使用它。Flash插件特别喜欢这种方法:所有下载的视频文件都保持打开状态,但文件系统未显示它们。

因此,答案是,尽管进程仍在打开文件,但您不应期望收回空间。它没有被释放,正在被积极使用。这也是应用程序在使用完文件后应真正关闭文件的原因之一。在正常使用中,您不应该认为该空间是免费的,这也不应该是非常普遍的-除了故意取消链接的临时文件外,实际上不应该有任何文件考虑不使用,但仍然开放。尝试查看是否有一个过程可以做到这一点,并考虑如何使用它,或者只是找到更多空间。


24

文件从文件系统中删除,其中删除了对该索引节点的任何引用。引用可以在磁盘上(任何目录中的链接),也可以来自打开的应用程序。如果删除文件-您只删除磁盘上的引用,但是-应用程序中仍然有引用。

您可以通过两种方式“释放”空间:

  1. 如上所述-您可以杀死打开文件的应用程序。
  2. 您可以...截断文件。即使已删除:

如果您知道pid,请查看此pid打开的文件:ls -l / proc / PID / fd,您会在此处看到以下链接:

undefine @ uml:〜$ ls -l / proc / 18596 / fd
razem 0
lrwx ------ 1未定义未定义64 lut 1 00:06 0-> / dev / pts / 30
lrwx ------ 1未定义未定义64 lut 1 00:06 1-> / dev / pts / 30
lrwx ------ 1未定义未定义64 lut 1 00:05 2-> / dev / pts / 30
lr-x ------ 1未定义未定义64 lut 1 00:06 3-> / home / undefine / x(已删除)
lr-x ------ 1未定义未定义64 lut 1 00:06 4-> anon_inode:inotify

如您所见-3 fd被删除。您可以通过命令截断它(例如):

undefine @ uml:〜$:> / proc / 18596 / fd / 3
undefine @ uml:〜$ 

请记住,如果应用程序从该文件中读取文件,则可能会对他们造成危险。但是-如果它只是一个日志文件-您可以安全地截断它。


请注意,截断文件后,保存文件的原始进程仍可以追加到末尾(期望结束的地方)。结果看似巨大,但稀疏文件占用的磁盘空间更少(如果文件系统支持稀疏文件),并且它们仍在不断增长!
törzsmókus

是。如果有东西写入文件,它将在磁盘上发生。在不停止将应用程序写入磁盘的情况下避免它是很难的;)
不确定

8

正如其他人所说lsof,由于打开的文件描述符,可以用来列出所有仍在磁盘上的已删除文件。但是,这可能是很长的清单。这是一个列出这些文件的命令,这些文件按字节的升序排列:

sudo lsof -F sn0 | tr -d '\000' | grep deleted | sed 's/^[a-z]*\([0-9]*\)n/\1 /' | sort -n

可能有更简洁的方法,但是上面的命令对我有用。


5

由于正在运行的进程仍然具有刚删除文件的打开文件句柄,因此不会立即释放空间。毕竟,如果某个进程仍在尝试使用文件,则您可能真的不希望内核摆脱它(文件)。这可能会使该过程有点麻烦。释放空间的最佳方法(据我所知也是唯一)就是按照您所做的方式进行-终止进程。


比“仅仅如何工作”更好的一句话是“如果进程仍在使用文件,Unix不应试图摆脱它”。
布拉奇利,2015年

好点子。我已将其添加到答案中。
约翰

-1

(薄荷17.1)

TL; DR:

  • 检查sudo baobab(磁盘使用情况分析器)。
  • 清除root用户的垃圾箱。

语境

当我不断删除文件时,我一直在减少空间。我安装了trash-cli包装以清空垃圾,但这并没有帮助。最后,我注意到当我运行baobab(至少在Mint 17.1上,在GUI中使用Disk Usage Analyzer)检查磁盘空间结构时,它发出警告,指出某些文件夹不可访问。因此,我root使用来运行它sudo baobab。这揭示了问题。许多已删除的文件位于root用户的垃圾箱中,而不是我自己的用户。因此,我无法释放空间。然后,我简单地使用root(sudo trash-cli)清空垃圾箱,并返回所有空间。


-1

尝试使用以下命令

lsof | grep deleted

然后杀死已删除文件的pid。


行动党走到了那一步。这不能回答他们的问题。
杰夫·谢勒
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.