web-dev-qa-db-fra.com

Trouvez où les inodes sont utilisés

J'ai donc reçu un avertissement de notre système de surveillance sur l'un de nos boîtiers indiquant que le nombre d'inodes libres sur un système de fichiers devenait faible.

df -i la sortie montre ceci:

Filesystem       Inodes  IUsed    IFree IUse% Mounted on
/dev/xvda1       524288 422613   101675   81% /

Comme vous pouvez le voir, la partition racine a 81% de ses inodes utilisés.
Je soupçonne qu'ils sont tous utilisés dans un seul répertoire. Mais comment puis-je trouver où cela se trouve?

201
Patrick

J'ai vu cette question sur stackoverflow, mais je n'ai aimé aucune des réponses, et c'est vraiment une question qui devrait être ici sur U&L de toute façon.

Fondamentalement, un inode est utilisé pour chaque fichier du système de fichiers. Donc, manquer d'inodes signifie généralement que vous avez beaucoup de petits fichiers qui traînent. Donc, la question devient vraiment: "quel répertoire contient un grand nombre de fichiers?"

Dans ce cas, le système de fichiers qui nous intéresse est le système de fichiers racine /, nous pouvons donc utiliser la commande suivante:

find / -xdev -printf '%h\n' | sort | uniq -c | sort -k 1 -n

Cela affichera une liste de chaque répertoire du système de fichiers préfixé avec le nombre de fichiers (et sous-répertoires) dans ce répertoire. Ainsi, le répertoire avec le plus grand nombre de fichiers sera en bas.

Dans mon cas, cela se présente comme suit:

   1202 /usr/share/man/man1
   2714 /usr/share/man/man3
   2826 /var/lib/dpkg/info
 306588 /var/spool/postfix/maildrop

Donc en gros /var/spool/postfix/maildrop consomme tous les inodes.

Remarque, cette réponse comporte trois mises en garde auxquelles je peux penser. Il ne gère rien correctement avec des retours à la ligne dans le chemin. Je sais que mon système de fichiers n'a pas de fichiers avec des retours à la ligne, et comme cela n'est utilisé que pour la consommation humaine, le problème potentiel ne vaut pas la peine d'être résolu (et on peut toujours remplacer le \n avec \0 et utilise sort -z au dessus de). Il ne gère pas non plus si les fichiers sont répartis sur un grand nombre de répertoires. Ce n'est cependant pas probable, donc je considère le risque comme acceptable. Il comptera également les liens durs vers un même fichier (donc en utilisant un seul inode) plusieurs fois. Encore une fois, il est peu probable de donner de faux positifs


La raison principale pour laquelle je n'ai aimé aucune des réponses de la réponse stackoverflow est qu'elles traversent toutes les limites du système de fichiers. Étant donné que mon problème concernait le système de fichiers racine, cela signifie qu'il traverserait tous les systèmes de fichiers montés. Lancer -xdev sur les commandes find ne fonctionnerait même pas correctement.
Par exemple, la réponse la plus votée est celle-ci:

for i in `find . -type d `; do echo `ls -a $i | wc -l` $i; done | sort -n

Si nous changeons cela à la place

for i in `find . -xdev -type d `; do echo `ls -a $i | wc -l` $i; done | sort -n

même si /mnt/foo est un montage, c'est aussi un répertoire sur le système de fichiers racine, donc il apparaîtra dans find . -mount -type d, puis il sera transmis au ls -a $i, qui plongera dans la monture.

Le find dans ma réponse répertorie à la place le répertoire de chaque fichier sur le montage. Donc, fondamentalement, avec une structure de fichiers telle que:

/foo/bar
/foo/baz
/pop/tart

on se retrouve avec

/foo
/foo
/pop

Il suffit donc de compter le nombre de lignes en double.

223
Patrick

Ceci est republié de ici à la demande du demandeur:

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

Et si vous voulez rester dans le même système de fichiers que vous:

du --inodes -xS

Voici quelques exemples de sortie:

