Encontre onde inodes estão sendo usados

178

Então eu recebi um aviso do nosso sistema de monitoramento em uma de nossas caixas de que o número de inodes livres em um sistema de arquivos estava ficando baixo.

df -i output mostra isso:

Filesystem       Inodes  IUsed    IFree IUse% Mounted on
/dev/xvda1       524288 422613   101675   81% /

Como você pode ver, a partição raiz tem 81% de seus inodes usados. Eu suspeito que todos eles estão sendo usados em um único diretório. Mas como posso encontrar onde isso está?

    
por Patrick 26.02.2014 / 18:55

7 respostas

210

Eu vi esta pergunta sobre o stackoverflow, mas eu não gostei de nenhuma das respostas, e é realmente uma questão que deve estar aqui no U & L de qualquer maneira.

Basicamente, um inode é usado para cada arquivo no sistema de arquivos. Então, ficar sem inodes geralmente significa que você tem muitos arquivos pequenos por aí. Então a questão realmente se torna "qual diretório possui um grande número de arquivos?"

Neste caso, o sistema de arquivos que nos interessa é o sistema de arquivos raiz / , então podemos usar o seguinte comando:

find / -xdev -printf '%h\n' | sort | uniq -c | sort -k 1 -n

Isto irá mostrar uma lista de todos os diretórios no sistema de arquivos prefixados com o número de arquivos (e subdiretórios) naquele diretório. Assim, o diretório com o maior número de arquivos estará na parte inferior.

No meu caso, isso é o seguinte:

   1202 /usr/share/man/man1
   2714 /usr/share/man/man3
   2826 /var/lib/dpkg/info
 306588 /var/spool/postfix/maildrop

Então, basicamente /var/spool/postfix/maildrop está consumindo todos os inodes.

Note que esta resposta tem três advertências que eu posso pensar. Ele não manipula adequadamente nada com novas linhas no caminho. Eu sei que meu sistema de arquivos não tem arquivos com novas linhas, e como isso só está sendo usado para consumo humano, o problema em potencial não vale a pena ser resolvido (e sempre é possível substituir o \n por sort -z e usar -xdev acima) . Ele também não manipula se os arquivos estão espalhados entre um grande número de diretórios. Isso não é provável, então considero o risco aceitável. Ele também contará hard links para um mesmo arquivo (usando apenas um inode) várias vezes. Mais uma vez, é improvável que dê falsos positivos

A principal razão pela qual eu não gostei de nenhuma das respostas na resposta do stackoverflow é que elas cruzam todos os limites do sistema de arquivos. Como o meu problema estava no sistema de arquivos raiz, isso significa que ele atravessaria todos os sistemas de arquivos montados. Lançar /mnt/foo nos comandos find nem funcionaria corretamente.
Por exemplo, a resposta mais votada é esta:

for i in 'find . -type d '; do echo 'ls -a $i | wc -l' $i; done | sort -n

Se mudarmos isso para

for i in 'find . -xdev -type d '; do echo 'ls -a $i | wc -l' $i; done | sort -n

mesmo que find . -mount -type d seja uma montagem, ela também é um diretório no sistema de arquivos raiz, então ela aparecerá em ls -a $i e, em seguida, será transmitida para o find , que será analisado o monte.

O %code% na minha resposta lista o diretório de cada arquivo na montagem. Então basicamente com uma estrutura de arquivos como:

/foo/bar
/foo/baz
/pop/tart

terminamos com

/foo
/foo
/pop

Então, só precisamos contar o número de linhas duplicadas.

    
por 26.02.2014 / 18:55
21

Isso é republicado de aqui a pedido do solicitante:

du --inodes -S | sort -rh | sed -n \
        '1,50{/^.\{71\}/s/^\(.\{30\}\).*\(.\{37\}\)$/.../;p}'

E se você quiser ficar no mesmo sistema de arquivos que você:

du --inodes -xS

