Encontre diretórios com muitos arquivos em

32

Então, um cliente meu recebeu um e-mail da Linode dizendo que o servidor estava causando o aumento do serviço de backup da Linode. Por quê? Muitos arquivos. Eu ri e corri:

# df -ih
Filesystem     Inodes IUsed IFree IUse% Mounted on
/dev/xvda        2.5M  2.4M   91K   97% /

Porcaria. 2,4 milhões de inodes em uso. O que diabos está acontecendo?!

Procurei os suspeitos óbvios ( /var/{log,cache} e o diretório onde todos os sites estão hospedados), mas não estou achando nada realmente suspeito. Em algum lugar nessa fera, tenho certeza de que há um diretório que contém alguns milhões de arquivos.

Para o contexto um, meus meus servidores ocupados usam 200k inodes e minha área de trabalho (uma instalação antiga com mais de 4 TB de armazenamento usado) é pouco mais de um milhão. Existe um problema.

Então, minha pergunta é: como encontro o problema? Existe um du para inodes?

    
por Oli 03.07.2013 / 21:32

6 respostas

22

Verifique /lost+found no caso de haver um problema no disco e muito lixo acabou sendo detectado como arquivos separados, possivelmente de forma errada.

Verifique iostat para ver se algum aplicativo ainda está produzindo arquivos como um louco.

find / -xdev -type d -size +100k dirá se há um diretório que usa mais de 100kB de espaço em disco. Esse seria um diretório que contém muitos arquivos ou continha muitos arquivos no passado. Você pode querer ajustar o tamanho.

Eu não acho que há uma combinação de opções para o GNU du para fazer com que ele conte 1 por entrada de diretório. Você pode fazer isso produzindo a lista de arquivos com find e fazendo um pouco de contagem no awk. Aqui está um du para inodes. Minimamente testado, não tenta lidar com nomes de arquivos contendo novas linhas.

#!/bin/sh
find "[email protected]" -xdev -depth | awk '{
    depth = $0; gsub(/[^\/]/, "", depth); depth = length(depth);
    if (depth < previous_depth) {
       # A non-empty directory: its predecessor was one of its files
       total[depth] += total[previous_depth];
       print total[previous_depth] + 1, $0;
       total[previous_depth] = 0;
    }
    ++total[depth];
    previous_depth = depth;
}
END { print total[0], "total"; }'

Uso: du-inodes / . Imprime uma lista de diretórios não vazios com a contagem total de entradas neles e seus subdiretórios recursivamente. Redirecionar a saída para um arquivo e revê-lo em seu lazer. sort -k1nr <root.du-inodes | head dirá os maiores ofensores.

    
por Gilles 03.07.2013 / 22:15
13

Você pode verificar com este script:

#!/bin/bash

if [ $# -ne 1 ];then
  echo "Usage: 'basename $0' DIRECTORY"
  exit 1
fi

echo "Wait a moment if you want a good top of the bushy folders..."

find "[email protected]" -type d -print0 2>/dev/null | while IFS= read -r -d '' file; do 
    echo -e 'ls -A "$file" 2>/dev/null | wc -l' "files in:\t $file"
done | sort -nr | head | awk '{print NR".", "\t", $0}'

exit 0

Imprime os 10 principais subdiretórios por contagem de arquivos. Se você quiser um top x, altere head com head -n x , onde x é um número natural maior que 0.

Para obter 100% de resultados seguros, execute este script com privilégios de root:

    
por Radu Rădeanu 04.07.2013 / 09:46
3

Com frequência, é mais rápido do que encontrar, se o banco de dados de localização estiver atualizado:

# locate '' | sed 's|/[^/]*$|/|g' | sort | uniq -c | sort -n | tee filesperdirectory.txt | tail

Isso despeja todo o banco de dados de localização, retira tudo além do último '/' no caminho, depois a ordenação e "uniq -c" fornecem o número de arquivos / diretórios por diretório. "ordene -n" canalizado para a cauda para obter os dez diretórios com o maior número de itens neles.

    
por chad 17.04.2014 / 16:39
1

Outra sugestão:

link

Use essas pesquisas para encontrar os maiores arquivos em seu servidor.

Encontrar arquivos com mais de 1 GB

sudo find / -type f -size +1000000k -exec ls -lh {} \;

Encontrar arquivos acima de 100 MB

sudo find / -type f -size +100000k -exec ls -lh {} \;

Encontrar arquivos com mais de 10 MB

sudo find / -type f -size +10000k -exec ls -lh {} \;

A primeira parte é o comando find usando o sinalizador "-size" para localizar arquivos em tamanhos diferentes, medidos em kilobytes.

O último bit no final que começa com "-exec" permite especificar um comando que queremos executar em cada arquivo que encontrarmos. Aqui, o comando "ls -lh" inclui todas as informações vistas ao listar o conteúdo de um diretório. O h em direção ao final é especialmente útil, pois imprime o tamanho de cada arquivo em um formato legível por humanos.

    
por ptheo 10.07.2013 / 09:01
0

Isso funcionou para mim quando o outro falhou no Android através do shell:

find / -type d -exec sh -c "fc=\$(find '{}' -type f | wc -l); echo -e \"\$fc\t{}\"" \; | sort -nr | head -n25
    
por Kevin Parker 12.02.2015 / 22:10
0

Eu gosto de usar algo como du --inodes -d 1 para encontrar um diretório que contenha recursivamente ou diretamente muitos arquivos.

Também gosto dessa resposta: link

For the lazy of us, here is the gist of it:

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