MySQL/MariaDB : vérifier et réparer les tables après un crash

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.

Kinsta: Premium Managed WordPress hosting

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.

Kinsta: Premium Managed WordPress hosting

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_recovery seulement 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 :

/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.

Kinsta: Premium Managed WordPress hosting

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é.

Distingo, le livret à 2%

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 :

  1. Ne pas paniquer. Facile à écrire, moins à faire.
  2. Lire les logs MySQL/MariaDB.
  3. Vérifier l’état disque, les inodes et les erreurs I/O.
  4. Identifier les moteurs de tables : InnoDB, MyISAM, Aria, etc.
  5. Faire une sauvegarde ou une copie à froid avant réparation.
  6. Utiliser mysqlcheck ou mariadb-check pour vérifier.
  7. Réparer uniquement les tables MyISAM/Aria concernées.
  8. Pour InnoDB, privilégier récupération, dump, restauration.
  9. Vérifier le site et les logs applicatifs.
  10. 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.

Demandez à l'IA son opinion
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