Veja alguns exemplos de saída:

15K     /usr/share/man/man3
4.0K    /usr/lib
3.6K    /usr/bin
2.4K    /usr/share/man/man1
1.9K    /usr/share/fonts/75dpi
...
519     /usr/lib/python2.7/site-packages/bzrlib
516     /usr/include/KDE
498     /usr/include/qt/QtCore
487     /usr/lib/modules/3.13.6-2-MANJARO/build/include/config
484     /usr/src/linux-3.12.14-2-MANJARO/include/config

AGORA COM LS:

Várias pessoas mencionaram que não têm coreutils atualizados e a opção --inodes não está disponível para eles. Então, aqui está o ls:

ls ~/test -AiR1U | 
sed -rn '/^[./]/{h;n;};G;
    s|^ *([0-9][0-9]*)[^0-9][^/]*([~./].*):|:|p' | 
sort -t : -uk1.1,1n |
cut -d: -f2 | sort -V |
uniq -c |sort -rn | head -n10

Se você está curioso, o coração e a alma desse bocado tedioso de regex está substituindo os filename em cada um dos resultados da pesquisa recursiva ls's pelo nome do diretório em que foi encontrado. A partir daí, é apenas uma questão de apertar números repetidos de inode, contando nomes de diretórios repetidos e classificando-os de acordo.

A opção -U é especialmente útil com a classificação em que ela faz não classificar e, em vez disso, apresenta a lista de diretórios na ordem original - ou, em outras palavras, inode number .

E é claro que -1 é incrivelmente útil na medida em que garante um único resultado por linha, independentemente de novas linhas possivelmente incluídas em nomes de arquivos ou outros problemas espetacularmente infelizes que podem ocorrer quando você tenta analisar uma lista.

E, é claro, -A para todos e -i para inode e -R para recursivos, e esse é o longo e o menor deles.

O método subjacente para isso é que eu substituo todos os nomes de arquivos de ls pelo seu nome de diretório contendo em sed. Na sequência disso ... Bem, eu sou um pouco confuso mesmo. Tenho certeza de que está contando os arquivos com precisão, como você pode ver aqui:

% _ls_i ~/test
> 100 /home/mikeserv/test/realdir
>   2 /home/mikeserv/test
>   1 /home/mikeserv/test/linkdir

Isso está me fornecendo resultados praticamente idênticos ao comando du :

DU:

15K     /usr/share/man/man3
4.0K    /usr/lib
3.6K    /usr/bin
2.4K    /usr/share/man/man1
1.9K    /usr/share/fonts/75dpi
1.9K    /usr/share/fonts/100dpi
1.9K    /usr/share/doc/arch-wiki-markdown
1.6K    /usr/share/fonts/TTF
1.6K    /usr/share/dolphin-emu/sys/GameSettings
1.6K    /usr/share/doc/efl/html

LS:

14686   /usr/share/man/man3:
4322    /usr/lib:
3653    /usr/bin:
2457    /usr/share/man/man1:
1897    /usr/share/fonts/100dpi:
1897    /usr/share/fonts/75dpi:
1890    /usr/share/doc/arch-wiki-markdown:
1613    /usr/include:
1575    /usr/share/doc/efl/html:
1556    /usr/share/dolphin-emu/sys/GameSettings:

Eu acho que a coisa include depende apenas do diretório que o programa olha primeiro - porque são os mesmos arquivos e hardlinked. Meio como a coisa acima. Eu posso estar errado sobre isso - e agradeço a correção ...

DU DEMO

% du --version
> du (GNU coreutils) 8.22

Crie um diretório de teste:

% mkdir ~/test ; cd ~/test
% du --inodes -S
> 1       .

Alguns diretórios de crianças:

% mkdir ./realdir ./linkdir
% du --inodes -S
> 1       ./realdir
> 1       ./linkdir
> 1       .

Crie alguns arquivos:

