Serveur dédié : à la recherche de l’inode perdue ou comment résoudre le problème “no space left on device”

Les inodes perdues ! Cette semaine, j’ai eu droit à un problème particulier sur le serveur : alors que rien dans la configuration des services n’a été changé, je me suis rendu compte que WordPress ne réagissait pas comme d’habitude.

Les symptômes les plus visibles sont la lenteur de l’application, l’impossibilité de mettre à jour ou corriger un article ou encore ajouter des tags à un nouvel article.

J’avais déjà connu cet état lors d’un crash de la base SQL il y a maintenant quelques années donc je me suis dit que j’allais commencer par redémarrer Apache puis réparer la base de données.

Serveur dédié : résoudre le problème "no space left on device" photo

Suppression des instances Apache et redémarrage du service

Dès le lancement de la session SSH, il est évident que quelque chose ne tourne pas rond. Après le message de bienvenue, un message d’erreur apparaît :

/usr/bin/xauth:  error in locking authority file /root/.Xauthority

Et en voulant arrêter Apache, on obtient:

Restarting web server: apache2. [error]
There are processes named 'apache2' running which do not match your pidCode language: JavaScript (javascript)

On commence donc par régler ce problème et on regarde quels sont les PID utilisés par Apache:

pidof apache2

La commande pidof nous retourne toute une liste de pid:

32691 31385 31154 30917 30663 29150 27368 24820 24563 17531 15227 14235 13559 13064 11028 10906 10256 9156 9144 9042 8855 8542

On met fin à toutes ces instances avec un simple kill -9:

kill -9 32691 31385 31154 30917 30663 29150 27368 24820 24563 17531 15227 14235 13559 13064 11028 10906 10256 9156 9144 9042 8855 8542

Une fois toutes les instances d’Apache supprimées, il nous est de nouveau possible de redémarrer le service normalement:

service apache2 restart

Ménage dans l’espace disque et le nombre d’inodes disponibles

Au moment de réparer les tables de la base de données, rebelote, erreur :

No space left on device (error 28)

On commence par un petit ménage dans les paquets obsolètes, qui ne résoudra pas grand-chose:

apt-get autoclean && apt-get autoremoveCode language: JavaScript (javascript)

Je tente un simple df pour vérifier si les disques sont pleins :

df

mais visiblement, non, il reste bien de la place :

Filesystem      Size  Used Avail Use% Mounted on
/dev/root       9.8G  4.4G  5.0G  47% /
devtmpfs        2.0G     0  2.0G   0% /dev
tmpfs           390M  408K  390M   1% /run
tmpfs           5.0M     0  5.0M   0% /run/lock
tmpfs           780M     0  780M   0% /run/shm
/dev/sda2       683G  531G  118G  82% /homeCode language: PHP (php)

Je tente alors un df -i pour vérifier le nombres d’inodes disponibles :

df -i

Un nœud d’index ou inode (contraction de l’anglais index et node) est une structure de données contenant des informations à propos d’un fichier stocké dans les systèmes de fichiers Linux/Unix.

À chaque fichier correspond un numéro d’inode (i-number) dans le système de fichiers dans lequel il réside, unique au périphérique sur lequel il est situé.

Serveur dédié : résoudre le problème "no space left on device" photo 1
Descripteurs de fichiers, table des fichiers et table des inodes sous Linux

Les inodes contiennent notamment les métadonnées des systèmes de fichiers, et en particulier celles concernant les droits d’accès.

Les inodes sont créés lors de la création du système de fichiers. La quantité d’inodes (généralement déterminée lors du formatage et dépendant de la taille de la partition) indique le nombre maximum de fichiers que le système de fichiers peut contenir.

Dans notre cas, catastrophe, il ne reste quasiment plus d’inodes disponibles !

Filesystem     Inodes IUsed IFree IUse% Mounted on
/dev/root        640K  640K     6   100% /
devtmpfs         487K  1.5K  486K    1% /dev
tmpfs            488K   864  487K    1% /run
tmpfs            488K    10  488K    1% /run/lock
tmpfs            488K     2  488K    1% /run/shm
/dev/sda2         44M   37K   43M    1% /home

