5 votes

Comment déterminer quels processus ont le plus d'inodes ouverts ?

Voici mon problème, visible dans un graphique munin :

munin inode chart

Mes inodes utilisés/ouverts sont "soudainement" en augmentation constante.

Existe-t-il un moyen de déterminer quel processus conserve les inodes les plus ouverts ? J'ai utilisé l'approche de https://unix.stackexchange.com/questions/117093/find-where-inodes-are-being-used et j'ai trouvé et nettoyé quelques dossiers avec des mails et des logs dont je pouvais me débarrasser... Pourtant, si les inodes sont OUVERTS, il doit y avoir un processus qui les maintient en service, non ? Ce n'est pas forcément du dossier contenant le plus de fichiers que provient l'augmentation - ou est-ce que je me trompe ?

J'aimerais donc savoir qui les garde ouverts et suivre l'utilisation pour voir d'où vient l'augmentation.

Mise à jour

En me basant sur le script d'Andrew, j'ai créé une version de celui-ci qui affiche également le nom du processus. Comme j'ai quelques processus nginx/apache en cours d'exécution qui peuvent respawn, j'aimerais voir les résultats sur le nom du processus.

for dir in /proc/*/fd;
do
    echo -n "$dir ";
    pid=`expr "$dir" : '\/proc\/\(.*\)\/.*'`; # extract the pid
    pname=`ps -p $pid -o comm=`; # grab process name
    echo -n "$pname ";
    ls $dir 2>/dev/null | wc -l;
done | sort -n -k 3

Exemple de sortie :

/proc/4612/fd sshd 49
/proc/46470/fd node 60
/proc/5655/fd nginx 66
/proc/6656/fd nginx 76
/proc/7654/fd nginx 81
/proc/8578/fd dovecot 107
/proc/9657/fd nginx 117
/proc/3495/fd java 146
/proc/4785/fd mysqld 382

Le prochain test consisterait à enregistrer la distribution dans le temps pour voir ce qui change et comment cela est corrélé avec le nombre de /proc/sys/fs/inode-nr que Morgan a mentionné.

Un an plus tard...

Un certain temps a passé, voici un nouveau graphique munin open inodes

Et devinez quoi, fin septembre est le moment où un disque défectueux a été remplacé. Il semble donc que tout le désordre ait été généré par une erreur de disque. Néanmoins, les scripts sont toujours utiles !

2voto

Andrew Henle Points 1212

Comptez le nombre d'entrées dans chaque /proc/[PID]/fd répertoire. Cela vous donnera le nombre de descripteurs de fichiers que chaque processus a ouvert. Bien qu'il faille un certain temps pour énumérer tous les processus, les processus manquants qui démarrent ou s'arrêtent pendant que votre comptage est en cours ne devraient pas être un problème puisque vous recherchez un processus à longue durée de vie avec beaucoup de descripteurs de fichiers ouverts.

Quelque chose comme ça :

for dir in /proc/*/fd;
do
    echo -n "$dir "; #need a space to get real columns for the sort
    ls $dir 2>/dev/null | wc -l;
done | sort -n -k 2

Les dernières lignes de la sortie montreront le répertoire /proc/[PID]/fd avec un compte de descripteurs de fichiers ouverts pour chaque processus. Le(s) processus coupable(s) devrait(ent) s'y trouver vers le bas.

Notez que chaque entrée dans /proc/[PID]/fd est techniquement un descripteur de fichier et non un inode ouvert séparé, chaque inode ouvert séparé doit avoir au moins un descripteur de fichier séparé dans un répertoire /proc/[PID]/fd quelque part.

1voto

user279360 Points 11

Je pense que le problème ici est, en partie, ce que munin entend par "inodes ouverts". Mon installation par défaut de munin possède deux plugins pour obtenir le nombre d'inodes alloués :

"/etc/munin/plugins/open_inodes" qui récupère la métrique des inodes depuis "/proc/sys/fs/inode-nr".

y

"/etc/munin/plugins/df_inode" qui obtient la métrique à partir de la sortie de "df -i".