% printf 'touch ./realdir/file%s\n' 'seq 1 100' | . /dev/stdin
% du --inodes -S
> 101     ./realdir
> 1       ./linkdir
> 1       .

Alguns hardlinks:

% printf 'n="%s" ; ln ./realdir/file$n ./linkdir/link$n\n' 'seq 1 100' | 
    . /dev/stdin
% du --inodes -S
> 101     ./realdir
> 1       ./linkdir
> 1       .

Veja os hardlinks:

% cd ./linkdir
% du --inodes -S
> 101

% cd ../realdir
% du --inodes -S
> 101

Eles são contados sozinhos, mas vão até um diretório ...

% cd ..
% du --inodes -S
> 101     ./realdir
> 1       ./linkdir
> 1       .

Em seguida, executei meu script de execução abaixo e:

> 100     /home/mikeserv/test/realdir
> 100     /home/mikeserv/test/linkdir
> 2       /home/mikeserv/test

E Graeme:

> 101 ./realdir
> 101 ./linkdir
> 3 ./

Então, acho que isso mostra que a única maneira de contar inodes é por inode. E como contar arquivos significa contar inodes, você não pode contar inodes duplamente - para contar arquivos com precisão, os inodes não podem ser contados mais de uma vez.

    
por 04.04.2014 / 03:21
5

Eu usei essa resposta da SO Q & A intitulada: Onde estão todas as minhas inodes sendo usados? quando nosso NAS acabou há 2 anos:

$ find . -type d -print0 \
    | while IFS= read -rd '' i; do echo $(ls -a "$i" | wc -l) "$i"; done \
    | sort -n

Exemplo

$ find . -type d -print0 \
    | while IFS= read -rd '' i; do echo $(ls -a "$i" | wc -l) "$i"; done \
    | sort -n
...
110 ./MISC/nodejs/node-v0.8.12/out/Release/obj.target/v8_base/deps/v8/src
120 ./MISC/nodejs/node-v0.8.12/doc/api
123 ./apps_archive/monitoring/nagios/nagios-check_sip-1.3/usr/lib64/nagios
208 ./MISC/nodejs/node-v0.8.12/deps/openssl/openssl/doc/crypto
328 ./MISC/nodejs/node-v0.8.12/deps/v8/src
453 ./MISC/nodejs/node-v0.8.12/test/simple

Inodes do dispositivo de verificação

Dependendo do seu NAS, ele pode não oferecer um comando df completo. Então, nesses casos, você pode recorrer ao uso de tune2fs :

$ sudo tune2fs -l /dev/sda1 |grep -i inode
Filesystem features:      has_journal ext_attr resize_inode dir_index filetype needs_recovery extent flex_bg sparse_super huge_file uninit_bg dir_nlink extra_isize
Inode count:              128016
Free inodes:              127696
Inodes per group:         2032
Inode blocks per group:   254
First inode:              11
Inode size:           128
Journal inode:            8
Journal backup:           inode blocks

Cruzando limites do sistema de arquivos

Você pode usar a opção -xdev para direcionar find para restringir a pesquisa apenas ao dispositivo em que você está iniciando a pesquisa.

Exemplo

Digamos que eu tenha minha automontagem de diretório /home via compartilhamentos NFS do meu NAS, cujo nome é mulder.

$ df -h /home/sam 
Filesystem            Size  Used Avail Use% Mounted on
mulder:/export/raid1/home/sam
                      917G  572G  299G  66% /home/sam

Observe que o ponto de montagem ainda é considerado local para o sistema.

$ df -h /home/ .
Filesystem            Size  Used Avail Use% Mounted on
-                        0     0     0   -  /home
/dev/mapper/VolGroup00-LogVol00
                      222G  159G   52G  76% /

Agora, quando eu inicio find :

$ find / -xdev  | grep '^/home'
/home

Encontrou /home , mas nenhum dos conteúdos automontados, porque eles estão em um dispositivo diferente!

