Trouver des répertoires contenant de nombreux fichiers

32

Ainsi, un de mes clients a reçu un courrier électronique de Linode indiquant aujourd'hui que son serveur provoquait l'explosion du service de sauvegarde de Linode. Pourquoi? Trop de fichiers. J'ai ri puis j'ai couru:

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

Merde. 2,4 millions d'inodes utilisés. Qu'est-ce qui s'est passé?!

J'ai recherché les suspects évidents ( /var/{log,cache} et le répertoire où tous les sites sont hébergés), mais je ne trouve rien de vraiment suspect. Quelque part sur cette bête, je suis certain qu’il existe un répertoire contenant quelques millions de fichiers.

Pour le contexte 1, mes mes serveurs occupés utilisent 200 000 inodes et mon ordinateur de bureau (une ancienne installation avec plus de 4 To de stockage utilisé) ne représente qu’un peu plus d’un million. Il y a un problème.

Ma question est donc: comment puis-je trouver où se trouve le problème? Existe-t-il un du pour les inodes?

    
posée Oli 03.07.2013 - 21:32
la source

6 réponses

22

Cochez /lost+found au cas où il y aurait un problème de disque et que beaucoup de fichiers inutiles ont été détectés sous forme de fichiers séparés, éventuellement à tort.

Vérifiez iostat pour voir si une application produit toujours des fichiers aussi dingues.

find / -xdev -type d -size +100k vous dira s’il existe un répertoire qui utilise plus de 100 Ko d’espace disque. Ce serait un répertoire contenant beaucoup de fichiers, ou contenant beaucoup de fichiers dans le passé. Vous voudrez peut-être ajuster la taille.

Je ne pense pas qu'il existe une combinaison d'options dans GNU du pour le faire compter 1 par entrée de répertoire. Vous pouvez le faire en produisant la liste de fichiers avec find et en effectuant un peu de comptage dans awk. Voici un du pour les inodes. Minimalement testé, n'essaye pas de gérer les noms de fichiers contenant des retours à la ligne.

#!/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"; }'

Utilisation: du-inodes / . Imprime une liste de répertoires non vides avec le nombre total d'entrées qu'ils contiennent et leurs sous-répertoires de manière récursive. Rediriger la sortie vers un fichier et l'examiner à votre guise. sort -k1nr <root.du-inodes | head vous dira les plus gros délinquants.

    
réponse donnée Gilles 03.07.2013 - 22:15
la source
13

Vous pouvez vérifier avec ce 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

Ceci imprime les 10 premiers sous-répertoires par nombre de fichiers. Si vous voulez un top x, changez head avec head -n x , où x est un nombre naturel supérieur à 0.

Pour des résultats sûrs à 100%, exécutez ce script avec les privilèges root:

    
réponse donnée Radu Rădeanu 04.07.2013 - 09:46
la source
3

Souvent plus rapide que rechercher, si votre base de données de localisation est à jour:

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

Ceci vide toute la base de données de localisation, supprime tout ce qui se trouve après le dernier '/' dans le chemin, puis le tri et "uniq -c" vous donnent le nombre de fichiers / répertoires par répertoire. "sort -n" va vous chercher les dix répertoires contenant le plus de choses.

    
réponse donnée chad 17.04.2014 - 16:39
la source
1

Une autre suggestion:

lien

Utilisez ces recherches pour trouver les fichiers les plus volumineux sur votre serveur.

Rechercher des fichiers de plus de 1 Go

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

Rechercher des fichiers de plus de 100 Mo

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

Rechercher des fichiers de plus de 10 Mo

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

La première partie est la commande de recherche utilisant l'indicateur "-size" pour rechercher des fichiers de différentes tailles mesurés en kilo-octets.

Le dernier bit à la fin commençant par "-exec" permet de spécifier une commande que nous voulons exécuter sur chaque fichier trouvé. Ici, la commande "ls -lh" doit inclure toutes les informations apparaissant lors de la liste du contenu d'un répertoire. Le h vers la fin est particulièrement utile car il affiche la taille de chaque fichier dans un format lisible par l’homme.

    
réponse donnée ptheo 10.07.2013 - 09:01
la source
0

Cela a fonctionné pour moi lorsque l'autre a échoué sous Android via le shell:

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

J'aime utiliser quelque chose comme du --inodes -d 1 pour trouver un répertoire qui contient de nombreux fichiers de manière récursive ou directe.

J'aime aussi cette réponse: lien

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}'
    
réponse donnée Tommy Bravo 16.01.2018 - 17:29
la source

Lire d'autres questions sur les étiquettes