Il arrive parfois qu’une table SQL soit endommagée après un crash serveur, une coupure brutale, un disque plein, une migration ratée ou un arrêt non propre de MySQL/MariaDB.
Sur un site WordPress, cela peut se traduire par une erreur de connexion à la base, des requêtes qui échouent, des tables marquées comme “crashed”, ou des messages dans les logs MySQL/MariaDB.
À l’époque, j’avais écrit un petit script Bash qui stoppait MySQL, lançait myisamchk sur toutes les tables .MYI, puis relançait MySQL, Apache et Varnish.
Cette méthode pouvait dépanner sur de vieilles bases en MyISAM. Aujourd’hui, elle doit être utilisée avec beaucoup plus de prudence, car la plupart des tables modernes sont en InnoDB. Et InnoDB ne se répare pas avec myisamchk.
L’ancien script myisamchk
Voici l’ancien script de dépannage :
#!/bin/sh
# MySQL Auto-Repair
# Written by Matt - skyminds.net
# Stop the MySQL server.
/etc/init.d/mysql stop
# Check for errors.
myisamchk /var/lib/mysql/*/*.MYI
# Ask permission to repair.
read -p "Repair tables ? (y/n)" -n 1 -r
if [[ $REPLY =~ ^[Yy]$ ]]
then
# Repair everything.
myisamchk -r /var/lib/mysql/*/*.MYI
# Restart servers.
/etc/init.d/mysql restart
/etc/init.d/apache2 restart
/etc/init.d/varnish restart
else
/etc/init.d/mysql restart
fiLangage du code : PHP (php)
Ce script a deux limites importantes aujourd’hui :
- il ne traite que les tables MyISAM, c’est-à-dire les fichiers
.MYI; - il arrête brutalement toute la base avant de réparer toutes les tables, sans diagnostic précis.
MySQL documente myisamchk comme un outil destiné aux tables MyISAM, dont les fichiers utilisent les extensions .MYI et .MYD.
Donc, si vos tables sont en InnoDB, ce script ne les réparera pas. Il passera à côté du vrai problème avec une confiance admirable, ce qui est rarement ce que l’on souhaite pendant un incident.
MyISAM ou InnoDB : commencer par identifier le moteur
Avant toute réparation, il faut savoir quels moteurs de stockage sont utilisés.
Connectez-vous à MySQL ou MariaDB :
sudo mysql
ou :
sudo mariadb
Puis listez les moteurs utilisés par vos tables :
SELECT TABLE_SCHEMA, ENGINE, COUNT(*) AS tables_count
FROM information_schema.TABLES
WHERE TABLE_SCHEMA NOT IN ('information_schema', 'performance_schema', 'mysql', 'sys')
GROUP BY TABLE_SCHEMA, ENGINE
ORDER BY TABLE_SCHEMA, ENGINE;Langage du code : PHP (php)
Pour un site WordPress moderne, vous devriez voir surtout :
InnoDB
Si vous voyez encore des tables MyISAM, elles peuvent venir d’un vieux site, d’un ancien plugin, d’une migration historique ou d’une table personnalisée.
MySQL 8.4 indique qu’InnoDB est le moteur par défaut, et qu’il faut généralement spécifier explicitement ENGINE=MyISAM pour créer une table MyISAM.
Ne pas utiliser myisamchk sur InnoDB
myisamchk ne répare pas les tables InnoDB.
Les tables InnoDB ne fonctionnent pas comme les anciennes tables MyISAM. Elles utilisent un moteur transactionnel, des journaux, un tablespace, de la récupération après crash, et une logique interne différente.
MariaDB indique que REPAIR TABLE fonctionne pour Archive, Aria, CSV et MyISAM. Pour InnoDB, la documentation renvoie vers les modes de récupération.
Donc, si une table InnoDB est corrompue, la démarche consiste plutôt à :
- lire les logs MariaDB/MySQL ;
- vérifier l’état du disque ;
- essayer un démarrage normal ;
- faire un dump si le serveur démarre ;
- restaurer depuis sauvegarde si nécessaire ;
- utiliser
innodb_force_recoveryseulement en dernier recours.
InnoDB sait souvent récupérer tout seul après un crash proprement journalisé. Mais si le moteur refuse de démarrer, on change de registre : on n’est plus dans la “réparation de table”, on est dans la récupération de données.
Première étape : lire les logs MySQL/MariaDB
Avant de lancer une réparation, regardez ce que dit le serveur SQL.
sudo journalctl -u mysql -n 200 --no-pager
sudo journalctl -u mariadb -n 200 --no-pager
Selon la distribution, les logs peuvent aussi se trouver ici :
Votre hébergement est devenu un problème ?
Serveur partagé saturé, limites PHP trop basses, support qui répond en 48h — à un certain niveau de trafic, l'hébergement mutualisé devient le goulot. Je migre et configure des serveurs dédiés.
Parlons de votre infrastructure →/var/log/mysql/error.log
/var/log/mysql/mariadb.log
/var/log/mariadb/mariadb.logLangage du code : JavaScript (javascript)
Vous pouvez chercher les mots clés utiles :
sudo grep -RiE "crash|corrupt|repair|InnoDB|MyISAM|Aria|error" /var/log/mysql /var/log/mariadb 2>/dev/nullLangage du code : JavaScript (javascript)
Le message exact change tout. Une table MyISAM “crashed” ne se traite pas comme un tablespace InnoDB corrompu.
Vérifier l’état du disque avant de réparer
Une table SQL ne se corrompt pas toujours “toute seule”. Avant de réparer, vérifiez que le serveur n’a pas un problème plus profond.
df -h
df -i
dmesg -T | grep -Ei "error|fail|i/o|ext4|xfs|nvme|sda|ata"
sudo journalctl -k -n 200 --no-pagerLangage du code : JavaScript (javascript)
Si le disque est plein, si les inodes sont épuisés, ou si le noyau signale des erreurs I/O, réparer les tables sans corriger la cause revient à repeindre un mur pendant que la maison brûle. Ambitieux, mais discutable.
Sauvegarder avant toute réparation
Avant de lancer une réparation, faites une sauvegarde si le serveur démarre encore.
Pour toutes les bases :
sudo mysqldump --all-databases --single-transaction --routines --triggers --events \
| gzip > all-databases-$(date +%Y%m%d-%H%M%S).sql.gzLangage du code : JavaScript (javascript)
Avec MariaDB :
sudo mariadb-dump --all-databases --single-transaction --routines --triggers --events \
| gzip > all-databases-$(date +%Y%m%d-%H%M%S).sql.gzLangage du code : JavaScript (javascript)
Si le serveur ne démarre plus, faites au minimum une copie à froid du datadir avant d’essayer des opérations destructrices :
sudo systemctl stop mysql || sudo systemctl stop mariadb
sudo rsync -aHAX --numeric-ids /var/lib/mysql/ /root/mysql-datadir-backup-$(date +%Y%m%d-%H%M%S)/Langage du code : JavaScript (javascript)
Adaptez évidemment le chemin si votre datadir a été déplacé.
Méthode moderne : vérifier les tables avec mysqlcheck
Pour vérifier les tables sans manipuler directement les fichiers sur disque, utilisez mysqlcheck ou mariadb-check.
MySQL documente mysqlcheck comme un outil de maintenance capable de vérifier, réparer, optimiser ou analyser les tables. La documentation précise aussi que les tables sont verrouillées pendant les opérations de maintenance.
Vérifier toutes les bases :
sudo mysqlcheck --all-databases --check
Avec MariaDB :
sudo mariadb-check --all-databases --check
Vérifier une seule base :
mysqlcheck -u root -p --check nom_de_base
Vérifier une table précise :
mysqlcheck -u root -p --check nom_de_base nom_de_table
Cette étape est non négociable : on diagnostique avant de réparer. Sinon, on répare peut-être la mauvaise chose, ce qui est une excellente manière d’aggraver une mauvaise journée.
Réparer les tables MyISAM avec mysqlcheck
Si les tables concernées sont en MyISAM, vous pouvez utiliser mysqlcheck --repair.
Réparer toutes les bases :
sudo mysqlcheck --all-databases --repair
Avec MariaDB :
sudo mariadb-check --all-databases --repair
Réparer une base :
mysqlcheck -u root -p --repair nom_de_base
Réparer une table précise :
mysqlcheck -u root -p --repair nom_de_base nom_de_table
Gardez en tête que la réparation peut verrouiller les tables et prendre du temps sur de grosses bases. Planifiez l’opération si le site est en production.
Réparer les tables MyISAM avec myisamchk
myisamchk reste utile pour les tables MyISAM, notamment si MySQL/MariaDB ne démarre pas ou si vous voulez travailler hors serveur SQL.
Mais il faut arrêter le serveur avant de manipuler directement les fichiers .MYI, afin d’éviter une corruption supplémentaire.
sudo systemctl stop mysql
# ou
sudo systemctl stop mariadbLangage du code : PHP (php)
Vérifier les tables MyISAM :
sudo myisamchk --check /var/lib/mysql/*/*.MYILangage du code : JavaScript (javascript)
Réparer les tables MyISAM :
sudo myisamchk --recover /var/lib/mysql/*/*.MYILangage du code : JavaScript (javascript)
Ou en mode plus fort si nécessaire :
sudo myisamchk --safe-recover /var/lib/mysql/*/*.MYILangage du code : JavaScript (javascript)
Puis redémarrer le service :
sudo systemctl start mysql
# ou
sudo systemctl start mariadbLangage du code : PHP (php)
MySQL documente aussi l’usage de CHECK TABLE et REPAIR TABLE comme alternatives à myisamchk pour les tables MyISAM.
Et pour InnoDB ?
Pour InnoDB, on ne lance pas myisamchk, et REPAIR TABLE n’est pas la bonne réponse.
Commencez par un redémarrage normal :
sudo systemctl restart mysql
# ou
sudo systemctl restart mariadbLangage du code : PHP (php)
Puis relisez les logs :
sudo journalctl -u mysql -n 200 --no-pager
sudo journalctl -u mariadb -n 200 --no-pager
Si InnoDB démarre, faites immédiatement un dump des bases importantes, puis restaurez-les sur une base saine si nécessaire.
Si InnoDB ne démarre pas, vous pouvez envisager innodb_force_recovery, mais seulement comme méthode de récupération pour extraire les données. Ce n’est pas une réparation magique.
Le principe est :
- activer temporairement un niveau de récupération ;
- démarrer MySQL/MariaDB en lecture limitée ;
- faire un dump des données ;
- recréer une instance saine ;
- restaurer les dumps ;
- retirer
innodb_force_recovery.
Ne gardez jamais innodb_force_recovery activé sur un serveur en production normale. C’est une béquille de secours, pas une configuration.
Exemple de récupération InnoDB en dernier recours
Si MariaDB/MySQL refuse de démarrer à cause d’InnoDB, éditez la configuration :
sudo nano /etc/mysql/mysql.conf.d/mysqld.cnf
ou, selon MariaDB :
sudo nano /etc/mysql/mariadb.conf.d/50-server.cnf
Dans la section [mysqld] ou [mariadb], ajoutez temporairement :
innodb_force_recovery = 1
Essayez de démarrer :
sudo systemctl start mysql
# ou
sudo systemctl start mariadbLangage du code : PHP (php)
Si cela démarre, faites un dump immédiatement :
sudo mysqldump --all-databases --routines --triggers --events \
| gzip > recovery-dump-$(date +%Y%m%d-%H%M%S).sql.gzLangage du code : JavaScript (javascript)
Si cela ne démarre pas, augmentez progressivement le niveau, sans sauter directement au niveau maximal :
innodb_force_recovery = 2
puis 3, etc., seulement si nécessaire.
Après récupération, retirez cette directive, recréez une base saine, puis restaurez les données. Encore une fois : innodb_force_recovery sert à récupérer, pas à continuer comme si de rien n’était.
Trouver les tables MyISAM restantes
Pour identifier les tables MyISAM encore présentes :
SELECT TABLE_SCHEMA, TABLE_NAME
FROM information_schema.TABLES
WHERE ENGINE = 'MyISAM'
AND TABLE_SCHEMA NOT IN ('information_schema', 'performance_schema', 'mysql', 'sys')
ORDER BY TABLE_SCHEMA, TABLE_NAME;Langage du code : JavaScript (javascript)
En ligne de commande :
sudo mysql -N -e "
SELECT CONCAT(TABLE_SCHEMA, '.', TABLE_NAME)
FROM information_schema.TABLES
WHERE ENGINE = 'MyISAM'
AND TABLE_SCHEMA NOT IN ('information_schema', 'performance_schema', 'mysql', 'sys')
ORDER BY TABLE_SCHEMA, TABLE_NAME;
"Langage du code : PHP (php)
Si vous êtes sur un site WordPress ancien, il peut être intéressant de convertir les tables MyISAM restantes vers InnoDB, après sauvegarde et test.
Convertir une table MyISAM en InnoDB
Après sauvegarde, on peut convertir une table :
ALTER TABLE nom_de_table ENGINE=InnoDB;
Pour WordPress, vérifiez d’abord les tables concernées et testez en staging. Les très vieux plugins ou tables personnalisées peuvent avoir des particularités.
La conversion MyISAM vers InnoDB réduit généralement les risques liés aux crashs, car InnoDB est transactionnel et possède une meilleure récupération après incident.
Script Bash moderne : diagnostic puis réparation MyISAM uniquement
Voici une version plus prudente du script. Elle ne prétend pas réparer InnoDB. Elle vérifie les tables, demande confirmation, puis répare uniquement via mysqlcheck.
#!/usr/bin/env bash
#
# MySQL/MariaDB table check and MyISAM repair helper.
# Author: Matt Biscay - skyminds.net
#
# This script checks all databases and can run a repair pass.
# It is mainly useful for MyISAM/Aria-style table repairs.
# InnoDB corruption must be handled separately.
set -euo pipefail
mysqlcheck_bin="$(command -v mariadb-check || command -v mysqlcheck || true)"
dump_bin="$(command -v mariadb-dump || command -v mysqldump || true)"
if [[ -z "$mysqlcheck_bin" ]]; then
echo "Error: neither mariadb-check nor mysqlcheck was found." >&2
exit 1
fi
echo "Using: $mysqlcheck_bin"
echo
echo "Checking database service..."
if systemctl list-unit-files | grep -q '^mariadb\.service'; then
db_service="mariadb"
elif systemctl list-unit-files | grep -q '^mysql\.service'; then
db_service="mysql"
else
db_service=""
fi
if [[ -n "$db_service" ]]; then
systemctl status "$db_service" --no-pager || true
fi
echo
echo "Checking all databases..."
sudo "$mysqlcheck_bin" --all-databases --check
echo
read -r -p "Create a SQL dump before repair if possible? [y/N] " dump_reply
if [[ "$dump_reply" =~ ^[Yy]$ ]]; then
if [[ -z "$dump_bin" ]]; then
echo "Warning: neither mariadb-dump nor mysqldump was found. Skipping dump." >&2
else
dump_file="all-databases-before-repair-$(date +%Y%m%d-%H%M%S).sql.gz"
echo "Creating dump: $dump_file"
sudo "$dump_bin" --all-databases --single-transaction --routines --triggers --events | gzip > "$dump_file"
fi
fi
echo
read -r -p "Run repair pass now? This may lock tables. [y/N] " repair_reply
if [[ "$repair_reply" =~ ^[Yy]$ ]]; then
sudo "$mysqlcheck_bin" --all-databases --repair
else
echo "Repair skipped."
fi
echo
echo "Done."Langage du code : PHP (php)
Rendez-le exécutable :
chmod +x mysql-table-check-repair.shLangage du code : CSS (css)
Lancez-le :
./mysql-table-check-repair.sh
Ce script est volontairement prudent : il vérifie, propose une sauvegarde, puis demande confirmation avant la réparation.
Script d’urgence MyISAM hors ligne avec myisamchk
Si vous savez que les tables concernées sont en MyISAM et que vous devez intervenir hors ligne, voici une version plus moderne du script myisamchk.
#!/usr/bin/env bash
#
# Offline MyISAM repair helper.
# Author: Matt Biscay - skyminds.net
#
# Use only for MyISAM tables. Do not use for InnoDB.
set -euo pipefail
datadir="${1:-/var/lib/mysql}"
if [[ ! -d "$datadir" ]]; then
echo "Error: datadir not found: $datadir" >&2
exit 1
fi
mapfile -t myi_files < <(find "$datadir" -type f -name '*.MYI' 2>/dev/null)
if [[ "${#myi_files[@]}" -eq 0 ]]; then
echo "No MyISAM .MYI files found in $datadir."
exit 0
fi
echo "Found ${#myi_files[@]} MyISAM index files."
printf '%s\n' "${myi_files[@]}"
echo
read -r -p "Stop MySQL/MariaDB and check these tables? [y/N] " check_reply
if [[ ! "$check_reply" =~ ^[Yy]$ ]]; then
echo "Aborted."
exit 0
fi
if systemctl list-unit-files | grep -q '^mariadb\.service'; then
db_service="mariadb"
else
db_service="mysql"
fi
sudo systemctl stop "$db_service"
echo
echo "Checking MyISAM tables..."
sudo myisamchk --check "${myi_files[@]}" || true
echo
read -r -p "Repair MyISAM tables now? [y/N] " repair_reply
if [[ "$repair_reply" =~ ^[Yy]$ ]]; then
sudo myisamchk --recover "${myi_files[@]}"
else
echo "Repair skipped."
fi
sudo systemctl start "$db_service"
echo
echo "Done."Langage du code : PHP (php)
Vous pouvez lui passer un datadir personnalisé :
./offline-myisam-repair.sh /home/mysql
Encore une fois : ce script ne concerne que MyISAM. Si vous avez un incident InnoDB, ce n’est pas le bon outil.
Faut-il redémarrer Apache, Nginx ou Varnish ?
L’ancien script redémarrait MySQL, Apache et Varnish.
Aujourd’hui, je ne redémarrerais pas les services web automatiquement après une réparation SQL, sauf si vous avez une raison précise.
Dans la plupart des cas, il suffit de redémarrer MySQL/MariaDB si vous l’avez arrêté :
sudo systemctl restart mysql
# ou
sudo systemctl restart mariadbLangage du code : PHP (php)
Pour PHP-FPM, Apache, Nginx ou Varnish, vérifiez d’abord les logs et le comportement du site. Redémarrer toute la pile “par sécurité” peut masquer le vrai problème et compliquer le diagnostic.
Cas WordPress : vérifier les tables avec WP-CLI
Sur WordPress, WP-CLI permet aussi de réparer les tables WordPress avec :
wp db check
wp db repair
Cela peut dépanner pour les tables WordPress, mais cela ne remplace pas un diagnostic MySQL/MariaDB complet. Si le moteur InnoDB est en difficulté, WP-CLI ne fera pas de miracle. Il parlera à la base tant qu’elle répond, puis il sera aussi impuissant que le reste du monde.
Méthode de résolution recommandée
En cas de crash SQL, j’utiliserais cette séquence :
- Ne pas paniquer. Facile à écrire, moins à faire.
- Lire les logs MySQL/MariaDB.
- Vérifier l’état disque, les inodes et les erreurs I/O.
- Identifier les moteurs de tables : InnoDB, MyISAM, Aria, etc.
- Faire une sauvegarde ou une copie à froid avant réparation.
- Utiliser
mysqlcheckoumariadb-checkpour vérifier. - Réparer uniquement les tables MyISAM/Aria concernées.
- Pour InnoDB, privilégier récupération, dump, restauration.
- Vérifier le site et les logs applicatifs.
- Prévoir une migration des tables MyISAM restantes vers InnoDB si possible.
Mémo rapide
# Logs MySQL/MariaDB.
sudo journalctl -u mysql -n 200 --no-pager
sudo journalctl -u mariadb -n 200 --no-pager
# Vérifier le disque.
df -h
df -i
dmesg -T | grep -Ei "error|fail|i/o|ext4|xfs|nvme|sda|ata"
# Voir les moteurs utilisés.
sudo mysql -e "
SELECT TABLE_SCHEMA, ENGINE, COUNT(*) AS tables_count
FROM information_schema.TABLES
WHERE TABLE_SCHEMA NOT IN ('information_schema', 'performance_schema', 'mysql', 'sys')
GROUP BY TABLE_SCHEMA, ENGINE
ORDER BY TABLE_SCHEMA, ENGINE;
"
# Vérifier toutes les tables.
sudo mysqlcheck --all-databases --check
sudo mariadb-check --all-databases --check
# Réparer ce qui est réparable par REPAIR TABLE.
sudo mysqlcheck --all-databases --repair
sudo mariadb-check --all-databases --repair
# Trouver les tables MyISAM.
sudo mysql -N -e "
SELECT CONCAT(TABLE_SCHEMA, '.', TABLE_NAME)
FROM information_schema.TABLES
WHERE ENGINE = 'MyISAM'
AND TABLE_SCHEMA NOT IN ('information_schema', 'performance_schema', 'mysql', 'sys');
"
# Réparer MyISAM hors ligne.
sudo systemctl stop mysql
sudo myisamchk --check /var/lib/mysql/*/*.MYI
sudo myisamchk --recover /var/lib/mysql/*/*.MYI
sudo systemctl start mysql
# WordPress.
wp db check
wp db repairLangage du code : PHP (php)
Conclusion
L’ancien script Bash basé sur myisamchk pouvait rendre service sur des serveurs utilisant encore largement MyISAM.
Mais sur un serveur MySQL/MariaDB moderne, il faut d’abord identifier le moteur des tables. myisamchk ne concerne que MyISAM. Pour InnoDB, on parle plutôt de récupération, de dump, de restauration et parfois de innodb_force_recovery en dernier recours.
La méthode moderne consiste donc à diagnostiquer avec les logs, vérifier l’état du disque, sauvegarder, utiliser mysqlcheck ou mariadb-check, puis réparer uniquement ce qui peut l’être.
En résumé : gardez un script de secours, oui. Mais gardez surtout des sauvegardes testées. Un script de réparation, c’est rassurant ; une restauration qui fonctionne, c’est mieux. C’est moins héroïque, mais beaucoup plus efficace.
Votre hébergement est devenu un problème ?
Serveur partagé saturé, limites PHP trop basses, support qui répond en 48h — à un certain niveau de trafic, l'hébergement mutualisé devient le goulot. Je migre et configure des serveurs dédiés.
Parlons de votre infrastructure →



