Como liberar o uso de inode?

275

Eu tenho uma unidade de disco em que o uso do inode é 100% (usando o df -icomando). No entanto, após a exclusão substancial de arquivos, o uso permanece 100%.

Qual é a maneira correta de fazer isso?

Como é possível que uma unidade de disco com menos uso de espaço em disco possa ter maior uso de Inode do que uma unidade de disco com maior uso de espaço em disco?

É possível se eu compactar muitos arquivos que reduziriam a contagem de inodes usados?

neversaint
fonte
4
Deseja dar 50 pontos para esta pergunta. Como eu posso fazer! :)
Sophy
@ Sophy Não faça isso. você será banido automaticamente
Steven Lu
1
@StevenLu Obrigado por suas informações! Quero dar crédito a ele porque passei alguns dias para resolver meu problema. Mas esse problema pode me ajudar. Obrigado novamente, #
Sophy
1
@Sophy: por que premiar algo fora do tópico para SO? :) Definitivamente, essa não é uma questão de programação, não importa quantas votações recebam.
tink
Diretórios vazios também consomem inodes. Excluí-los pode liberar alguns inodes. O número pode ser significativo em alguns casos de uso. Você pode excluir diretórios vazios com: find. -type d -empty -delete
Ruchit Patel

Respostas:

170

É muito fácil para um disco usar um grande número de inodes, mesmo que o disco não esteja muito cheio.

Um inode é alocado para um arquivo, portanto, se você tiver zilhões de arquivos, todos com 1 byte cada, ficará sem inodes muito antes de ficar sem disco.

Também é possível que a exclusão de arquivos não reduza a contagem de inodes se os arquivos tiverem vários links físicos. Como eu disse, os inodes pertencem ao arquivo, não à entrada do diretório. Se um arquivo tiver duas entradas de diretório vinculadas, a exclusão de uma não liberará o inode.

Além disso, você pode excluir uma entrada de diretório, mas, se um processo em execução ainda tiver o arquivo aberto, o inode não será liberado.

Meu conselho inicial seria excluir todos os arquivos que você puder e, em seguida, reinicie a caixa para garantir que nenhum processo seja deixado mantendo os arquivos abertos.

Se você fizer isso e ainda tiver um problema, informe-nos.

A propósito, se você estiver procurando os diretórios que contêm muitos arquivos, este script pode ajudar:

#!/bin/bash
# count_em - count files in all subdirectories under current directory.
echo 'echo $(ls -a "$1" | wc -l) $1' >/tmp/count_em_$$
chmod 700 /tmp/count_em_$$
find . -mount -type d -print0 | xargs -0 -n1 /tmp/count_em_$$ | sort -n
rm -f /tmp/count_em_$$
paxdiablo
fonte
12
Obviamente, >/tmp/count_em_$$isso só funcionará se você tiver espaço para isso ... se for esse o caso, veja a resposta do @ simon.
alxndr
1
@alxndr, é por isso que geralmente é uma boa ideia manter seus sistemas de arquivos separados - dessa forma, preencher algo como /tmpisso não afetará seus outros sistemas de arquivos.
precisa
Sua resposta é perfeitamente adequada para "o sistema não permanecerá usando o arquivo após a reinicialização, se ele foi excluído". Mas a pergunta foi feita "como recuperar ou reutilizar os inodes após o ponteiro do inode ser excluído?". Basicamente, o kernel do linux cria um novo inode para um arquivo sempre que criado, e também não recupera automaticamente o inode sempre que você excluir um arquivo.
precisa saber é o seguinte
1
@AshishKarpe, eu assumo que você está falando sobre o seu próprio situação, já que o OP não fez menção a servidores de produção. Se você não pode reiniciar imediatamente, existem duas possibilidades. Primeiro, espere que os processos em andamento fechem os arquivos atuais para que os recursos do disco possam ser liberados. Segundo, até os servidores de produção devem ter espaço para reinicialização em algum momento - basta agendar algum tempo de inatividade planejado ou aguardar a próxima janela de tempo de inatividade.
22416
2
Suponho que você queira em ls -Avez de ls -a. Por que você quer contar? e ..?
jarno
205

Se você é muito azarado, usou cerca de 100% de todos os inodes e não pode criar o scipt. Você pode verificar isso com df -ih.

Então este comando bash pode ajudá-lo:

sudo find . -xdev -type f | cut -d "/" -f 2 | sort | uniq -c | sort -n

E sim, isso levará tempo, mas você pode localizar o diretório com mais arquivos.

