Trouver des répertoires avec beaucoup de fichiers dans

33

Un de mes clients a donc reçu un courrier électronique de Linode indiquant que son serveur faisait exploser le 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 cherché 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 un contexte de mes mes serveurs occupés utilise 200K inodes et mon bureau (une ancienne installation avec plus de 4 To de stockage utilisé) est seulement un peu plus d' un million. Il ya un problème.

Donc ma question est, comment puis-je trouver où le problème est? Y a-t-il un dupour les inodes?

Oli
la source
1
lancez vmstat -1 100 et montrez-nous une partie de cela. méfiez-vous des grands nombres dans CS (commutation de contexte). Parfois, un système de fichiers défaillant peut perdre beaucoup d'inodes en erreurs. Ou peut-être légitimement, il y a beaucoup de fichiers. Ce lien devrait vous informer sur les fichiers et les inodes. stackoverflow.com/questions/653096/howto-free-inode-usage il vous faudra peut-être voir ce qui est en cours d'exécution / ouvert avec la commande lsof.
j0h

Réponses:

23

Vérifiez /lost+foundau cas où il y aurait un problème de disque et que de nombreux fichiers indésirables aient été détectés sous forme de fichiers séparés, éventuellement à tort.

Vérifiez iostatsi une application produit toujours des fichiers aussi dingues.

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

Je ne pense pas qu’il existe une combinaison d’options permettant à GNU dude compter 1 par entrée de répertoire. Vous pouvez le faire en produisant la liste des fichiers findet en comptant un peu dans awk. Voici un dupour les inodes. Minimalement testé, n'essaye pas de gérer les noms de fichiers contenant des sauts de lignes.

#!/bin/sh
find "$@" -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 le réviser à votre guise. sort -k1nr <root.du-inodes | headvous dira les plus grands délinquants.

Gilles, arrête de faire le mal
la source
Le script donne des erreurs:awk: line 2: find: regular expression compile failed (bad class -- [], [^] or [) [^ awk: line 2: syntax error at or near ] `/tmp/tmpw99dhs': Permission denied
Radu Rădeanu
@ RaduRădeanu Ah, je vois, j'ai utilisé une particularité gawk qui ne fonctionne pas dans les autres versions. J'ai ajouté une barre oblique inverse qui, à mon avis, est nécessaire selon POSIX.
Gilles 'SO- arrête d'être méchant'
14

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 "$@" -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 affiche les 10 meilleurs sous-répertoires par nombre de fichiers. Si vous voulez un top x, changez headavec head -n x, où xest un nombre naturel supérieur à 0.

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

top-bushy-folder

Radu Rădeanu
la source
2019: soulevé 10: read: Illegal option -d... récuré le -ddrapeau de l' readespoir qu'il ne se passera rien de mal. Je vous ferai savoir quand il aura fini de courir ...
Williams
3

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

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

Cela vide la totalité de 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.

chad
la source
+1: utiliser la base de données de localisation est une très bonne idée!
Max Beikirch
Lorsque vous ne pouvez pas utiliser local pour quelque raison que ce soit, lancez-le en find /path/to/parent -xdev > filelistpremier, puis demandez à sed de lire les entrées de cette liste.
gerrit
1

Une autre suggère:

http://www.iasptk.com/20314-ubuntu-find-large-files-fast-from-command-line

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

Trouver des fichiers de plus de 1 Go

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

Trouver des fichiers de plus de 100 Mo

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

Trouver 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 imprime la taille de chaque fichier dans un format lisible par l'homme.

ptheo
la source
2
Son problème est l’utilisation élevée d’inodes, qui pointe vers de nombreux fichiers plus petits, et non volumineux.
UpTheCreek
0

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

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

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

J'aime aussi cette réponse: https://unix.stackexchange.com/a/123052

Pour les paresseux, voici l'essentiel:

du --inodes -S | sort -rh | sed -n \
    '1,50{/^.\{71\}/s/^\(.\{30\}\).*\(.\{37\}\)$/\1...\2/;p}'
Tommy Bravo
la source