Tipos de sistema de arquivos

Você pode utilizar a opção para find , -fstype para controlar os tipos de sistemas de arquivos find que serão examinados.

   -fstype type
          File is on a filesystem of type type.  The valid filesystem types 
          vary among different versions of Unix; an incomplete list of 
          filesystem  types that are accepted on some version of Unix or 
          another is: ufs, 4.2, 4.3, nfs, tmp, mfs, S51K, S52K.  You can use 
          -printf with the %F directive to see the types of your
          filesystems.

Exemplo

Qual sistema de arquivos eu tenho?

$ find . -printf "%F\n" | sort -u
ext3

Então você pode usar isso para controlar o cruzamento:

somente ext3

$ find . -fstype ext3 | head -5
.
./gdcm
./gdcm/gdcm-2.0.16
./gdcm/gdcm-2.0.16/Wrapping
./gdcm/gdcm-2.0.16/Wrapping/CMakeLists.txt

apenas nfs

$ find . -fstype nfs | head -5
$ 

ext3 & ext4

$ find . -fstype ext3 -o -fstype ext4 | head -5
.
./gdcm
./gdcm/gdcm-2.0.16
./gdcm/gdcm-2.0.16/Wrapping
./gdcm/gdcm-2.0.16/Wrapping/CMakeLists.txt
    
por 26.02.2014 / 19:20
3

Comando para encontrar o inode usado:

for i in /*; do echo $i; find $i |wc -l | sort ; done
    
por 09.12.2015 / 11:05
2

Para listar o uso detalhado do inode para / , use o seguinte comando:

echo "Detailed Inode usage for: $(pwd)" ; for d in 'find -maxdepth 1 -type d |cut -d\/ -f2 |grep -xv . |sort'; do c=$(find $d |wc -l) ; printf "$c\t\t- $d\n" ; done ; printf "Total: \t\t$(find $(pwd) | wc -l)\n" 
    
por 29.03.2015 / 12:09
1

Definitivamente responda com o máximo de votos positivos para entender o conceito de inodes no linux e no unix, mas isso não ajuda muito quando se trata de resolver o problema real de excluir ou remover os inodes do disco. Uma maneira mais simples de fazer isso em sistemas baseados no Ubuntu é remover cabeçalhos e imagens indesejados do kernel do Linux.

sudo apt-get autoremove

Faria isso por você. No meu caso, o uso de inodes foi de 78% devido ao qual recebi alerta.

$ df -i
Filesystem     Inodes  IUsed  IFree IUse% Mounted on
/dev/xvda1     524288 407957 116331   78% /
none           957443      2 957441    1% /sys/fs/cgroup
udev           956205    388 955817    1% /dev
tmpfs          957443    320 957123    1% /run
none           957443      1 957442    1% /run/lock
none           957443      1 957442    1% /run/shm
none           957443      5 957438    1% /run/user

Depois de executar o comando sudo apt-get autoremove , ele caiu para 29%

$ df -i
Filesystem     Inodes  IUsed  IFree IUse% Mounted on
/dev/xvda1     524288 150472 373816   29% /
none           957443      2 957441    1% /sys/fs/cgroup
udev           956205    388 955817    1% /dev
tmpfs          957443    320 957123    1% /run
none           957443      1 957442    1% /run/lock
none           957443      1 957442    1% /run/shm
none           957443      5 957438    1% /run/user

Esta foi apenas a minha observação que salvou meu tempo. As pessoas podem encontrar uma solução melhor do que isso.

    
por 10.11.2016 / 20:54
1

Acho mais rápido e fácil detalhar usando o seguinte comando:

$ sudo du -s --inodes * | sort -rn

170202  var
157325  opt
103134  usr
53383   tmp
<snip>

Você pode, então, ir para var , por exemplo, e ver quais são os grandes inode que usam diretórios.

    
por 28.08.2017 / 02:47