Как восстановить свободное место на удаленных файлах без перезапуска ссылочных процессов?

11

Когда большие файлы удаляются на сервере, процессы могут ссылаться на файлы, поэтому файловая система не имеет больше свободного места.

Я пытался использовать 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

Иногда случается, что файл удаляется приложением или пользователем, например, файлом журнала, и на этот файл все еще ссылается процесс, который не может быть перезапущен.

Существуют ли методы товаров для восстановления дискового пространства в удаленных файлах без перезапуска процесса, который имеет ссылку на этот удаленный файл?

Ujjain
источник
для справки ... лучший способ удалить открытый файл - скопировать в него файл / dev / nullcp /dev/null file
Майк
@Mike cp /dev/null- пустая команда, так как ей cpнечего копировать, простое перенаправление строго эквивалентно :>fileили даже>file
jlliagre

Ответы:

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

Найти все открытые файловые дескрипторы.

Grep удален.

StdError to / 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 '/ Удалено / {печать $ 11}';

вывод awk (протестирован в bash Ubuntu 12.04):

/proc/28680/fd/113

Найти и обрезать все удаленные файлы (протестировано в bash Ubuntu 12.04):

(НЕ ДЕЛАЙТЕ ЭТОГО, ЕСЛИ ВЫ НЕ ЗНАЕТЕ, ЧТО ВЫ ДЕЛАЕТЕ)

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

-p запрос перед выполнением усечения

Лучший способ - усечение вручную

Ручное усечение:

: > /proc/28680/fd/113

или же:

> /proc/28680/fd/113

или же:

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

Наслаждаться ;)

user3439968
источник
+1, но я также требовал sudo для запуска этих команд
79E09796
6

Вот простой пример с less:

Давайте предположим, что у нас есть файл 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% /

Это все еще там, но удалено. Посмотрите на 4-й столбец вывода lsof: дескриптор файла № 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% /

Наши 10 МБ приветствуются :)

$ ls /proc/29351/fd
0  1  2  3

$ ps 29351
29351 pts/0    S+     0:00 less /tmp/my10MBfile

Процесс все еще работает.

maxxvw
источник
2
Хорошо, но как долго? многие процессы просто завершаются, если они не могут записать в свой файл журнала.
longneck
Logrotate не может сделать это для вас?
maxxvw
logrotate отправляет процессу сигнал, чтобы закрыть файл журнала и открыть новый.
longneck
2

Эта команда покажет все удаленные файлы, все еще открытые в системе Solaris:

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

Вы можете обрезать те, которые вы уверены, что вы хотите с этой командой:

:> /proc/p/fd/x

где p - идентификатор процесса, а x - дескриптор файла, возвращаемый первой командой.

Не беспокойтесь, если в некоторых программах размер, о котором сообщается, через некоторое время lsвосстанавливается до размера перед усечением, фактический размер, используемый на диске, будет намного меньше, поскольку файл теперь является разреженным.

jlliagre
источник
0

Вы можете попытаться перейти в /proc/<pid>/fdкаталог и обрезать соответствующий файловый дескриптор. Допустим, fd = 3 балла к удаленному файлу pid == 123:

# echo "" >! /proc/123/fd/3
kofemann
источник
у вас есть пример, где этот метод работает? Не могу найти способ изменить FD оттуда
maxxvw
Да, это работает, но как найти pid процесса?
Ujjain
-2

Ни одно из этих решений не помогло мне. Только после использования Bleachbit в качестве пользователя root я смог правильно освободить пространство, связанное с удаленными файлами.

user189721
источник