simon
fonte
8
isso faz o truque. meu problema era ter uma quantidade incrível de sessões no diretório / lib / php / sessions. talvez alguém tem o mesmo problema
stema
2
Alguém deve reescrever esse tipo de localização, corte e uniq em um único comando awk!
Mogie15 /
5
O @alxndr awkpode manter um hash do diretório e a contagem de arquivos sem uniqing e ordenando um zilhão de linhas. Dito isto, talvez aqui esteja uma melhoria: find . -maxdepth 1 -type d | grep -v '^\.$' | xargs -n 1 -i{} find {} -xdev -type f | cut -d "/" -f 2 | uniq -c | sort -n- isso apenas classifica a última lista.
mogsie
12
Se você não pode criar nenhum arquivo, mesmo isso pode falhar, pois sortpode não manter tudo na memória e tentará voltar automaticamente à gravação de um arquivo temporário. Um processo que, obviamente, não conseguem ...
Mikko Rantalainen
10
sortfalhou para mim, mas eu era capaz de dar o --buffer-size=10Gque funcionou.
Frederick Nord
69

Minha situação era que eu estava sem inodes e já havia excluído tudo o que podia.

$ df -i
Filesystem     Inodes  IUsed  IFree IUse% Mounted on
/dev/sda1      942080 507361     11  100% /

Estou em um ubuntu 12.04LTS e não foi possível remover os antigos kernels do linux, que ocupavam cerca de 400.000 inodes porque o apt foi quebrado por causa de um pacote ausente. E não consegui instalar o novo pacote porque estava sem inodes, por isso fiquei preso.

Acabei excluindo alguns kernels Linux antigos manualmente para liberar cerca de 10.000 inodes

$ sudo rm -rf /usr/src/linux-headers-3.2.0-2*

Isso foi o suficiente para, então, deixar-me instalar o pacote que faltava e corrigir meu apt

$ sudo apt-get install linux-headers-3.2.0-76-generic-pae

e remova o restante dos antigos kernel do linux com o apt

$ sudo apt-get autoremove

as coisas estão muito melhores agora

$ df -i
Filesystem     Inodes  IUsed  IFree IUse% Mounted on
/dev/sda1      942080 507361 434719   54% /
LNamba
fonte
3
Este foi o mais próximo da minha própria abordagem em uma situação semelhante. É importante notar que uma abordagem mais cautelosa está bem documentado na help.ubuntu.com/community/Lubuntu/Documentation/...
beldaz
Meu caso exatamente! Mas tive que usar "sudo apt-get autoremove -f" para o progresso
Tony Sépia
É seguro fazer isso:, sudo rm -rf /usr/src/linux-headers-3.2.0-2*se tiver certeza de que não estou usando esse kernel?
Mars Lee
@MarsLee Você pode verificar qual kernel está sendo executado com "uname -a"
Dominique Eav
Ligar $ sudo apt-get autoremovesozinho, fez o truque para mim.
Morten Grum
49

Minha solução:

Tente descobrir se este é um problema de inodes com:

df -ih

Tente encontrar pastas raiz com grande número de inodes:

