如何恢复已删除文件的可用空间而不重新启动引用过程?

在服务器上删除大文件时,文件仍可能被进程引用,因此文件系统没有更多的可用空间。

我试图使用lsof,但似乎没有列出删除的文件。 Fuser -c做得好,但是进程列表太长,无法检查每个进程,特别是因为每个进程都是Oracle进程。

bash-3.2# fuser -c /var /var: 105o 29999o 20444c 3528c 27258o 7715o 3864o 3862o 2494o 18205o 17450co 17445co 14912co 14824co 14818co 14816o 14814o 8532c 8530c 7633com 7118o 6958o 6790c 6784co 6734o 6693o 6689o 6684o 6675o 6635o 6594c 6548o 6547o 6546o 6545o 6544o 6543o 6542o 6541o 6540o 6537o 6535o 6456o 6128co 6113o 335o 245co 229o 161o 8o bash-3.2# du -hs /proc 139T /proc 

有时会发生文件被应用程序或用户删除,例如日志文件,并且该文件仍然被无法重新启动的进程引用。

有没有商品的方法来回收删除的文件的磁盘空间,而不重新启动有这个删除文件的引用的过程?

 find /proc/*/fd -ls 2> /dev/null | grep '(deleted)' 

find所有打开的文件描述符。

Grep删除。

将StdError设置为/ dev / null

输出:

 160448715 0 lrwx------ 1 user user 64 Nov 29 15:34 /proc/28680/fd/113 -> /tmp/vteT3FWPX\ (deleted) 

或者你可以使用awk

find / proc / * / fd -ls 2> / dev / null | awk'/ deleted / {print $ 11}';

awk输出(在bash Ubuntu 12.04中testing):

 /proc/28680/fd/113 

查找和截断所有删除的文件(在bash Ubuntu 12.04中testing):

(不要这样做,如果你不知道你做什么)

 find /proc/*/fd -ls 2> /dev/null | awk '/deleted/ {print $11}' | xargs -p -n 1 truncate -s 0 

-p在执行truncate之前提示

更好的方法是手动截断

手动截断:

 : > /proc/28680/fd/113 

要么:

 > /proc/28680/fd/113 

要么:

 truncate -s 0 /proc/28680/fd/113 

请享用 ;)

下面是一个简单的例子:

假设我们有一个文件my10MBfile

 $ dd if=/dev/zero of=/tmp/my10MBfile bs=1M count=10 10+0 enregistrements lus 10+0 enregistrements écrits 10485760 octets (10 MB) copiés, 0,0454491 s, 231 MB/s $ ls -l /tmp/my10MBfile -rw-r--r-- 1 max max 10485760 avril 23 22:49 /tmp/my10MBfile $ df -m /tmp /dev/disk/by-uuid/6835b2fd-971d-420c-ba18-3c729ec2e8a0 14637 9225 4662 67% / 

现在我打开文件less(是的,这是一个二进制文件…不要害怕)

 $ less /tmp/my10MBfile & $ lsof -p $(pidof less) | grep 10MBfile less 29351 max 4r REG 8,3 10485760 521464 /tmp/my10MBfile 

然后我删除该文件

 $ rm /tmp/my10MBfile $ lsof -p $(pidof less) | grep 10MBfile less 29351 max 4r REG 8,3 10485760 521464 /tmp/my10MBfile (deleted) $ df -m /tmp /dev/disk/by-uuid/6835b2fd-971d-420c-ba18-3c729ec2e8a0 14637 9225 4662 67% / 

仍然存在,但删除,看看lsof输出的第4列:文件描述符号4打开阅读(4r)

让我们来运行GDB!

 $ gdb -p $(pidof less) GNU gdb (GDB) 7.4.1-debian .... Attaching to process 29351 .... (gdb) p close(4) $1 = 0 (gdb) q 

而已!

 $ df -m /tmp /dev/disk/by-uuid/6835b2fd-971d-420c-ba18-3c729ec2e8a0 14637 9215 4672 67% / 

我们的10MB欢迎回来:)

 $ ls /proc/29351/fd 0 1 2 3 $ ps 29351 29351 pts/0 S+ 0:00 less /tmp/my10MBfile 

进程仍在运行。

该命令将显示在Solaris系统上仍然打开的所有被删除的文件:

 find /proc/*/fd -type f -links 0 

您可以使用以下命令截断您确定需要的那些:

 :> /proc/p/fd/x 

其中p是进程ID,x是第一个命令返回的文件描述符。

不用担心,如果某些程序将由ls报告的大小恢复到截断之前的大小,磁盘上使用的实际大小将会变得更小,因为文件现在是稀疏的。

您可以尝试去/ proc // fd目录和截断相应的文件描述符。 假设fd = 3分给pid删除的文件== 123:

 # echo "" >! /proc/123/fd/3