Histórico: servidor físico, com cerca de dois anos, unidades SATA de 7200-RPM conectadas a uma placa 3Ware RAID, ext3 FS montado noatime e dados = pedidos, sem carga louca, kernel 2.6.18-92.1.22.el5, tempo de atividade 545 dias . O diretório não contém subdiretórios, apenas milhões de arquivos pequenos (~ 100 bytes), com alguns maiores (alguns KB).
Temos um servidor que ficou um pouco covarde ao longo dos últimos meses, mas só o notamos outro dia quando começou a não conseguir gravar em um diretório por conter muitos arquivos. Especificamente, ele começou a lançar esse erro em / var / log / messages:
ext3_dx_add_entry: Directory index full!
O disco em questão possui muitos inodes restantes:
Filesystem Inodes IUsed IFree IUse% Mounted on
/dev/sda3 60719104 3465660 57253444 6% /
Então, acho que isso significa que atingimos o limite de quantas entradas podem estar no próprio arquivo de diretório. Não faço ideia de quantos arquivos seriam, mas não pode ser mais do que três milhões, como você pode ver. Não que isso seja bom, lembre-se! Mas essa é uma parte da minha pergunta: exatamente qual é esse limite superior? É sintonizável? Antes de eu chegar gritado-Quero ajustá-lo para baixo ; esse diretório enorme causou todo tipo de problemas.
Enfim, rastreamos o problema no código que estava gerando todos esses arquivos e o corrigimos. Agora estou preso em excluir o diretório.
Algumas opções aqui:
rm -rf (dir)
Eu tentei isso primeiro. Desisti e matei depois que durou um dia e meio, sem qualquer impacto perceptível.
- unlink (2) no diretório: definitivamente vale a pena considerar, mas a questão é se seria mais rápido excluir os arquivos dentro do diretório via fsck do que excluir via unlink (2). Ou seja, de uma forma ou de outra, tenho que marcar esses inodes como não utilizados. Isso pressupõe, é claro, que eu posso dizer ao fsck para não soltar entradas nos arquivos em / lost + found; caso contrário, acabei de mudar meu problema. Além de todas as outras preocupações, depois de ler um pouco mais sobre isso, provavelmente eu teria que chamar algumas funções internas do FS, pois nenhuma das variantes de desvinculação (2) que posso encontrar me permitiria excluir alegremente um diretório com entradas. Pooh.
while [ true ]; do ls -Uf | head -n 10000 | xargs rm -f 2>/dev/null; done )
Esta é realmente a versão abreviada; o real que estou executando, que apenas adiciona alguns relatórios de progresso e uma parada limpa quando ficamos sem arquivos para excluir, é:
exportar i = 0; time (while [true]; faça ls -Uf | cabeça -n 3 | grep -qF '.png' || pausa; ls -Uf | cabeça -n 10000 | xargs rm -f 2> / dev / null; exportar i = $ (($ i + 10000)); eco "$ i ..."; feito )
Isso parece estar funcionando muito bem. Enquanto escrevo isso, ele excluiu 260.000 arquivos nos últimos trinta minutos.
- Como mencionado acima, o limite de entrada por diretório é ajustável?
- Por que demorou "7m9.561s / usuário 0m0.001s / sys 0m0.001s" reais para excluir um único arquivo que foi o primeiro na lista retornado
ls -U
e demorou talvez dez minutos para excluir as primeiras 10.000 entradas com o comando comando no # 3, mas agora ele está indo muito feliz? Na verdade, ele excluiu 260.000 em cerca de trinta minutos, mas agora são necessários mais quinze minutos para excluir mais 60.000. Por que as enormes oscilações de velocidade? - Existe uma maneira melhor de fazer esse tipo de coisa? Não armazene milhões de arquivos em um diretório; Eu sei que isso é bobagem, e isso não teria acontecido no meu relógio. Pesquisar no Google e analisar SF e SO oferece muitas variações
find
que não serão significativamente mais rápidas do que minha abordagem por várias razões evidentes. Mas a idéia delete-via-fsck tem alguma perna? Ou algo completamente diferente? Estou ansioso para ouvir o pensamento fora da caixa (ou dentro da caixa não é bem conhecida).
Saída final do script !:
2970000...
2980000...
2990000...
3000000...
3010000...
real 253m59.331s
user 0m6.061s
sys 5m4.019s
Assim, três milhões de arquivos excluídos em pouco mais de quatro horas.
rm -rfv | pv -l >/dev/null
. O pv deve estar disponível no repositório EPEL .