CLI AI

df diz que o disco está cheio e o du diz que não

2026-05-20

Os dois. O df pergunta ao sistema de arquivos quantos blocos estão alocados; o du percorre a árvore de diretórios e soma o que consegue ver. Quando os dois discordam, alguma coisa está segurando espaço que já não tem nome. Veja como achar.

1. Confirmar a divergência

clai
$ clai compare o que o df relata para / com o que o du realmente encontra lá→ df -h / && du -shx / 2>/dev/nullFilesystem      Size  Used Avail Use% Mounted on/dev/nvme1n1p2  915G  871G   44G  96% /348G	/

871 GB ocupados, 348 GB encontrados. Essa diferença é o problema inteiro. O -x impede que o du saia andando por outros sistemas de arquivos montados e infle a própria resposta.

2. Cheque os inodes antes de caçar bytes

clai
$ clai verifique se o sistema de arquivos ficou sem inodes em vez de sem espaço→ df -i /Filesystem        Inodes   IUsed      IFree IUse% Mounted on/dev/nvme1n1p2 124960768 3634368  121326400    3% /

Se IUse% estiver em 100% e Use% não, você tem milhões de arquivos minúsculos e nenhum inode livre. É outro problema: o disco tem espaço, mas o sistema de arquivos não tem onde registrar mais um arquivo.

3. Achar os arquivos apagados que continuam abertos

clai
$ clai mostre arquivos que foram apagados mas ainda estão abertos por um processo→ sudo lsof +L1COMMAND    PID USER   FD   TYPE DEVICE   SIZE/OFF NLINK  NODE NAMEpython3  23435 app     3u   REG  259,2 1000000000     0 41231 /var/log/app/debug.log (deleted)

NLINK 0 é a assinatura: nenhuma entrada de diretório aponta mais para esse arquivo, então o du não o vê, mas os blocos seguem alocados até o último descritor fechar. Normalmente é um log que alguém apagou sem reiniciar o serviço que escreve nele.

4. Recuperar o espaço

clai
$ clai reinicie o serviço que está segurando esse arquivo apagado→ sudo systemctl restart app.service

Reiniciar o processo fecha o descritor e o kernel libera os blocos na hora. O df cai no mesmo instante — sem desmontar, sem reboot.

5. Se não dá para reiniciar agora

clai
$ clai zere o arquivo apagado que o pid 23435 ainda segura no descritor 3→ sudo truncate -s 0 /proc/23435/fd/3

Escrever através de /proc/<pid>/fd/<n> esvazia o arquivo em que o processo continua escrevendo, sem matá-lo. O processo mantém o descritor e segue logando; você recupera o espaço agora.

6. O outro clássico: um ponto de montagem escondendo arquivos

clai
$ clai verifique se algo está montado sobre um diretório que ainda tem arquivos embaixo→ sudo mount --bind / /mnt/root && du -shx /mnt/root/var14G	/mnt/root/var

Se escreveram em /var/data antes de montar um disco ali, esses arquivos continuam no sistema de arquivos raiz — ocupando espaço que ninguém enxerga através da montagem. Um bind mount de / os expõe.

Pegadinhas

  • Rode o du como root. Como usuário comum ele pula em silêncio os diretórios que não consegue ler, e você vai culpar um fantasma pelo que na verdade é permissão.
  • lsof +L1 precisa de privilégio para ver descritores de outros usuários. Sem sudo você recebe uma lista curta e enganosamente limpa.
  • Não apague de novo um log ativo. Foi exatamente isso que criou a situação. Use truncate -s 0 em logs vivos, ou configure o logrotate com copytruncate.

Perguntas relacionadas

Por que o espaço não volta depois do rm? No Unix, o unlink remove o nome, não os dados. Os blocos são liberados quando o último descritor aberto fecha — o que, para um serviço rodando, significa nunca, até ele reiniciar.

du e df diferem em alguns por cento, é problema? Não. São os blocos reservados (5% para o root por padrão no ext4) mais os metadados. Só diferenças grandes merecem investigação.

Dá para achar sem o lsof? Dá: sudo ls -l /proc/*/fd 2>/dev/null | grep deleted mostra a mesma coisa através da tabela de processos.

Veja também

Pare de procurar flags do lsof às 3 da manhã — descreva o problema e o CliAI escreve o comando. Instale em uma linha.