15K     /usr/share/man/man3
4.0K    /usr/lib
3.6K    /usr/bin
2.4K    /usr/share/man/man1
1.9K    /usr/share/fonts/75dpi
...
519     /usr/lib/python2.7/site-packages/bzrlib
516     /usr/include/KDE
498     /usr/include/qt/QtCore
487     /usr/lib/modules/3.13.6-2-MANJARO/build/include/config
484     /usr/src/linux-3.12.14-2-MANJARO/include/config

MAINTENANT AVEC LS:

Plusieurs personnes ont indiqué qu'elles n'avaient pas de coreutils à jour et que l'option --inodes ne leur était pas disponible. Alors, voici ls:

ls ~/test -AiR1U | 
sed -rn '/^[./]/{h;n;};G;
    s|^ *([0-9][0-9]*)[^0-9][^/]*([~./].*):|\1:\2|p' | 
sort -t : -uk1.1,1n |
cut -d: -f2 | sort -V |
uniq -c |sort -rn | head -n10

Si vous êtes curieux, le cœur et l'âme de ce morceau fastidieux de regex remplace les filename dans chacun des résultats de recherche récursive ls's Par le nom du répertoire dans dont il a été trouvé. À partir de là, il suffit de presser les numéros d'inode répétés, puis de compter les noms de répertoire répétés et de les trier en conséquence.

L'option -U Est particulièrement utile pour le tri dans la mesure où elle trie spécifiquement et non , et présente à la place la liste des répertoires dans l'ordre d'origine - ou, en d'autres termes, par inode numéro.

Et bien sûr, -1 Est incroyablement utile en ce qu'il garantit un seul résultat par ligne, indépendamment des nouvelles lignes éventuellement incluses dans les noms de fichiers ou d'autres problèmes spectaculairement malheureux qui peuvent survenir lorsque vous essayez d'analyser une liste.

Et bien sûr -A Pour tous et -i Pour inode et -R Pour récursif et c'est le long et le court.

La méthode sous-jacente à cela est que je remplace chacun des noms de fichiers de ls par son nom de répertoire contenant dans sed. À la suite de ça ... Eh bien, je suis un peu flou moi-même. Je suis assez certain qu'il compte précisément les fichiers, comme vous pouvez le voir ici:

% _ls_i ~/test
> 100 /home/mikeserv/test/realdir
>   2 /home/mikeserv/test
>   1 /home/mikeserv/test/linkdir

Cela me donne des résultats à peu près identiques à la commande du:

DU:

15K     /usr/share/man/man3
4.0K    /usr/lib
3.6K    /usr/bin
2.4K    /usr/share/man/man1
1.9K    /usr/share/fonts/75dpi
1.9K    /usr/share/fonts/100dpi
1.9K    /usr/share/doc/Arch-wiki-markdown
1.6K    /usr/share/fonts/TTF
1.6K    /usr/share/dolphin-emu/sys/GameSettings
1.6K    /usr/share/doc/efl/html

LS:

14686   /usr/share/man/man3:
4322    /usr/lib:
3653    /usr/bin:
2457    /usr/share/man/man1:
1897    /usr/share/fonts/100dpi:
1897    /usr/share/fonts/75dpi:
1890    /usr/share/doc/Arch-wiki-markdown:
1613    /usr/include:
1575    /usr/share/doc/efl/html:
1556    /usr/share/dolphin-emu/sys/GameSettings:

Je pense que la chose include dépend juste du répertoire dans lequel le programme regarde en premier - car ce sont les mêmes fichiers et liés. Un peu comme la chose ci-dessus. Je peux me tromper cependant - et je me réjouis de la correction ...

DU DEMO

% du --version
> du (GNU coreutils) 8.22

Créez un répertoire de test:

% mkdir ~/test ; cd ~/test
% du --inodes -S
> 1       .

Quelques répertoires enfants:

% mkdir ./realdir ./linkdir
% du --inodes -S
> 1       ./realdir
> 1       ./linkdir
> 1       .

Créez des fichiers:

% printf 'touch ./realdir/file%s\n' `seq 1 100` | . /dev/stdin
% du --inodes -S
> 101     ./realdir
> 1       ./linkdir
> 1       .

Quelques liens physiques:

% printf 'n="%s" ; ln ./realdir/file$n ./linkdir/link$n\n' `seq 1 100` | 
    . /dev/stdin
% du --inodes -S
> 101     ./realdir
> 1       ./linkdir
> 1       .