for i in /*; do echo $i; find $i |wc -l; done

Tente encontrar pastas específicas:

for i in /src/*; do echo $i; find $i |wc -l; done

Se esse for o cabeçalho do linux, tente remover o mais antigo com:

sudo apt-get autoremove linux-headers-3.13.0-24

Pessoalmente, mudei-os para uma pasta montada (porque para mim o último comando falhou) e instalei o mais recente com:

sudo apt-get autoremove -f

Isso resolveu meu problema.

dardarlt
fonte
1
No meu caso, a questão era SpamAssasin-Temp. find /var/spool/MailScanner/incoming/SpamAssassin-Temp -mtime +1 -print | xargs rm -ffez o trabalho :) Obrigado!
joystick
4
Para mim, isso estava levando horas. No entanto, existe uma solução simples: quando o segundo comando travar em um diretório específico, mate o comando atual e reinicie a alteração / * para qualquer diretório em que ele estivesse pendurado. Eu fui capaz de detalhar o culpado <minuto.
Michael Terry
Eu usei essa variante do seu comando para imprimir os números na mesma linha: for i in /usr/src/*; do echo -en "$i\t"; find $i 2>/dev/null |wc -l; done
cscracker
for i in /src/*; do echo "$i, `find $i |wc -l`"; done|sort -nrk 2|head -10mostrar os 10 maiores diretórios
Mark Simon
12

Eu tive o mesmo problema, corrigi-o removendo as sessões de diretório do php

rm -rf /var/lib/php/sessions/

Pode estar sob /var/lib/php5 se você estiver usando uma versão php mais antiga.

Recrie-o com a seguinte permissão

mkdir /var/lib/php/sessions/ && chmod 1733 /var/lib/php/sessions/

A permissão por padrão para o diretório no Debian foi mostrada drwx-wx-wt(1733)

Anyone_ph
fonte
1
Alguma idéia de por que isso acontece?
Sibidharan
1
@ Sibidharan no meu caso, foi porque o trabalho cron do PHP para limpar as sessões antigas do PHP não estava funcionando.
sombrio
3
rm -rf /var/lib/php/sessions/*provavelmente seria um comando melhor - ele não removerá o diretório da sessão, apenas seu conteúdo ... Então você não precisa se preocupar em recriá-lo.
Shadow
Eu não tive sessão php, mas problema de sessão magento, semelhante a este. Obrigado pela direção.
Mohit
sessões PHP não deve limpar via cron empregos, conjunto session.gc_maxlifetime no php.ini php.net/manual/en/...
2

Experimentamos isso em uma conta HostGator (que impõe limites de inode a toda a hospedagem) após um ataque de spam. Ele deixou um grande número de registros de fila em /root/.cpanel/comet. Se isso acontecer e você achar que não possui inodes gratuitos, poderá executar este utilitário cpanel através do shell:

/usr/local/cpanel/bin/purge_dead_comet_files
designgroop
fonte
2

Você pode usar o RSYNC para excluir o grande número de arquivos

rsync -a --delete blanktest/ test/

Crie uma pasta blanktest com 0 arquivos e o comando sincronizará suas pastas de teste com um grande número de arquivos (eu excluí quase 5 milhões de arquivos usando este método).

Obrigado a http://www.slashroot.in/which-is-the-fastest-method-to-delete-files-in-linux

VIGNESH
fonte
Pelo que sei do artigo / comentários, isso é mais rápido do que rm *para muitos arquivos, devido à expansão do curinga e à passagem / processamento de cada argumento, mas rm test/é bom para excluir uma test/pasta que contém muitos arquivos.
Mkfearnley
Atenção, isso funciona bem, mas certifique-se de definir as permissões corretamente no diretório em branco! Não fiz isso e alterei inadvertidamente as permissões no meu diretório de sessões PHP. Demorei duas horas para descobrir o que eu estraguei.
aecend 21/02
1

O eaccelerator pode estar causando o problema, pois compila o PHP em blocos ... Eu tive esse problema com um servidor Amazon AWS em um site com carga pesada. Libere os inodes excluindo o cache do eaccelerator em / var / cache / eaccelerator se você continuar com problemas.

rm -rf /var/cache/eaccelerator/*

(ou qualquer que seja o diretório do cache)

supershwa
fonte
1

Enfrentamos um problema semelhante recentemente. Caso um processo se refira a um arquivo excluído, o Inode não será liberado; portanto, você deve verificar lsof / e interromper / reiniciar o processo liberará os inodes.

Corrija-me se estiver errado aqui.

Razal
fonte
1

Como dito anteriormente, o sistema de arquivos pode ficar sem inodes, se houver muitos arquivos pequenos. Forneci alguns meios para encontrar diretórios que contêm a maioria dos arquivos aqui .

jarno
fonte
0

Resposta tardia: no meu caso, eram meus arquivos de sessão em

/var/lib/php/sessions

que estavam usando inodes.
Eu até consegui abrir o meu crontab ou criar um novo diretório e muito menos acionar a operação de exclusão. Como uso o PHP, temos este guia onde copiei o código do exemplo 1 e configurei um cronjob para executar essa parte do código.

<?php
// Note: This script should be executed by the same user of web server 
process.

// Need active session to initialize session data storage access.
session_start();

// Executes GC immediately
session_gc();

// Clean up session ID created by session_gc()
session_destroy();
?>

Se você está se perguntando como eu consegui abrir meu crontab, então excluí algumas sessões manualmente através da CLI.

Espero que isto ajude!

Han
fonte
0

você pode ver esta informação

for i in /var/run/*;do echo -n "$i "; find $i| wc -l;done | column -t
张馆长
fonte
-2

Muitas respostas até agora e todas as opções acima parecem concretas. Eu acho que você estará seguro usando à statmedida que avança, mas dependendo do SO, você pode receber alguns erros de inode. Portanto, implementar sua própria statfuncionalidade de chamada 64bitpara evitar problemas de estouro parece bastante compatível.

kinokaf
fonte
nós amamos exemplos aqui no tão;)
Bohne
-3

Se você usar a janela de encaixe, remova todas as imagens. Eles usaram muito espaço ....

Pare todos os contêineres

docker stop $(docker ps -a -q)

Excluir todos os contêineres

docker rm $(docker ps -a -q)

Excluir todas as imagens

docker rmi $(docker images -q)

Trabalha para mim

Pankaj Shinde
fonte
Isso não ajuda a detectar se "muitos inodes" são o problema.
Mark Stosberg 13/06/19
Isso não tem nada a ver com o Docker.
Urda