Erreur MySQL : Le Serveur a Quitté Sans Mettre à Jour le Fichier PID — Guide Complet de Diagnostic et de Correction
L’erreur "The server quit without updating PID file" signifie que MySQL s’est arrêté avant de pouvoir écrire son identifiant de processus dans le fichier `.pid` configuré — un arrêt brutal qui empêche le daemon d’accepter des connexions. Cette défaillance est presque toujours le symptôme d’un problème plus profond : une mauvaise configuration dans `my.cnf`, une incompatibilité de permissions sur le répertoire de données, une partition disque pleine, une corruption au niveau des tables, ou un conflit de port avec une seconde instance MySQL ou MariaDB.
Ce guide passe en revue chaque cause racine confirmée, fournit les commandes shell exactes pour diagnostiquer et réparer chacune d’elles, et couvre les cas particuliers que les tutoriels génériques omettent systématiquement.
Ce que fait réellement le fichier PID et pourquoi son absence est importante
MySQL écrit son identifiant de processus (PID) dans un petit fichier texte brut — généralement `/var/run/mysqld/mysqld.pid` — immédiatement après l’initialisation du daemon. Les systèmes init, les gestionnaires de services (systemd, SysVinit) et les outils de surveillance lisent ce fichier pour envoyer des signaux au bon processus. Si MySQL plante, se termine anormalement ou rencontre une erreur fatale au démarrage, il n’atteint jamais le point d’écriture de ce fichier. Le gestionnaire de services signale alors le message "quit without updating PID file".
Comprendre cette séquence est essentiel : l’erreur du fichier PID est une *conséquence*, pas la cause racine. Chercher à résoudre le problème du fichier PID lui-même sans lire d’abord le journal d’erreurs est l’erreur la plus courante que commettent les administrateurs.
Causes racines courantes en un coup d’œil
| Cause racine | Symptôme typique dans le journal d’erreurs | Systèmes concernés |
|---|---|---|
| — | — | — |
| Chemin `pid-file` incorrect dans `my.cnf` | `Can't start server: can't create PID file` | Toutes les distributions |
| Propriété incorrecte sur `/var/run/mysqld` | `Permission denied` sur le répertoire PID | Debian/Ubuntu après mises à jour |
| Disque plein ou épuisement des inodes | `No space left on device` | Tout serveur avec un petit `/var` |
| Corruption de `ibdata1` ou des journaux redo InnoDB | `InnoDB: Corruption detected` | MySQL 5.7, 8.0, MariaDB |
| Fichier `.pid` obsolète d’un crash précédent | `A mysqld process already exists` | Tout système après un redémarrage brutal |
| Port 3306 déjà utilisé | `Can't start server: Bind on TCP/IP port` | Configurations multi-instances |
| Refus de politique AppArmor ou SELinux | `apparmor="DENIED"` dans syslog | Ubuntu, RHEL/CentOS |
| `datadir` incompatible après mise à jour du paquet | `[ERROR] Fatal error: Can't open and lock privilege tables` | Mises à jour de version majeure |
Étape 1 — Lire d’abord le journal d’erreurs MySQL
Toutes les autres étapes dépendent de ce que dit le journal d’erreurs. Ne sautez pas cette étape.
“`bash
Debian/Ubuntu default path
sudo tail -100 /var/log/mysql/error.log
RHEL/CentOS/AlmaLinux default path
sudo tail -100 /var/log/mysqld.log
If you are unsure of the path, query the running config
mysqld –verbose –help 2>/dev/null | grep "log-error"
“`
Recherchez les lignes contenant `[ERROR]`, `[FATAL]`, `Aborting` ou `InnoDB`. La première entrée `[ERROR]` dans la séquence de démarrage est presque toujours la véritable cause.
Étape 2 — Vérifier et corriger le répertoire du fichier PID
Le répertoire PID est souvent recréé avec la propriété `root` après un redémarrage du système car `/var/run` est un montage `tmpfs` sur les distributions Linux modernes. C’est l’une des causes les plus fréquemment négligées sur Ubuntu 20.04+ et Debian 11+.
“`bash
Check current ownership
ls -ld /var/run/mysqld
Recreate the directory with correct ownership
sudo mkdir -p /var/run/mysqld
sudo chown mysql:mysql /var/run/mysqld
sudo chmod 755 /var/run/mysqld
“`
Pour rendre cela persistant après les redémarrages sur les systèmes systemd, créez une règle `tmpfiles.d` :
“`bash
echo "d /var/run/mysqld 0755 mysql mysql -" | sudo tee /etc/tmpfiles.d/mysqld.conf
“`
Confirmez que le chemin PID configuré dans `my.cnf` correspond au répertoire que vous venez de créer :
“`bash
sudo grep -i "pid" /etc/mysql/my.cnf /etc/mysql/mysql.conf.d/*.cnf 2>/dev/null
“`
Étape 3 — Auditer la propriété et les permissions du répertoire de données
Le répertoire de données de MySQL doit être entièrement détenu par l’utilisateur système `mysql`. Les mises à jour de paquets, les copies manuelles de fichiers ou les restaurations depuis une sauvegarde brisent fréquemment cela.
“`bash
Correct ownership recursively
sudo chown -R mysql:mysql /var/lib/mysql
Correct permissions — directories 750, files 640 is more secure than 755/644
sudo find /var/lib/mysql -type d -exec chmod 750 {} ;
sudo find /var/lib/mysql -type f -exec chmod 640 {} ;
“`
Cas particulier important : Si vous avez restauré une sauvegarde en utilisant `rsync` ou `cp` en tant que `root`, le fichier socket `/var/lib/mysql/mysql.sock` peut également appartenir à root. Supprimez-le — MySQL le recréera au démarrage :
“`bash
sudo rm -f /var/lib/mysql/mysql.sock
sudo rm -f /var/run/mysqld/mysqld.sock
“`
Étape 4 — Vérifier l’espace disque et la disponibilité des inodes
Un disque plein empêche silencieusement MySQL d’écrire tout fichier, y compris le fichier PID et les journaux binaires.
“`bash
Check disk space
df -h
Check inode usage — often overlooked
df -i
Find the largest directories consuming space
sudo du -sh /var/lib/mysql/* | sort -rh | head -20
“`
Si la partition est pleine, les coupables habituels sont les journaux binaires (`mysql-bin.000*`), les journaux de requêtes généraux laissés activés par inadvertance, ou les fichiers core dump. Pour purger en toute sécurité les anciens journaux binaires depuis MySQL :
“`bash
mysql -u root -p -e "PURGE BINARY LOGS BEFORE DATE_SUB(NOW(), INTERVAL 7 DAY);"
“`
Étape 5 — Éliminer les fichiers PID obsolètes et les processus en conflit
Après une panique du noyau, une coupure de courant ou `kill -9`, un fichier PID obsolète peut rester sur le disque. MySQL refuse de démarrer s’il en trouve un.
“`bash
Check for a stale PID file
cat /var/run/mysqld/mysqld.pid
Verify whether that PID is actually running
ps aux | grep mysqld
If the process is not running but the file exists, remove it
sudo rm -f /var/run/mysqld/mysqld.pid
“`
Si une autre instance MySQL ou MariaDB est réellement en cours d’exécution et occupe le port 3306 :
“`bash
sudo ss -tlnp | grep 3306
sudo systemctl stop mariadb
sudo systemctl stop mysql
sudo killall -9 mysqld mysqld_safe
“`
Attendez trois secondes après avoir arrêté les processus avant de tenter un redémarrage pour permettre aux états TIME_WAIT des sockets du noyau de se vider.
Étape 6 — Vérifier les politiques AppArmor et SELinux
Cette cause n’est presque jamais mentionnée dans les tutoriels de base, pourtant elle est responsable d’un pourcentage significatif des erreurs de fichier PID sur Ubuntu et les systèmes de la famille RHEL.
Ubuntu / AppArmor :
“`bash
sudo dmesg | grep -i apparmor | grep -i mysql
sudo grep -i "DENIED" /var/log/syslog | grep mysql
“`
Si AppArmor bloque MySQL, mettez à jour le profil ou définissez-le temporairement en mode plainte pour le diagnostic :
“`bash
sudo aa-complain /usr/sbin/mysqld
“`
RHEL / CentOS / AlmaLinux — SELinux :
“`bash
sudo ausearch -c 'mysqld' –raw | audit2why
sudo sealert -a /var/log/audit/audit.log | grep mysqld
“`
Un correctif courant pour les problèmes de contexte SELinux après le déplacement du répertoire de données :
“`bash
sudo semanage fcontext -a -t mysqld_db_t "/new/datadir(/.*)?"
sudo restorecon -Rv /new/datadir
“`
Étape 7 — Diagnostiquer et réparer la corruption InnoDB
Si le journal d’erreurs contient des messages comme `InnoDB: Corruption detected`, `[ERROR] InnoDB: Unable to lock ./ibdata1`, ou des références à des incohérences dans les journaux redo, le tablespace InnoDB lui-même est endommagé.
Pour les tables MyISAM, utilisez `mysqlcheck` :
“`bash
sudo mysqlcheck –all-databases –repair –user=root –password
“`
Pour la corruption InnoDB, `mysqlcheck` est insuffisant. L’approche correcte consiste à activer le mode de récupération forcée InnoDB dans `my.cnf` :
“`ini
[mysqld]
innodb_force_recovery = 1
“`
Démarrez MySQL avec ce paramètre, exportez immédiatement toutes les bases de données, puis reconstruisez :
“`bash
mysqldump –all-databases –single-transaction -u root -p > full_backup.sql
“`
Incrémentez `innodb_force_recovery` de 1 à 6 uniquement si les valeurs inférieures ne permettent pas de démarrer le serveur. Aux niveaux 4 et supérieurs, une perte de données est possible — traitez l’instance comme étant en lecture seule et exportez immédiatement.
Après une exportation réussie :
“`bash
sudo systemctl stop mysql
sudo rm -rf /var/lib/mysql/ib_logfile* # Remove corrupt redo logs
Remove innodb_force_recovery from my.cnf
sudo systemctl start mysql
mysql -u root -p < full_backup.sql
“`
Étape 8 — Isoler les erreurs de configuration dans my.cnf
Une simple faute de frappe ou une directive invalide dans `my.cnf` interrompra le démarrage avant que le fichier PID ne soit écrit. MySQL 8.0+ est plus strict concernant les options inconnues que ne l’était la version 5.7.
“`bash
Validate configuration without starting the server
mysqld –validate-config
Or test with verbose output
mysqld –verbose –help > /dev/null
“`
Sauvegardez et réduisez la configuration aux valeurs par défaut :
“`bash
sudo cp /etc/mysql/my.cnf /etc/mysql/my.cnf.bak.$(date +%F)
“`
Les directives problématiques courantes après les mises à jour de version majeure incluent les options dépréciées comme `query_cache_size`, `query_cache_type`, `innodb_file_format` et `innodb_large_prefix` — toutes supprimées dans MySQL 8.0.
Étape 9 — Redémarrer MySQL et valider
“`bash
sudo systemctl restart mysql
Check service status
sudo systemctl status mysql
Confirm the PID file was written
cat /var/run/mysqld/mysqld.pid
Confirm MySQL is accepting connections
mysqladmin -u root -p status
“`
Étape 10 — Réinstaller MySQL (dernier recours avec préservation des données)
La réinstallation ne doit intervenir qu’après avoir épuisé toutes les étapes de diagnostic ci-dessus. Avant de procéder, sauvegardez toutes les données :
“`bash
If MySQL can start in recovery mode, dump first
mysqldump –all-databases -u root -p > /backup/full_$(date +%F).sql
Copy raw data directory as a secondary backup
sudo rsync -av /var/lib/mysql/ /backup/mysql_datadir_$(date +%F)/
“`
Puis supprimez et réinstallez :
“`bash
sudo systemctl stop mysql
sudo apt-get remove –purge mysql-server mysql-client mysql-common
sudo apt-get autoremove && sudo apt-get autoclean
sudo rm -rf /var/lib/mysql /etc/mysql
sudo apt-get install mysql-server
sudo mysql_secure_installation
“`
Restaurez depuis l’exportation :
“`bash
mysql -u root -p < /backup/full_$(date +%F).sql
“`
Choisir le bon environnement d’hébergement pour prévenir les récidives
Beaucoup de ces défaillances — épuisement du disque, réinitialisations des permissions après les redémarrages, contention des ressources due aux services co-hébergés — sont autant des problèmes d’infrastructure que des problèmes MySQL. Exécuter une base de données en production sur un serveur correctement provisionné avec des ressources dédiées élimine des catégories entières de ces erreurs.
Si vous gérez une application s’appuyant sur MySQL, un environnement VPS Hosting vous donne un accès root complet, des ressources isolées et la possibilité de configurer `tmpfiles.d`, les profils AppArmor et les substitutions d’unités systemd sans restriction. Pour les bases de données à fort trafic nécessitant des IOPS et une RAM garantis, les Serveurs Dédiés éliminent entièrement tout problème de partage des ressources.
Pour les équipes qui préfèrent un panneau de contrôle géré plutôt que l’administration directe en ligne de commande, le VPS avec cPanel fournit des interfaces de gestion MySQL ainsi qu’un accès au niveau serveur. Si votre stack nécessite également la configuration de domaines et DNS, l’Enregistrement de Domaines et les Certificats SSL peuvent être gérés auprès du même fournisseur, réduisant ainsi la charge opérationnelle.
Matrice de décision : quel correctif appliquer en premier
| Symptôme dans le journal d’erreurs | Première action | Temps de résolution estimé |
|---|---|---|
| — | — | — |
| `Permission denied` sur le répertoire PID ou de données | Corriger la propriété avec `chown mysql:mysql` | 2 minutes |
| `No space left on device` | Purger les journaux binaires, étendre le disque | 5–30 minutes |
| `A mysqld process already exists` | Supprimer le fichier PID obsolète, arrêter le processus orphelin | 2 minutes |
| `Bind on TCP/IP port: Address already in use` | Arrêter l’instance en conflit, vérifier `ss -tlnp` | 5 minutes |
| `InnoDB: Corruption detected` | Activer `innodb_force_recovery`, exporter, reconstruire | 30 minutes à plusieurs heures |
| `apparmor="DENIED"` dans syslog | Mettre à jour le profil AppArmor ou définir le mode plainte | 10 minutes |
| `unknown variable` dans le journal | Exécuter `mysqld –validate-config`, corriger `my.cnf` | 5 minutes |
| Aucune erreur spécifique, tout le reste a échoué | Réinstaller MySQL, restaurer depuis la sauvegarde | 1–2 heures |
Liste de contrôle des points techniques clés
- Lisez toujours `/var/log/mysql/error.log` ou `/var/log/mysqld.log` avant de toucher à tout fichier — la première ligne `[ERROR]` identifie la cause réelle.
- Sur les systèmes systemd avec `tmpfs` sur `/var/run`, créez une règle `/etc/tmpfiles.d/mysqld.conf` persistante pour éviter les réinitialisations de permissions à chaque redémarrage.
- Après tout `rsync` ou restauration manuelle depuis une sauvegarde, exécutez `chown -R mysql:mysql /var/lib/mysql` avant de tenter de démarrer MySQL.
- Vérifiez `df -i` (utilisation des inodes) en parallèle avec `df -h` (espace disque) — une table d’inodes pleine produit des symptômes identiques à un disque plein.
- Pour la corruption InnoDB, utilisez `innodb_force_recovery` de manière incrémentale à partir de 1 ; ne passez jamais directement au niveau 6.
- Validez la syntaxe de `my.cnf` avec `mysqld –validate-config` avant de redémarrer — cela détecte les fautes de frappe sans tentative de démarrage échouée.
- Supprimez les directives MySQL 5.7 dépréciées (`query_cache_*`, `innodb_file_format`) avant de mettre à niveau vers MySQL 8.0.
- Sur Ubuntu, vérifiez les refus AppArmor dans `/var/log/syslog` ; sur RHEL/AlmaLinux, vérifiez SELinux avec `ausearch -c mysqld`.
Foire aux questions
Quelle est la façon la plus rapide de trouver pourquoi MySQL n’a pas réussi à démarrer ?
Exécutez `sudo tail -50 /var/log/mysql/error.log` et recherchez la première ligne contenant `[ERROR]` ou `[FATAL]`. Cette seule ligne identifie la cause racine dans la grande majorité des cas et détermine quel correctif appliquer.
Pourquoi le répertoire PID perd-il ses permissions après un redémarrage ?
Sur les distributions Linux utilisant `tmpfs` pour `/var/run` (ce qui inclut Ubuntu 18.04+ et Debian 10+), l’arborescence `/var/run` entière est reconstruite en mémoire au démarrage. Tout répertoire non défini dans `/etc/tmpfiles.d/` est recréé avec la propriété `root:root`. Le correctif consiste à ajouter une règle `tmpfiles.d` : `echo "d /var/run/mysqld 0755 mysql mysql -" | sudo tee /etc/tmpfiles.d/mysqld.conf`.
Puis-je récupérer des données si MySQL ne démarre pas du tout en raison d’une corruption InnoDB ?
Oui, dans la plupart des cas. Définissez `innodb_force_recovery = 1` dans `my.cnf`, démarrez MySQL et exécutez immédiatement `mysqldump –all-databases`. Si le niveau 1 ne démarre pas le serveur, incrémentez à 2, puis 3, et ainsi de suite. Aux niveaux 4–6, certaines données peuvent être irrécupérables, mais la majorité des tables est généralement intacte.
Comment éviter que "no space left on device" ne fasse tomber MySQL à nouveau ?
Activez l’expiration des journaux binaires : définissez `binlog_expire_logs_seconds = 604800` (7 jours) dans `my.cnf`. De plus, désactivez le journal de requêtes général en production (`general_log = 0`) et configurez une alerte d’utilisation du disque à 80% de capacité via votre système de surveillance.
Cette erreur se produit-elle également sur MariaDB, et le correctif est-il le même ?
Oui. MariaDB utilise le même mécanisme de fichier PID et la même structure de répertoire de données que MySQL. Toutes les étapes de diagnostic de ce guide s’appliquent directement à MariaDB, la seule différence étant que le nom du service est `mariadb` au lieu de `mysql` dans les commandes `systemctl`, et que le journal d’erreurs peut se trouver à `/var/log/mariadb/mariadb.log` selon la distribution.
