Comment libérer l'utilisation d'Inode?

276

J'ai un lecteur de disque où l'utilisation d'inode est de 100% (à l'aide de la df -icommande). Cependant, après la suppression substantielle des fichiers, l'utilisation reste à 100%.

Quelle est la bonne façon de procéder alors?

Comment est-il possible qu'un lecteur de disque avec moins d'espace disque puisse avoir une utilisation Inode plus élevée qu'un lecteur de disque avec une utilisation d'espace disque plus élevée?

Est-il possible que le nombre de fichiers compressés réduise le nombre d'inodes utilisés?

neversaint
la source
4
Je veux vous donner 50 points pour cette question. Comment puis-je faire! :)
Sophy
@Sophy Ne fais pas ça. vous serez automatiquement banni
Steven Lu
1
@StevenLu Merci pour vos informations! Je veux lui rendre hommage parce que j'ai passé quelques jours à résoudre mon problème. Mais ce problème peut m'aider. Merci encore,
Sophy
1
@Sophy: pourquoi attribuer quelque chose hors sujet à SO? :) Ce n'est certainement pas une question de programmation, peu importe le nombre de votes positifs qu'il reçoit.
tink
Les répertoires vides consomment également des inodes. Les supprimer peut libérer des inodes. Le nombre peut être significatif dans certains cas d'utilisation. Vous pouvez supprimer des répertoires vides avec: find. -type d -empty -delete
Ruchit Patel

Réponses:

171

Il est assez facile pour un disque d'avoir un grand nombre d'inodes utilisés même si le disque n'est pas très plein.

Un inode est alloué à un fichier, donc, si vous avez des millions de fichiers, tous de 1 octet chacun, vous manquerez d'inodes bien avant de manquer de disque.

Il est également possible que la suppression de fichiers ne réduise pas le nombre d'inodes si les fichiers ont plusieurs liens durs. Comme je l'ai dit, les inodes appartiennent au fichier, pas à l'entrée de répertoire. Si un fichier a deux entrées de répertoire liées, la suppression d'une ne libérera pas l'inode.

De plus, vous pouvez supprimer une entrée de répertoire mais, si un processus en cours a toujours le fichier ouvert, l'inode ne sera pas libéré.

Mon premier conseil serait de supprimer tous les fichiers que vous pouvez, puis de redémarrer la boîte pour vous assurer qu'aucun processus ne laisse les fichiers ouverts.

Si vous faites cela et que vous avez toujours un problème, faites-le nous savoir.

Soit dit en passant, si vous recherchez les répertoires contenant de nombreux fichiers, ce script peut vous aider:

#!/bin/bash
# count_em - count files in all subdirectories under current directory.
echo 'echo $(ls -a "$1" | wc -l) $1' >/tmp/count_em_$$
chmod 700 /tmp/count_em_$$
find . -mount -type d -print0 | xargs -0 -n1 /tmp/count_em_$$ | sort -n
rm -f /tmp/count_em_$$
paxdiablo
la source
12
Bien sûr, >/tmp/count_em_$$cela ne fonctionnera que si vous avez de la place ... si c'est le cas, voir la réponse de @ simon.
alxndr
1
@alxndr, c'est pourquoi c'est souvent une bonne idée de garder vos systèmes de fichiers séparés - de cette façon, remplir quelque chose comme ça /tmpn'affectera pas vos autres systèmes de fichiers.
paxdiablo
Votre réponse est parfaitement adaptée à "le système ne restera pas utiliser le fichier après le redémarrage s'il a été supprimé". Mais la question a été posée: "comment récupérer ou réutiliser les inodes après la suppression du pointeur d'inode?". Fondamentalement, le noyau Linux crée un nouvel inode dans un fichier chaque fois qu'il est créé et ne récupère pas automatiquement l'inode chaque fois que vous supprimez un fichier.
Mohanraj
1
@AshishKarpe, je suppose que vous parlez de votre propre situation puisque l'OP n'a fait aucune mention des serveurs de production. Si vous ne pouvez pas redémarrer immédiatement, il y a deux possibilités. Tout d'abord, espérons que les processus en cours finiront par fermer les fichiers actuels afin que les ressources du disque puissent être libérées. Deuxièmement, même les serveurs de production devraient avoir la possibilité de redémarrer à un moment donné - il suffit de planifier un temps d'arrêt planifié ou d'attendre la prochaine fenêtre de temps d'arrêt.
paxdiablo
2
Je suppose que tu veux ls -Aau lieu de ls -a. Pourquoi voudriez-vous compter. et ..?
jarno
205