Regardez les liens physiques:

% cd ./linkdir
% du --inodes -S
> 101

% cd ../realdir
% du --inodes -S
> 101

Ils sont comptés seuls, mais remontez d'un répertoire ...

% cd ..
% du --inodes -S
> 101     ./realdir
> 1       ./linkdir
> 1       .

Ensuite, j'ai exécuté mon script d'exécution par le bas et:

> 100     /home/mikeserv/test/realdir
> 100     /home/mikeserv/test/linkdir
> 2       /home/mikeserv/test

Et Graeme:

> 101 ./realdir
> 101 ./linkdir
> 3 ./

Je pense donc que cela montre que la seule façon de compter les inodes est par inode. Et parce que compter des fichiers signifie compter des inodes, vous ne pouvez pas compter doublement les inodes - pour compter les fichiers avec précision, les inodes ne peuvent pas être comptés plus d'une fois.

27
mikeserv

J'ai utilisé cette réponse de SO Q&A intitulée: Où sont tous mes inodes utilisés? lorsque notre NAS a manqué environ 2 ans depuis:

$ find . -type d -print0 \
    | while IFS= read -rd '' i; do echo $(ls -a "$i" | wc -l) "$i"; done \
    | sort -n

Exemple

$ find . -type d -print0 \
    | while IFS= read -rd '' i; do echo $(ls -a "$i" | wc -l) "$i"; done \
    | sort -n
...
110 ./MISC/nodejs/node-v0.8.12/out/Release/obj.target/v8_base/deps/v8/src
120 ./MISC/nodejs/node-v0.8.12/doc/api
123 ./apps_archive/monitoring/nagios/nagios-check_sip-1.3/usr/lib64/nagios
208 ./MISC/nodejs/node-v0.8.12/deps/openssl/openssl/doc/crypto
328 ./MISC/nodejs/node-v0.8.12/deps/v8/src
453 ./MISC/nodejs/node-v0.8.12/test/simple

Vérification des inodes de l'appareil

En fonction de votre NAS il peut ne pas offrir une commande df complète. Ainsi, dans ces cas, vous pouvez recourir à l'utilisation de tune2fs au lieu:

$ Sudo tune2fs -l /dev/sda1 |grep -i inode
Filesystem features:      has_journal ext_attr resize_inode dir_index filetype needs_recovery extent flex_bg sparse_super huge_file uninit_bg dir_nlink extra_isize
Inode count:              128016
Free inodes:              127696
Inodes per group:         2032
Inode blocks per group:   254
First inode:              11
Inode size:           128
Journal inode:            8
Journal backup:           inode blocks

Traverser les limites du système de fichiers

Vous pouvez utiliser le -xdev basculez sur direct find pour restreindre la recherche uniquement à l'appareil sur lequel vous lancez la recherche.

Exemple

Dis que j'ai mon /home montage automatique de répertoire via des partages NFS depuis mon NAS, dont le nom est mulder.

$ df -h /home/sam 
Filesystem            Size  Used Avail Use% Mounted on
mulder:/export/raid1/home/sam
                      917G  572G  299G  66% /home/sam

Notez que le point de montage est toujours considéré comme local sur le système.

$ df -h /home/ .
Filesystem            Size  Used Avail Use% Mounted on
-                        0     0     0   -  /home
/dev/mapper/VolGroup00-LogVol00
                      222G  159G   52G  76% /

Maintenant, quand j'initie find:

$ find / -xdev  | grep '^/home'
/home

Il a trouvé /home mais aucun des contenus montés automatiquement car ils sont sur un appareil différent!

Types de systèmes de fichiers

Vous pouvez utiliser le commutateur sur find, -fstype pour contrôler dans quel type de systèmes de fichiers find se penchera.

   -fstype type
          File is on a filesystem of type type.  The valid filesystem types 
          vary among different versions of Unix; an incomplete list of 
          filesystem  types that are accepted on some version of Unix or 
          another is: ufs, 4.2, 4.3, nfs, tmp, mfs, S51K, S52K.  You can use 
          -printf with the %F directive to see the types of your
          filesystems.

Exemple

Quels systèmes de fichiers ai-je?

$ find . -printf "%F\n" | sort -u
ext3