Il nous faut donc trouver quels sont les répertoires qui pompent toutes nos inodes. Voici comment identifier les répertoires qui en consomment le plus:

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

J’ai répété l’opération jusqu’à me rendre compte que le problème se trouvait dans les milliers de fichiers de session PHP du répertoire /var/lib/php/sessions.

A ce stade, je ne me suis pas posé de questions – les fichiers de session sont par défaut volatiles, ne durant que le temps d’une session (une visite) et peuvent donc être supprimés sans crainte :

find /var/lib/php/sessions -name '*' | xargs rmCode language: JavaScript (javascript)

La suppression totale des fichiers a pris plus de dix minutes. Vous pouvez vous assurer de la suppression en calculant la taille du répertoire :

du -s /var/lib/php/sessionsCode language: JavaScript (javascript)

On relance df -i et là, magie, on a retrouvé un nombre d’inodes disponibles beaucoup plus raisonnable :

Filesystem     Inodes IUsed IFree IUse% Mounted on
/dev/root        640K   81K  560K   13% /
devtmpfs         487K  1.5K  486K    1% /dev
tmpfs            488K   864  487K    1% /run
tmpfs            488K    10  488K    1% /run/lock
tmpfs            488K     2  488K    1% /run/shm
/dev/sda2         44M   37K   43M    1% /home

Nous sommes passés de 100% d’utilisation des inodes à 13%, en supprimant plus de 2 Go de données de sessions PHP.

Pour créer un crontab et automatiser la tâche, rendez-vous sur le tutoriel BASH : supprimer les fichiers de session PHP obsolètes.

Réparation de la base de données SQL

Le système étant redevenu stable et réactif, sans avoir à rebooter le serveur, nous pouvons maintenant réparer nos tables SQL au format InnoDB avec :

mysqlrepair -o -A

Puis redémarrer la base de données :

service mysql restart

Attaquons-nous maintenant à la racine du mal : la configuration PHP.

Configuration des sessions sous PHP

Nous allons éditer notre fichier php.ini pour comprendre pourquoi autant de fichiers de sessions sont créés et surtout pourquoi ils ne sont pas supprimés lorsqu’ils arrivent à expiration.

On commence par trouver le bon fichier php.ini à éditer en créant une page sur le site avec un simple phpinfo().

Il suffit de rechercher la variable Loaded Configuration File :

Loaded Configuration File 	/etc/php/7.0/fpm/php.ini 

On édite php.ini :

nano /etc/php/7.0/fpm/php.ini

et on vérifie/modifie les valeurs suivantes dans la section [session]:

session.save_handler = files
session.save_path = ""
session.gc_probability = 1
session.gc_divisor = 100
session.gc_maxlifetime = 1440
session.lazy_write = OnCode language: JavaScript (javascript)

On sauvegarde le fichier et on redémarre Apache et PHP :

service apache2 restart

Notez que j’avais modifié la valeur de la directive session.save_path il y a quelques mois et lui avait attribué la valeur /var/lib/php/sessions, ce qui est une erreur monumentale.

En effet, par défaut et depuis quelques versions de PHP, cette valeur est “”, c’est-à-dire que les sessions sont stockées dans le répertoire temporaire du système (/tmp).

Conclusion

Voilà, problème résolu. Tout est revenu à la normale et le nombre de sessions est maintenant revenu à un niveau beaucoup plus correct : le nombre d’inodes utilisé est stabilisé.

Gravatar for Matt Biscay

Je suis Matt Biscay, développeur WordPress & WooCommerce certifié chez Codeable, administrateur système et enseignant.

J’aide les entreprises à créer, optimiser et fiabiliser leurs sites WordPress avec une approche technique propre : performance, sécurité, maintenance, développement sur mesure et résolution de problèmes complexes.

Sur Skyminds, je partage des tutoriels WordPress, WooCommerce, Linux et administration système, avec des solutions testées sur des cas réels et pensées pour durer.

Découvrez mes services WordPress et WooCommerce.

Opinions