A melhor maneira de liberar espaço em disco dos arquivos excluídos mantidos abertos

28

Olá, tenho muitos arquivos que foram excluídos, mas, por algum motivo, o espaço em disco associado aos arquivos excluídos não pode ser utilizado até que eu explique explicitamente o processo do arquivo que ocupa o espaço em disco

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

O espaço em disco ocupado pelo arquivo excluído acima causa problemas, como ao tentar usar a tecla tab para preencher automaticamente um caminho de arquivo. Eu recebo o erro bash: cannot create temp file for here-document: No space left on device

Mas depois que eu executo kill -9 1623o espaço para esse PID é liberado e não recebo mais o erro.

Minhas perguntas são:

  • por que esse espaço não é liberado imediatamente quando o arquivo é excluído pela primeira vez?
  • qual é a melhor maneira de recuperar o espaço no arquivo associado aos arquivos excluídos?

e informe-me de qualquer terminologia incorreta que usei ou de qualquer outra informação relevante e pertinente sobre essa situação.

BryanK
fonte

Respostas:

26

Nos unices, os nomes de arquivos são apenas ponteiros (inodes) que apontam para a memória em que o arquivo reside (que pode ser um disco rígido ou mesmo um sistema de arquivos suportado por RAM). Cada arquivo registra o número de links para ele: os links podem ser o nome do arquivo (plural, se houver vários links físicos para o mesmo arquivo) e também sempre que um arquivo é aberto, o processo mantém o "link" para o mesmo espaço.

O espaço é liberado fisicamente somente se não houver mais links (portanto, é impossível acessá-lo). Essa é a única opção sensata: enquanto o arquivo está sendo usado, não é importante se alguém não puder mais acessá-lo: você o está usando e até fechá-lo, você ainda tem controle sobre ele - você nem notará o nome do arquivo se foi ou mudou-se ou o que quer. Isso é usado até para arquivos temporários: algumas implementações criam um arquivo e o desvinculam imediatamente, para que não seja visível no sistema de arquivos, mas o processo que o criou está usando normalmente. O plug-in Flash gosta especialmente desse método: todos os arquivos de vídeo baixados são mantidos abertos, mas o sistema de arquivos não os mostra.

Portanto, a resposta é que, enquanto os processos ainda têm os arquivos abertos, você não deve esperar recuperar o espaço. Não é liberado, está sendo usado ativamente. Esse também é um dos motivos pelos quais os aplicativos devem realmente fechar os arquivos quando terminarem de usá-los. No uso normal, você não deve pensar nesse espaço como livre, e isso também não deve ser muito comum - com exceção dos arquivos temporários que são desvinculados de propósito, não deve haver realmente nenhum arquivo que você desejaria. considere não ser usado, mas ainda aberto. Tente revisar se existe um processo que faça muito isso e considere como você o usa, ou apenas encontre mais espaço.

orion
fonte
24

Os arquivos são excluídos do sistema de arquivos, onde é excluída qualquer referência a este inode. A referência pode estar no disco (link em qualquer diretório) e .. de aplicativos abertos. Se você remover o arquivo - você excluirá apenas a referência do disco, mas - ainda haverá referência do aplicativo.

Você pode "liberar" espaço de duas maneiras:

  1. como mencionado acima - você pode matar o aplicativo, que abre o arquivo.
  2. você pode ... truncar arquivo. Mesmo se for excluído:

Se você conhece pid - veja quais arquivos estão abertos por este pid: ls -l / proc / PID / fd, você vê aqui links como:

undefine @ uml: ~ $ ls -l / proc / 18596 / fd
razem 0
lrwx ------ 1 undefine undefine 64 lut 1 00:06 0 -> / dev / pts / 30
lrwx ------ 1 undefine undefine 64 lut 1 00:06 1 -> / dev / pts / 30
lrwx ------ 1 undefine undefine 64 lut 1 00:05 2 -> / dev / pts / 30
lr-x ------ 1 undefine undefine 64 lut 1 00:06 3 -> / home / undefine / x (excluído)
lr-x ------ 1 undefine undefine 64 lut 1 00:06 4 -> anon_inode: inotify

Como você vê - 3 fd é excluído. você pode truncá-lo por comando (por exemplo):

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

Lembre-se de que, se o aplicativo ler este arquivo - poderá ser perigoso para eles. Mas - se for apenas um arquivo de log - você pode truncá-lo com segurança.

indefinir
fonte
observe que, após truncar o arquivo, o processo original que o mantém ainda pode ser anexado ao final (onde espera o final). o resultado são arquivos aparentemente enormes, mas esparsos, que ocupam menos espaço no disco (se o sistema de arquivos suportar arquivos esparsos) e ainda continuam crescendo!
törzsmókus
sim. Se algo gravar no arquivo, ocorrerá no disco. É difícil evitá-lo sem interromper o aplicativo que grava no disco;)
undefine
8

Como outros já disseram, lsofpode ser usado para listar todos os arquivos excluídos que ainda estão no disco devido aos descritores de arquivos abertos. No entanto, essa pode ser uma lista muito longa. Aqui está um comando que lista esses arquivos classificados por tamanho crescente em bytes:

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

Pode haver uma maneira mais sucinta de fazer isso, mas o comando acima funcionou para mim.

jcoffland
fonte
5

O espaço não é liberado imediatamente porque o processo em execução ainda possui um identificador de arquivo aberto para o arquivo recém-excluído. Afinal, se um processo ainda está tentando usar um arquivo, você provavelmente não quer que o kernel se livre dele (o arquivo). Isso pode tornar o processo um pouco chateado. A melhor (e única, até onde eu sei) maneira de liberar espaço é fazer exatamente o que você fez - matar o processo.

John
fonte
Provavelmente, uma frase melhor do que "exatamente como funciona" é "se um processo ainda estiver usando um arquivo que o Unix não deve tentar se livrar dele".
Bratchley
Bom ponto. Eu adicionei isso à resposta.
John
-1

(Casa da moeda 17.1)

TL; DR:

  • Inspecione com sudo baobab(Disk Usage Analyzer).
  • Limpar roota lixeira do usuário.

Contexto

Fiquei preso com o espaço cada vez menor enquanto excluía constantemente os arquivos. Instalei o trash-clipacote para esvaziar o lixo, mas isso não ajudou. Por fim, notei que, quando executei baobab(Disk Usage Analyzer na GUI, pelo menos no Mint 17.1) para inspecionar a estrutura do espaço em disco, ele avisou que algumas pastas não estavam acessíveis. Então eu executei como rootusando sudo baobab. Isso revelou o problema. Muitos arquivos que foram excluídos estavam na lixeira do rootusuário, não no meu próprio usuário. Assim, não pude liberar o espaço. Simplesmente esvaziei o lixo usando como root ( sudo trash-cli) e todo o meu espaço retornou.

Deleet
fonte
-1

Tente usar o comando abaixo

lsof | grep deleted

e depois mate o pid do arquivo excluído.

Sumit Tyagi
fonte
O OP chegou tão longe; isso não responde às perguntas deles.
Jeff Schaller