题 df在linux中,文件删除后没有显示正确的可用空间


我有用于存储文件的文件服务器。文件可能在那里停留一周或一年。不幸的是,当我从服务器中删除文件时, df 命令不反映释放的空间。最终,服务器被填满(df 显示99%),我的脚本不再发送任何文件,除了那里可能有几十GB的可用空间。

我有 noatime 如果这有任何区别,则在已安装的分区上标记。


107
2018-02-08 07:36




这是在单个分区还是在所有分区上发生的? - Khaled
好吧,它发生在我的主数据分区上,这是我唯一关心的分区,因为我只在其上写/删除文件。
请通过解决方案或一个链接来启发我。
什么文件系统? DF执行超级块的统计,可能是您的文件系统没有更新sb inode。你试过刷新缓存吗? - beans
使用ext4。你如何刷新缓存?


答案:


删除文件名实际上并不删除文件。其他一些进程将文件保持打开状态,导致文件无法删除;重启或终止该进程以释放该文件。

使用

lsof +L1

找出哪个进程正在使用已删除(未链接)的文件。


181
2018-02-08 07:48



一个多月内没有访问被删除的文件,访问它们的唯一进程是nginx,所以它是值得怀疑的。
+1。此外,“lsof + L1”将告诉您哪个程序正在打开文件。 - pehrs
作为root运行“lsof -n | grep文件”,你会感到惊讶的是,由于进程因任何原因保持打开状态,文件可以保留多长时间。如果所有其他方法都失败了,重新启动,我感觉很糟糕,但它肯定会确保没有任何东西保留在文件中。每个人,lsof + L1可能是更好的方式。 - ScottZ
你救了我!删除了一个93G的日志文件,并没有得到回来的空间,无法解决原因。谢谢。 - Luke Cousins
沿着相同的路线,如果这有助于其他人,我擦除了一个大的nginx access.log文件,但只能在重新启动nginx后回收空间:service nginx restart - Nick


正如Ignacio所提到的,删除文件将不会释放空间,直到您删除具有针对该文件的打开句柄的进程。

然而,您可以在不杀死进程的情况下回收空间。您需要做的就是删除文件描述符。

首先执行lsof | grep已删除以标识保存文件的进程

[hudson@opsynxvm0055 log]$ /usr/sbin/lsof |grep deleted
java       8859   hudson    1w      REG              253,0 3662503356    7578206 /crucible/data/current/var/log/fisheye.out (deleted)

然后执行:

cd /proc/PID/fd

然后

[hudson@opsynxvm0055 fd]$ ls -l |grep deleted
total 0
l-wx------ 1 hudson devel 64 Feb  7 11:48 1 -> /crucible/data/current/var/log/fisheye.out (deleted)

“1”将是文件描述符。现在输入“> FD”来回收那个空间

> 1

如果有其他进程持有该文件,您可能需要重复该操作。


21
2018-02-07 01:24



是什么 > FD 做? - Pred
它删除了文件描述符 - Adrián Deccico
做这个 > 命令有名字​​?我不得不从zsh切换到bash才能使用它。是否可以在zsh上运行它? - ariera
它是输出重定向,因此截断文件。长距离将是“echo -n> 1”或“true> 1”。它并没有真正删除FD,它只是指向一个空文件。 - eckes


一种可能性是您删除的文件在文件系统中有更多引用。如果您已创建了硬链接,则多个文件名将指向相同的数据,并且在删除对其的所有引用之前,数据(实际内容)将不会标记为空闲/可用。在删除文件之前,要么对它们进行统计(条目名为Links),要么对它们执行ls -l(应该是第二列)。

如果事实证明文件在其他地方被引用,我猜你必须ls -i文件找到inode-number,然后使用-inum <inode-number>进行查找以找到对该文件的其他引用(您可能还希望使用-mount保持在同一文件系统中)。


8
2018-02-08 10:01





该文件仍然被打开它的进程锁定。要释放空间,请执行以下步骤:

  1. sudo lsof | grep deleted 并查看哪个进程正在保存该文件。示例结果:

    $ sudo lsof | grep deleted
    COMMAND   PID USER   FD   TYPE DEVICE SIZE/OFF      NODE NAME
    cron     1623 root    5u   REG   0,21        0 395919638 /tmp/tmpfPagTZ4 (deleted)
    
  2. 使用杀死进程 sudo kill -9 {PID}。在上面的例子中,PID是1623。

    $ sudo kill -9 1623
    
  3. df 检查空间是否已经释放。如果它仍然满了,也许您需要等待几秒钟然后再次检查。


3
2018-02-16 05:31





如果已将分区配置为仅为root用户保留磁盘空间的某些部分, df 将不包括此空间。

[root@server]# df -h
Filesystem            Size  Used Avail Use% Mounted on
...
/dev/optvol           625G  607G     0 100% /opt
...

即使在通过删除文件/目录来回收空间之后,非root用户也将无法写入特定分区。

您可以通过尝试在设备上以root用户身份和非root用户身份创建文件来轻松检查是否属于您的情况。

此外,您可以通过运行来检查文件系统配置

tune2fs -l <device> | egrep "Block count|Reserved block count

并自己计算实际%。

要更改为仅root用户保留的磁盘%,请执行

tune2fs -m <percentage> <device>

2
2018-05-08 10:31





其他答案是正确的:如果删除文件,并且空间没有被释放,通常要么是因为文件仍然保持打开,要么还有其他硬链接。

为了帮助进行故障排除,请使用一个工具来告诉您驱动器空间的使用位置:您可以使用 du 了解空间的发展方向。更好的是,使用像这样的图形工具 xdiskusage (有很多像这样的人)追捕罪魁祸首。 xdiskusage和朋友们可以让你深入了解最大的空间生猪,找到空间的去向。

这样,由于第二个硬链接,您将很快找到仍占用空间的文件。它还会显示被删除但占用空间的文件(因为它不能读取文件名)(因为(权限被拒绝))。


1
2018-02-08 10:11





因为我知道你们有很多人在为redhat做这件事 /var 和gzipping文件期望FS缩小,但相反它会增长,只需​​确保服务syslog重新启动。和

lsof -v file

无论如何会告诉你这个。


1
2018-03-23 15:02



这并没有增加太多;接受的答案涵盖了2001年背后的逻辑。当您有50个代表时,如果要在现有答案中添加限定符,请使用注释。 - Andrew B


还有一个选项:由于持续创建数据的进程,磁盘可能已满:日志,核心等。实际上空间可能被释放但是立即被填满。我实际上看到过这样的情况。 df 在这种情况下,根本不给出孔图。使用 du 了解更多。


0
2017-07-17 12:01





我正在使用EXT2,FSCK在这种情况下帮助了我。试试shudown -F现在,经过一些重新启动和fscks后,我看到了一半的空间。


0
2018-01-16 09:00



亲爱的马塞勒斯,您的解决方案包含在已接受的答案中;如果你不被迫......有时你不想重启 - Deer Hunter


要检查哪些已删除的文件已占用内存,请输入命令

 $ sudo lsof | grep deleted

它将显示保存内存的已删除文件。

然后使用pid或名称终止进程

$ sudo kill <pid>
$ df -h

现在检查你将拥有相同的记忆

如果不是,请键入以下命令以查看占用内存的文件

# cd /
# du --threshold=(SIZE)

提及任何大小,它将显示哪些文件占用超过阈值大小并删除文件,您将找到保留的内存


-1
2018-03-06 07:16