Como Lidar com Esgotamento de inodes - Disco Nao Esta Cheio Mas Escritas Falham
O Que Voce Vai Resolver Aqui
- Entender por que escritas falham com
No space left on deviceenquantodf -hreporta espaco livre - Usar
df -ipara encontrar qual filesystem ficou sem inodes - Localizar o diretorio ofensor e recuperar inodes com seguranca por causa (sessoes, email, Docker, logs)
Caminho mais rapido (3 passos)
df -ipara encontrar o ponto de montagem onde IUse% e 100%- A partir desse ponto de montagem, refine com
find ... -xdev | cut ... | sort | uniq -c | sort -rnpara encontrar o diretorio acumulando arquivos - Exclua por causa (sessoes / fila de email / journal / Docker / logs) e previna recorrencia com cron e logrotate
Ambiente assumido
- SO: Ubuntu / Debian / familia RHEL (ext4 assumido)
- Privilegio:
sudodisponivel - XFS / Btrfs / ZFS alocam inodes dinamicamente, entao este sintoma raramente ocorre neles
O Que e Esgotamento de inodes e Por Que Acontece?
Esgotamento de inodes e o estado em que a tabela de metadados do filesystem esta cheia mesmo com blocos de dados ainda livres, entao a criacao de qualquer novo arquivo falha.
Um filesystem tem dois limites:
- Blocos de dados: os bytes do conteudo dos arquivos. Mostrado por
df -h. - Inodes: metadados por arquivo (permissoes, dono, tamanho, ponteiros de bloco). Mostrado por
df -i. Um arquivo consome um inode.
ext4 usa alocacao estatica de inodes: a quantidade de inodes e fixada no momento do mkfs (a proporcao padrao e aproximadamente um inode por 16 KiB). Uma carga de trabalho que cria muitos arquivos pequenos esgota inodes muito antes de encher o disco.
Sintomas classicos
touch newfileretornaNo space left on devicedf -hmostra uso em torno de 60% — parece "livre"df -imostra IUse% = 100%
1. Verifique o Uso de inodes com df -i
Comece com df -i. Ele reporta o uso de inodes por ponto de montagem.
$ df -ih
Filesystem Inodes IUsed IFree IUse% Mounted on /dev/sda1 3.8M 3.8M 12K 100% / /dev/sdb1 6.4M 12K 6.4M 1% /data tmpfs 1.0M 5 1.0M 1% /run
A linha com IUse% em 100% (ou 99%) e o ponto de montagem com problema. No exemplo acima, / esta cheio de inodes.
A flag -i faz parte do GNU coreutils e funciona em praticamente todas as distribuicoes Linux. Nao esta no POSIX mas esta universalmente disponivel na pratica.
2. Encontre o Diretorio Consumindo inodes
Investigue a partir do ponto de montagem ofensor ate os diretorios com mais arquivos.
2-1. Conte arquivos rapidamente sob um caminho
$ sudo find /var -xdev -printf . | wc -c
Sempre passe -xdev para que o find nao cruze para outros pontos de montagem. -printf . emite um unico ponto por arquivo e wc -c conta bytes — muito mais rapido que wc -l em caminhos completos.
2-2. Agregue contagens de arquivos por subdiretorio
$ sudo find / -xdev -type f -printf '%h\n' 2>/dev/null \
| cut -d/ -f1-4 \
| sort \
| uniq -c \
| sort -rn \
| head -20432105 /var/lib/php 187220 /var/spool/postfix 54221 /var/log/journal 8021 /var/lib/docker ...
cut -d/ -f1-4 agrupa por profundidade 3 para revelar a forma geral. Quando um caminho suspeito aparecer, re-execute com -f1-6 para investigar mais fundo.
2-3. Conte entradas em um unico diretorio
$ ls -1U /var/lib/php/sessions | wc -l
ls -1U pula a ordenacao para manter a velocidade mesmo com milhoes de entradas. wc -l conta linhas, que equivale a contagem de arquivos.
ls com ordenacao pode esgotar a memoria em diretorios com milhoes de entradas. Use ls -U ou find em vez disso.
3. Corrija por Causa
3-1. Sessoes PHP (/var/lib/php/sessions)
Sessoes se acumulam quando session.gc_probability e baixo ou o cron sessionclean da distro parou de executar.
# Verifique contagem e idade primeiro $ sudo find /var/lib/php/sessions -xdev -type f | head $ sudo find /var/lib/php/sessions -xdev -type f -mtime +7 | wc -l # Imprima antes de excluir (dry run), depois exclua $ sudo find /var/lib/php/sessions -xdev -type f -mtime +7 -print $ sudo find /var/lib/php/sessions -xdev -type f -mtime +7 -delete
No Debian/Ubuntu, verifique se /etc/cron.d/php executa sessionclean no agendamento.
3-2. Fila de email do Postfix (/var/spool/postfix)
Um email de saida com falha ou tempestade de bounces pode inflar a fila.
$ sudo mailq | tail -1 # contagem da fila $ sudo postqueue -p | tail -1 # mesmo $ sudo postsuper -d ALL deferred # excluir apenas email adiado $ sudo postsuper -d ALL # excluir TUDO (alto impacto)
postsuper -d ALL exclui todo email nao entregue. Confirme que nao ha email de negocios na fila antes de executar.
3-3. Fragmentos do journal do systemd
$ journalctl --disk-usage $ sudo journalctl --vacuum-time=7d # excluir entradas mais antigas que 7 dias $ sudo journalctl --vacuum-size=200M # limitar total a 200 MB
Configure SystemMaxFiles= em /etc/systemd/journald.conf para prevenir recorrencia.
3-4. Camadas overlay2 do Docker
$ docker system df $ docker system prune -a --volumes # remover imagens e volumes nao utilizados (avalie o impacto primeiro)
Veja Identificando uso de disco do Docker para o detalhamento completo.
3-5. Rotacao de log com falha
$ sudo ls -lh /var/log | head $ sudo logrotate -d /etc/logrotate.conf # dry run $ sudo logrotate -f /etc/logrotate.conf # execucao forcada
4. Seguranca Antes de Excluir
4-1. Sempre faca dry-run primeiro
# Imprima o que corresponderia $ sudo find /tmp -xdev -type f -mtime +30 -print # Exclua apenas apos revisar a lista $ sudo find /tmp -xdev -type f -mtime +30 -delete
4-2. Cuidado com arquivos mantidos abertos apos unlink
Um arquivo excluido enquanto um processo o mantem aberto esta unlinked but still open — disco e inode nao sao liberados ate o processo fechar o descritor.
$ sudo lsof +L1 | head # arquivos com link count 0 ainda abertos
Reinicie o processo ofensor para liberar tanto o inode quanto o espaco.
4-3. Evite overflow de argumentos com xargs
# RUIM: linha de comando pode estourar ou executar parcialmente
$ rm $(find /var/lib/php/sessions -type f)
# BOM: use -print0 / xargs -0 para seguranca
$ sudo find /var/lib/php/sessions -xdev -type f -mtime +7 -print0 \
| sudo xargs -0 -r rm --Veja Excluindo arquivos com seguranca usando find para o padrao completo.
5. Previna Recorrencia: Aumentando inodes Permanentemente
5-1. Inspecione a proporcao atual de inodes
$ sudo tune2fs -l /dev/sda1 | grep -E 'Inode count|Block count|Inode size'
5-2. ext4: reformate para aumentar a quantidade de inodes
# Faca backup primeiro. -i define bytes-per-inode; valor menor = mais inodes $ sudo mkfs.ext4 -i 8192 /dev/sdb1 # aproximadamente um inode por 8 KB $ sudo mkfs.ext4 -N 10000000 /dev/sdb1 # especificar quantidade total
mkfs apaga o filesystem. Faca snapshot ou backup antes de executar. Sempre ensaie o procedimento em um ambiente de staging antes de tocar em producao.
5-3. Migre para um filesystem com inodes dinamicos (XFS / Btrfs)
Se voce pode provisionar um novo volume para uma carga de trabalho que cria muitos arquivos pequenos, XFS ou Btrfs elimina o problema do teto de inodes porque ambos alocam inodes sob demanda.
5-4. Adicione monitoramento
Colete node_filesystem_files e node_filesystem_files_free (Prometheus node_exporter) e alerte quando IUse% exceder 80%. Detectar antes de 100% da tempo para excluir com seguranca em vez de no modo panico.
6. O Que Nao Fazer
- Remover diretorios inteiros de servicos como
rm -rf /var/spool/postfix(Postfix recusara iniciar) - Exclusoes em massa incondicionais como
find / -delete - Tentar aumentar inodes com
tune2fs(nao suportado no ext4) postsuper -d ALLsem verificacao (risco de excluir email de negocios)- Pressionar
Ctrl+Cno meio da exclusao (deixa o FS em estado semi-limpo)