Si vous n'avez pas de chance, vous avez utilisé environ 100% de tous les inodes et ne pouvez pas créer le scipt. Vous pouvez vérifier cela avec df -ih.

Cette commande bash peut alors vous aider:

sudo find . -xdev -type f | cut -d "/" -f 2 | sort | uniq -c | sort -n

Et oui, cela prendra du temps, mais vous pouvez localiser le répertoire contenant le plus de fichiers.

Simon
la source
8
ça fait l'affaire. mon problème était d'avoir une quantité incroyable de sessions dans le répertoire / lib / php / sessions. peut-être que quelqu'un a le même problème
SteMa
2
Quelqu'un devrait réécrire ce tri find, cut, uniq en une seule commande awk!
mogsie
5
@alxndr awkpourrait conserver un hachage du répertoire et le nombre de fichiers sans unifier et trier un gazillion de lignes. Cela dit, voici peut-être une amélioration: find . -maxdepth 1 -type d | grep -v '^\.$' | xargs -n 1 -i{} find {} -xdev -type f | cut -d "/" -f 2 | uniq -c | sort -n- cela ne trie que la dernière liste.
mogsie
12
Si vous ne pouvez pas créer de fichiers, même cela peut échouer car il est sortpossible que tout ne soit pas conservé en mémoire et essaiera de revenir automatiquement à l'écriture d'un fichier temporaire. Un processus qui échouera évidemment ...
Mikko Rantalainen
10
sorta échoué pour moi, mais j'ai pu donner --buffer-size=10Gce qui a fonctionné.
Frederick Nord
69

Ma situation était que je n'avais plus d'inodes et j'avais déjà supprimé tout ce que je pouvais.

$ df -i
Filesystem     Inodes  IUsed  IFree IUse% Mounted on
/dev/sda1      942080 507361     11  100% /

Je suis sur un Ubuntu 12.04LTS et je n'ai pas pu supprimer les anciens noyaux Linux qui occupaient environ 400 000 inodes car apt était cassé à cause d'un paquet manquant. Et je n'ai pas pu installer le nouveau paquet parce que j'étais à court d'inodes donc j'étais coincé.

J'ai fini par supprimer quelques anciens noyaux Linux à la main pour libérer environ 10 000 inodes

$ sudo rm -rf /usr/src/linux-headers-3.2.0-2*

C'était suffisant pour ensuite me laisser installer le paquet manquant et réparer mon apt

$ sudo apt-get install linux-headers-3.2.0-76-generic-pae

puis supprimez le reste des anciens noyaux Linux avec apt

$ sudo apt-get autoremove

les choses vont beaucoup mieux maintenant

$ df -i
Filesystem     Inodes  IUsed  IFree IUse% Mounted on
/dev/sda1      942080 507361 434719   54% /
LNamba
la source
3
C'était la plus proche de ma propre approche dans une situation similaire. Il convient de noter qu'une approche plus prudente est bien documentée sur help.ubuntu.com/community/Lubuntu/Documentation/…
beldaz
Mon cas exactement! Mais j'ai dû utiliser "sudo apt-get autoremove -f" pour progresser
Tony Sepia
Est-il sûr de faire ceci:, sudo rm -rf /usr/src/linux-headers-3.2.0-2*si je suis sûr que je n'utilise pas ce noyau?
Mars Lee
@MarsLee Vous pouvez vérifier quel noyau est actuellement en cours d'exécution avec "uname -a"
Dominique Eav
Appeler $ sudo apt-get autoremoveseul, a fait l'affaire pour moi.
Morten Grum
49