Vous pouvez donc l'utiliser pour contrôler la traversée:

uniquement ext3

$ find . -fstype ext3 | head -5
.
./gdcm
./gdcm/gdcm-2.0.16
./gdcm/gdcm-2.0.16/Wrapping
./gdcm/gdcm-2.0.16/Wrapping/CMakeLists.txt

uniquement nfs

$ find . -fstype nfs | head -5
$ 

ext3 & ext4

$ find . -fstype ext3 -o -fstype ext4 | head -5
.
./gdcm
./gdcm/gdcm-2.0.16
./gdcm/gdcm-2.0.16/Wrapping
./gdcm/gdcm-2.0.16/Wrapping/CMakeLists.txt
6
slm

Commande pour trouver l'inode utilisé:

for i in /*; do echo $i; find $i |wc -l | sort ; done
5
Ashish Karpe

Je le trouve plus rapide et plus facile à explorer en utilisant la commande suivante:

$ Sudo du -s --inodes * | sort -rn

170202  var
157325  opt
103134  usr
53383   tmp
<snip>

Vous pouvez ensuite aller dans var par exemple et voir ce que contient le gros inode utilisant les répertoires.

4
JonoB

Pour répertorier l'utilisation détaillée des inodes pour /, utilisez la commande suivante:

echo "Detailed Inode usage for: $(pwd)" ; for d in `find -maxdepth 1 -type d |cut -d\/ -f2 |grep -xv . |sort`; do c=$(find $d |wc -l) ; printf "$c\t\t- $d\n" ; done ; printf "Total: \t\t$(find $(pwd) | wc -l)\n" 
3
user108434

Répondez certainement avec un maximum de votes positifs pour comprendre le concept des inodes sous linux et unix, mais cela n'aide pas vraiment quand il s'agit de résoudre le problème réel de la suppression ou de la suppression des inodes du disque. Un moyen plus simple de le faire sur les systèmes basés sur Ubuntu consiste à supprimer les en-têtes et les images indésirables du noyau Linux.

Sudo apt-get autoremove

Je ferais ça pour toi. Dans mon cas, l'utilisation des inodes était à 78%, raison pour laquelle j'ai reçu une alerte.

$ df -i
Filesystem     Inodes  IUsed  IFree IUse% Mounted on
/dev/xvda1     524288 407957 116331   78% /
none           957443      2 957441    1% /sys/fs/cgroup
udev           956205    388 955817    1% /dev
tmpfs          957443    320 957123    1% /run
none           957443      1 957442    1% /run/lock
none           957443      1 957442    1% /run/shm
none           957443      5 957438    1% /run/user

Après avoir exécuté Sudo apt-get autoremove commande, il était descendu à 29%

$ df -i
Filesystem     Inodes  IUsed  IFree IUse% Mounted on
/dev/xvda1     524288 150472 373816   29% /
none           957443      2 957441    1% /sys/fs/cgroup
udev           956205    388 955817    1% /dev
tmpfs          957443    320 957123    1% /run
none           957443      1 957442    1% /run/lock
none           957443      1 957442    1% /run/shm
none           957443      5 957438    1% /run/user

Ce n'est que mon observation qui m'a fait gagner du temps. Les gens peuvent trouver une meilleure solution que cela.

2
Shailesh Sutar

Jusqu'à présent, chaque réponse suppose que le problème provient de nombreux fichiers dans un seul répertoire, au lieu de nombreux sous-répertoires contribuant tous au problème. Heureusement, la solution consiste à simplement utiliser moins de drapeaux.

# du --inodes --one-file-system /var | sort --numeric-sort
...
2265    /var/cache/salt/minion
3818    /var/lib/dpkg/info
3910    /var/lib/dpkg
4000    /var/cache/salt/master/gitfs/refs
4489    /var/lib
5709    /var/cache/salt/master/gitfs/hash
12954   /var/cache/salt/master/gitfs
225058  /var/cache/salt/master/jobs
241678  /var/cache/salt/master
243944  /var/cache/salt
244078  /var/cache
248949  /var

Ou avec des options plus courtes: du --inodes -x | sort -n. Malheureusement, toutes les versions de du n'ont pas l'option inodes.

0
OrangeDog