Como recupero espaço livre em arquivos excluídos sem reiniciar os processos de referência?

11

Quando arquivos grandes são excluídos em um servidor, os arquivos ainda podem ser referenciados por processos, para que o sistema de arquivos não tenha mais espaço livre.

Tentei usar o lsof , mas parece que não listou os arquivos excluídos. fuser -cfuncionou melhor, mas a lista de processos é longa demais para verificá-la para cada processo, especialmente porque cada processo é um processo 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

Às vezes, um arquivo é excluído por um aplicativo ou usuário, por exemplo, um arquivo de log e esse arquivo ainda está sendo referenciado por um processo que não pode ser reiniciado.

Existem métodos de mercadorias para recuperar espaço em disco nos arquivos excluídos sem reiniciar o processo que tem uma referência a esse arquivo excluído?

ujjain
fonte
para referência .. a melhor maneira de excluir um arquivo aberto é copiar / dev / null no arquivocp /dev/null file
Mike
@ Mike cp /dev/nullé um comando nulo como cpnão tem nada a cópia, um redirecionamento simples é estritamente equivalente :>fileou mesmo>file
jlliagre

Respostas:

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

Encontre todos os descritores de arquivos abertos.

Grep excluído.

StdError para / dev / null

Resultado:

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

Ou você pode usar o awk

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

Saída awk (testada no bash Ubuntu 12.04):

/proc/28680/fd/113

Encontre e trunque todos os arquivos excluídos (testados no bash Ubuntu 12.04):

(NÃO FAÇA ISSO SE NÃO SABE O QUE FAZ)

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

-p prompt antes de executar truncado

Melhor maneira é truncar manualmente

Truncar manual:

: > /proc/28680/fd/113

ou:

> /proc/28680/fd/113

ou:

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

Desfrutar ;)

user3439968
fonte
+1, mas eu também necessário sudo para executar estes comandos
79E09796
6

Aqui está um exemplo simples com less:

Vamos supor que temos um arquivo 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% /

Agora abro esse arquivo com less(sim, é um arquivo binário ... não importa)

$ less /tmp/my10MBfile &

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

Então eu removo esse arquivo

$ 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% /

Ainda está lá, mas foi excluído. Observe a quarta coluna da saída lsof: Descritor de arquivo número 4 aberto para Reading (4r)

Vamos rodar o GDB!

$ gdb -p $(pidof less)

GNU gdb (GDB) 7.4.1-debian
....
Attaching to process 29351
....

(gdb) p close(4)
$1 = 0
(gdb) q

É isso aí!

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

Nossos 10 MB são bem-vindos de volta :)

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

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

O processo ainda está em execução.

maxxvw
fonte
2
Ok, mas por quanto tempo? muitos processos simplesmente saem se não puderem gravar no arquivo de log.
longneck
Logrotate não pode fazer isso por você?
maxxvw
logrotate envia ao processo um sinal para fechar o arquivo de log e abrir um novo.
longneck
2

Este comando mostrará todos os arquivos excluídos ainda abertos em um sistema Solaris:

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

Você pode truncar os que você tem certeza que deseja com este comando:

:> /proc/p/fd/x

sendo p o ID do processo e x o descritor de arquivo retornado pelo primeiro comando.

Não se preocupe se, em alguns programas, o tamanho reportado por lsfor restaurado para o tamanho anterior ao truncamento após algum tempo, o tamanho real usado no disco será muito menor, pois o arquivo agora é escasso.

jlliagre
fonte
0

Você pode tentar ir para o /proc/<pid>/fddiretório e o descritor de arquivo correspondente truncado. Digamos que fd = 3 pontos para o arquivo excluído do pid == 123:

# echo "" >! /proc/123/fd/3
Kofemann
fonte
você tem um exemplo em que esse método funciona? Não consegue encontrar uma maneira de alterar FD de lá
maxxvw
Sim, isso funciona, mas como encontrar o pid do processo?
Ujjain
-2

Nenhuma dessas soluções funcionou para mim. Somente depois de usar o Bleachbit como root, consegui liberar adequadamente o espaço associado aos arquivos excluídos.

user189721
fonte