Ces chiffres sont le reflet des fichiers existants ET NON du nombre de fichiers/inodes utilisés par tous les processus du système.

Par exemple, ce script crée dix fichiers et après qu'il se termine, nous pouvons voir l'augmentation de l'allocation des inodes à la fois dans "df -i" et inode-nr.

    #!/usr/bin/python

    f0 = open("foo0", "w")
    f1 = open("foo1", "w")
    f2 = open("foo2", "w")
    f3 = open("foo3", "w")
    f4 = open("foo4", "w")
    f5 = open("foo5", "w")
    f6 = open("foo6", "w")
    f7 = open("foo7", "w")
    f8 = open("foo8", "w")
    f9 = open("foo9", "w")

Cependant, si je modifie ce paramètre pour empêcher le programme de se terminer (et que les fichiers existent déjà)... les fichiers restent "ouverts" et "utilisés" par le processus.

    #!/usr/bin/python

    import time

    f0 = open("foo0", "w")
    f1 = open("foo1", "w")
    f2 = open("foo2", "w")
    f3 = open("foo3", "w")
    f4 = open("foo4", "w")
    f5 = open("foo5", "w")
    f6 = open("foo6", "w")
    f7 = open("foo7", "w")
    f8 = open("foo8", "w")
    f9 = open("foo9", "w")

    time.sleep(600)

ce que nous pouvons voir reflété dans la sortie de "lsof -p PID".

COMMAND    PID   USER   FD   TYPE DEVICE SIZE/OFF   NODE NAME
...
open_some 6602 morgan    3w   REG  254,1        0 262198 /home/morgan/src/foo0
open_some 6602 morgan    4w   REG  254,1        0 262273 /home/morgan/src/foo1
open_some 6602 morgan    5w   REG  254,1        0 262284 /home/morgan/src/foo2
open_some 6602 morgan    6w   REG  254,1        0 262287 /home/morgan/src/foo3
open_some 6602 morgan    7w   REG  254,1        0 262289 /home/morgan/src/foo4
open_some 6602 morgan    8w   REG  254,1        0 262301 /home/morgan/src/foo5
open_some 6602 morgan    9w   REG  254,1        0 262302 /home/morgan/src/foo6
open_some 6602 morgan   10w   REG  254,1        0 262309 /home/morgan/src/foo7
open_some 6602 morgan   11w   REG  254,1        0 262457 /home/morgan/src/foo8
open_some 6602 morgan   12w   REG  254,1        0 268672 /home/morgan/src/foo9

Mais je peux exécuter ce script "ouvrir et rester ouvert" autant de fois que je veux, et il ne changera pas les chiffres dans df/inode-nr.

Donc, en résumé, munin indique le nombre d'inodes alloués, et non le nombre d'inodes utilisés par tous les processus. Si, après avoir supprimé un tas de fichiers, le graphique de munin ne reflète pas les inodes libérés, il se peut que le graphique n'ait pas été généré à nouveau ou, dans l'exemple montré, que l'échelle de temps du graphique soit trop longue pour refléter un changement soudain.

0voto

Jonathan Mayhak Points 4183

Il se peut que si c'est à cause des fichiers journaux, les inodes n'aient pas été libérés lorsque vous les avez nettoyés. Essayez de redémarrer les services qui avaient ces fichiers journaux ouverts, ou vous pourriez être en mesure de vraiment effacer les fichiers journaux sans redémarrage en faisant echo "" > logfilenamegoeshere après avoir sauvegardé toutes les données que vous voulez sauvegarder du journal.

0voto

user279360 Points 11

J'ai trouvé un utilitaire "fatrace" pour "file access trace" sur le site de l'auteur. blogpost disponible pour le téléchargement aquí . Il affichera tous les processus accédant à n'importe quel fichier du système.

SistemesEz.com

SystemesEZ est une communauté de sysadmins où vous pouvez résoudre vos problèmes et vos doutes. Vous pouvez consulter les questions des autres sysadmins, poser vos propres questions ou résoudre celles des autres.

Powered by:

X