Ma solution:

Essayez de trouver s'il s'agit d'un problème d'inodes avec:

df -ih

Essayez de trouver des dossiers racine avec un grand nombre d'inodes:

for i in /*; do echo $i; find $i |wc -l; done

Essayez de trouver des dossiers spécifiques:

for i in /src/*; do echo $i; find $i |wc -l; done

S'il s'agit d'en-têtes Linux, essayez de supprimer les plus anciens avec:

sudo apt-get autoremove linux-headers-3.13.0-24

Personnellement, je les ai déplacés vers un dossier monté (car pour moi la dernière commande a échoué) et j'ai installé la dernière avec:

sudo apt-get autoremove -f

Cela a résolu mon problème.

dardarlt
la source
1
Dans mon cas, le problème était SpamAssasin-Temp. find /var/spool/MailScanner/incoming/SpamAssassin-Temp -mtime +1 -print | xargs rm -fa fait le travail :) Merci!
joystick
4
Pour moi, cela prenait des heures. Cependant, il existe une solution simple: lorsque la deuxième commande se bloque sur un répertoire particulier, supprimez la commande actuelle et recommencez à remplacer / * par le répertoire sur lequel elle était suspendue. J'ai pu descendre jusqu'au coupable <minute.
Michael Terry
J'ai utilisé cette variante de votre commande afin d'imprimer les chiffres sur la même ligne: for i in /usr/src/*; do echo -en "$i\t"; find $i 2>/dev/null |wc -l; done
cscracker
for i in /src/*; do echo "$i, `find $i |wc -l`"; done|sort -nrk 2|head -10montrer le top 10 du plus grand répertoire
Mark Simon
12

J'ai eu le même problème, je l'ai résolu en supprimant les sessions d'annuaire de php

rm -rf /var/lib/php/sessions/

Il peut être inférieur /var/lib/php5si vous utilisez une ancienne version de php.

Recréez-le avec l'autorisation suivante

mkdir /var/lib/php/sessions/ && chmod 1733 /var/lib/php/sessions/

L'autorisation par défaut pour le répertoire sur Debian a été montrée drwx-wx-wt(1733)

Anyone_ph
la source
1
Une idée pourquoi cela se produit?
Sibidharan
1
@Sibidharan dans mon cas, c'était parce que le travail cron PHP pour effacer les anciennes sessions PHP ne fonctionnait pas.
sinistre
3
rm -rf /var/lib/php/sessions/*serait probablement une meilleure commande - elle ne supprimera pas le répertoire de la session, juste son contenu ... Ensuite, vous n'avez pas à vous soucier de le recréer
Shadow
Je n'ai pas eu de session php mais un problème de session magento, similaire à celui-ci. Merci pour la direction.
Mohit
les sessions php ne doivent pas s'effacer via les tâches cron, définissez session.gc_maxlifetime dans php.ini php.net/manual/en/…
2

Nous l'avons constaté sur un compte HostGator (qui place des limites d'inode sur tous leurs hébergements) suite à une attaque de spam. Il a laissé un grand nombre d'enregistrements de file d'attente dans /root/.cpanel/comet. Si cela se produit et que vous constatez que vous n'avez pas d'inodes libres, vous pouvez exécuter cet utilitaire cpanel via shell:

/usr/local/cpanel/bin/purge_dead_comet_files
designgroop
la source
2

Vous pouvez utiliser RSYNC pour SUPPRIMER le grand nombre de fichiers

rsync -a --delete blanktest/ test/

Créez un dossier vierge avec 0 fichier et la commande synchronisera vos dossiers de test avec un grand nombre de fichiers (j'ai supprimé près de 5 millions de fichiers en utilisant cette méthode).

Merci à http://www.slashroot.in/which-is-the-fastest-method-to-delete-files-in-linux

VIGNESH
la source
D'après ce que je peux dire de l'article / commentaires, c'est plus rapide que rm *pour beaucoup de fichiers, en raison de l'expansion du caractère générique et de la transmission / du traitement de chaque argument, mais rm test/c'est bien pour supprimer un test/dossier contenant beaucoup de fichiers.
mwfearnley
Attention, cela fonctionne bien, mais assurez-vous de définir correctement les autorisations sur le répertoire vierge! Je ne l'ai pas fait et j'ai modifié par inadvertance les autorisations sur mon répertoire de sessions PHP. Il a fallu deux heures pour comprendre ce que j'ai raté.
aecend
1

eaccelerator pourrait être à l'origine du problème car il compile PHP en blocs ... J'ai eu ce problème avec un serveur Amazon AWS sur un site à forte charge. Libérez des inodes en supprimant le cache eaccelerator dans / var / cache / eaccelerator si vous continuez à rencontrer des problèmes.

rm -rf /var/cache/eaccelerator/*

(ou quel que soit votre répertoire cache)

supershwa
la source
1

Nous avons récemment rencontré un problème similaire.Si un processus fait référence à un fichier supprimé, l'inode ne doit pas être libéré, vous devez donc vérifier lsof / et tuer / redémarrer le processus libérera les inodes.

Corrigez-moi si je me trompe ici.

Razal
la source
1

Comme indiqué précédemment, le système de fichiers peut manquer d'inodes, s'il y a beaucoup de petits fichiers. J'ai fourni quelques moyens pour trouver des répertoires contenant la plupart des fichiers ici .

jarno
la source
0

Réponse tardive: dans mon cas, c'était mes fichiers de session sous

/var/lib/php/sessions

qui utilisaient des inodes.
Je n'ai même pas pu ouvrir ma crontab ou créer un nouveau répertoire et encore moins déclencher l'opération de suppression. Depuis que j'utilise PHP, nous avons ce guide où j'ai copié le code de l'exemple 1 et mis en place un cronjob pour exécuter cette partie du code.

<?php
// Note: This script should be executed by the same user of web server 
process.

// Need active session to initialize session data storage access.
session_start();

// Executes GC immediately
session_gc();

// Clean up session ID created by session_gc()
session_destroy();
?>

Si vous vous demandez comment ai-je réussi à ouvrir mon crontab, eh bien, j'ai supprimé certaines sessions manuellement via CLI.

J'espère que cela t'aides!

Han
la source
0

vous pouvez voir cette info

for i in /var/run/*;do echo -n "$i "; find $i| wc -l;done | column -t
张馆长
la source
-2

Jusqu'à présent, de nombreuses réponses à celle-ci et toutes les réponses ci-dessus semblent concrètes. Je pense que vous serez en sécurité en utilisant au statfur et à mesure, mais selon le système d'exploitation, vous pouvez obtenir des erreurs d'inode sur vous. Donc, l'implémentation de votre propre statfonctionnalité d'appel en utilisant 64bitpour éviter tout problème de débordement semble assez compatible.

kinokaf
la source
nous aimons les exemples ici à so;)
Bohne
-3

Si vous utilisez Docker, supprimez toutes les images. Ils ont utilisé beaucoup d'espace ....

Arrêtez tous les conteneurs

docker stop $(docker ps -a -q)

Supprimer tous les conteneurs

docker rm $(docker ps -a -q)

Supprimer toutes les images

docker rmi $(docker images -q)

Fonctionne pour moi

Pankaj Shinde
la source
Cela n'aide pas à détecter si "trop ​​d'inodes" sont le problème.
Mark Stosberg
Cela n'a rien à voir avec Docker.
Urda