Como contar “inodes” no Linux
“Inode” (de index node) ou “Nó-I” em Português (embora eu nunca tenha visto essa tradução em nenhuma literatura técnica) é uma estrutura de dados associada a cada arquivo em um sistema de arquivo UNIX. Entre outras coisas, o inode contém informações sobre os atributos e propriedades de um arquivo, seu “pai”, etc.
Cada arquivo e cada diretório num sistema de arquivo Unix ocupa um inode, e a quantidade de inodes que um determinado volume suporta é limitada.
Alguns pacotes de software, como o cPanel, têm limitações severas quanto à quantidade de inodes que podem gerenciar. Uma conta de usuário do cPanel pode conter no máximo 64k (ou 65535) inodes. Caso a contagem de inodes de uma conta no cPanel exceda este valor resultados imprevisíveis podem advir, sempre vinculados a perda de dados.
Recentemente passei por uma situação inédita em mais de doze anos como administrador de sistemas: o disco rígido (uma unidade SSD, a bem da verdade) estava com mais de 50% de espaço disponível, mas o servidor estava apresentando um comportamento inesperado, sempre com mensagens de erro alusivas a espaço em disco esgotado.
Depois de penar um bocado tentando entender o problema lembrei dessa particularidade do cPanel, e embora o servidor de meu cliente não tenha este sistema, imaginei que talvez fossem os inodes esgotados causando problema.
Dito e feito!
Ao consultar o espaço disponível no disco eu obtinha um resultado semelhante ao da ilustração abaixo:
root@ee:~# df -h Filesystem Size Used Avail Use% Mounted on /dev/mapper/ubuntu1404--vg-root 28G 13G 14G 47% / none 4.0K 0 4.0K 0% /sys/fs/cgroup udev 990M 4.0K 990M 1% /dev tmpfs 201M 672K 200M 1% /run none 5.0M 0 5.0M 0% /run/lock none 1001M 0 1001M 0% /run/shm none 100M 0 100M 0% /run/user /dev/vda1 228M 92M 125M 43% /boot root@ee:~#
Contudo, ao listar os inodes livres no sistema os números eram outros, bem assustadores:
root@ee:~# df -i Filesystem Inodes IUsed IFree IUse% Mounted on /dev/mapper/ubuntu1404--vg-root 1826816 1826816 0 100% / none 256229 2 256227 1% /sys/fs/cgroup udev 253435 442 252993 1% /dev tmpfs 256229 406 255823 1% /run none 256229 4 256225 1% /run/lock none 256229 1 256228 1% /run/shm none 256229 2 256227 1% /run/user /dev/vda1 124496 312 124184 1% /boot root@ee:~#
Saber qual é o problema é meio problema resolvido. Mas eu ainda precisava descobrir onde estava acontecendo o gargalo, o consumo absurdo de inodes.
E aí a linha de comando abaixo veio a calhar:
echo "Contagem detalhada de inodes: $(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"
Rodei a linha mágica acima em diversos locais do servidor, e finalmente descobri que o esgotamento do disco se dava por causa de um script na crontab que gerava um relatório de poucos bytes a cada vez que era executado (o que acontecia a cada minuto). Foram algumas semanas funcionando perfeitamente até a verbosidade do script acabar gerando tantos, mas tantos arquivos minúsculos no disco, que nada mais funcionava direito.