Como Lidar com Esgotamento de inodes - Disco Nao Esta Cheio Mas Escritas Falham

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 device enquanto df -h reporta espaco livre
  • Usar df -i para 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)

  1. df -i para encontrar o ponto de montagem onde IUse% e 100%
  2. A partir desse ponto de montagem, refine com find ... -xdev | cut ... | sort | uniq -c | sort -rn para encontrar o diretorio acumulando arquivos
  3. 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: sudo disponivel
  • 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 newfile retorna No space left on device
  • df -h mostra uso em torno de 60% — parece "livre"
  • df -i mostra 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 -20
 432105 /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)

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

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

Proximas Leituras