Si vous avez déjà vu un “table is marked as crashed” dans vos logs, ou un site WordPress 6.9.4 qui devient lent sans raison, il y a de fortes chances que votre base MySQL/MariaDB ait besoin d’un contrôle ciblé — pas d’un “plugin magique”.
Je croise souvent ce problème sur des sites qui ont beaucoup de révisions, des imports WooCommerce, ou des migrations faites à la va-vite. Le point clé : réparer et optimiser ne veulent pas dire la même chose, et selon le moteur (InnoDB vs MyISAM) les commandes n’ont pas le même impact.
Le besoin / Le problème serveur
Vous avez un WordPress 6.9.4 (PHP 8.1+ recommandé) qui :
- répond plus lentement (TTFB élevé),
- affiche des erreurs SQL sporadiques,
- fait exploser la charge CPU lors des sauvegardes ou des imports,
- ou a subi un crash serveur (OOM, disque plein, redémarrage brutal).
Le problème vient souvent de trois zones :
- Tables corrompues (plus fréquent sur MyISAM, mais possible ailleurs après incident disque).
- Fragmentation / espace perdu (surtout MyISAM ; InnoDB se gère différemment).
- Configuration MySQL/MariaDB inadaptée à WordPress (buffer pool trop petit, log trop agressif, etc.).
À la fin, vous saurez :
- identifier les tables à risque (CHECK TABLE + vues sur l’engine),
- réparer sans improviser (REPAIR pour MyISAM, stratégie InnoDB),
- optimiser sans bloquer votre site en production,
- mettre en place une maintenance automatisée et vérifiable,
- ajuster des paramètres MySQL/MariaDB réalistes pour WordPress.
Résumé rapide
- Ne lancez pas OPTIMIZE “sur toute la base” en pleine journée : ça peut locker et faire tomber le site.
- InnoDB ≠ MyISAM : REPAIR TABLE n’est pas une baguette magique pour InnoDB.
- Sauvegarde d’abord : dump logique (mysqldump) + idéalement snapshot.
- Diagnostiquez avec MySQL (CHECK TABLE) et les logs (error log MySQL + PHP + Nginx/Apache).
- Optimisez WordPress côté DB (autoloader, révisions, transients) seulement après avoir stabilisé le serveur.
- Automatisez une routine sûre via cron + WP-CLI + commandes SQL ciblées.
Avant de commencer (prérequis)
Accès nécessaires :
- SSH sur le serveur (ou au minimum un shell dans un conteneur),
- Accès MySQL/MariaDB (utilisateur avec droits SELECT + éventuellement ALTER/LOCK/REPAIR selon actions),
- WP-CLI disponible (recommandé) : WP-CLI Commands,
- Accès aux logs : error log MySQL/MariaDB, logs PHP-FPM, logs Nginx/Apache.
Versions :
- WordPress : 6.9.4 (avril 2026)
- PHP : 8.1+ (idéalement 8.2/8.3 selon votre stack)
- MySQL ou MariaDB : l’article reste volontairement compatible avec les deux, mais certains réglages diffèrent.
Sauvegarde obligatoire : si vous réparez/optimisez en production sans sauvegarde, vous jouez à pile ou face avec vos données. J’ai déjà vu un “REPAIR” mal ciblé sur une table MyISAM finir en perte de lignes après un incident disque.
Enfin, si vous utilisez Divi 5, Elementor ou Avada : ces builders n’influencent pas directement le moteur SQL, mais ils augmentent la taille de wp_posts/wp_postmeta. Résultat : les opérations de maintenance prennent plus de temps, et les locks sont plus visibles.
Étape 1 : Diagnostiquer l’état des tables (sans rien casser)
Commencez par identifier le moteur de stockage et les tables les plus lourdes. C’est la base pour décider entre réparation, optimisation, ou simple tuning.
1) Récupérer les infos de connexion WordPress
Sur le serveur, récupérez les variables DB dans wp-config.php :
cd /var/www/votre-site
grep -E "DB_NAME|DB_USER|DB_HOST" wp-config.php
2) Se connecter à MySQL/MariaDB
mysql -h 127.0.0.1 -u votre_user -p
3) Lister les tables WordPress, leur engine et leur taille
mysql -h 127.0.0.1 -u votre_user -p -e "
SELECT
table_name,
engine,
table_rows,
ROUND((data_length+index_length)/1024/1024, 2) AS size_mb
FROM information_schema.tables
WHERE table_schema = 'votre_db'
ORDER BY (data_length+index_length) DESC
LIMIT 30;
"
Ce que vous cherchez :
- Engine : InnoDB (souvent) ou MyISAM (plus rare en 2026, mais encore vu sur des vieux hébergements/migrations).
- wp_options : si elle grossit, c’est souvent
autoloadqui devient toxique. - wp_postmeta et wp_posts : énormes sur Elementor/Divi/Avada + WooCommerce.
4) Vérifier l’intégrité des tables (CHECK TABLE)
Sur une base WordPress moyenne, vous pouvez checker toutes les tables. Sur une base énorme, faites-le table par table (pour éviter des opérations longues).
mysql -h 127.0.0.1 -u votre_user -p -e "
USE votre_db;
SHOW TABLES;
"
Générer une série de CHECK TABLE :
mysql -h 127.0.0.1 -u votre_user -p -N -e "
SELECT CONCAT('CHECK TABLE `', table_name, '` QUICK;')
FROM information_schema.tables
WHERE table_schema = 'votre_db';
" | mysql -h 127.0.0.1 -u votre_user -p votre_db
Notes terrain :
- QUICK limite la profondeur du check. Si vous suspectez une corruption, vous pourrez relancer sans QUICK sur la table concernée.
- Sur InnoDB, CHECK TABLE renvoie souvent “OK” même quand le problème est en réalité un souci de transactions/logs. D’où l’importance des logs MySQL.
5) Diagnostiquer via les logs MySQL/MariaDB
Sur Debian/Ubuntu, c’est souvent :
sudo tail -n 200 /var/log/mysql/error.log
# ou MariaDB :
sudo tail -n 200 /var/log/mysql/mariadb.log
sudo tail -n 200 /var/log/mysql/error.log
Sur systemd :
sudo journalctl -u mysql --since "2 hours ago" -n 300
# ou :
sudo journalctl -u mariadb --since "2 hours ago" -n 300
Indicateurs typiques :
- InnoDB: corruption, pages illisibles, crash recovery en boucle.
- Disk full ou “No space left on device” pendant une opération.
- Too many connections (souvent confondu avec “base lente”).
Étape 2 : Sauvegarder proprement avant toute réparation
Avant un REPAIR/OPTIMIZE, faites au minimum un dump logique. Idéalement, faites aussi un snapshot (LVM/ZFS/volume cloud) si vous pouvez.
1) Dump avec mysqldump (transaction-safe pour InnoDB)
export DB_HOST="127.0.0.1"
export DB_NAME="votre_db"
export DB_USER="votre_user"
# Dump compressé. --single-transaction évite de locker InnoDB.
mysqldump -h "$DB_HOST" -u "$DB_USER" -p
--single-transaction
--quick
--routines --triggers
"$DB_NAME" | gzip > "$DB_NAME-$(date +%F-%H%M)-pre-maintenance.sql.gz"
Ce que ça évite :
- un dump qui met votre site à genoux (le
--quickstream les lignes), - des locks longs sur InnoDB (le
--single-transaction).
2) Vérifier rapidement l’archive
gzip -t "$DB_NAME-$(date +%F-%H%M)-pre-maintenance.sql.gz" || echo "Archive corrompue"
ls -lh *.sql.gz | tail -n 5
3) Option staging (recommandé si site pro)
Si vous avez un staging, appliquez d’abord la maintenance dessus. Avec WP-CLI :
# Sur le staging uniquement
wp --info
wp core version
wp db size --all-tables
Sur des sites Elementor/Divi/Avada, c’est typiquement sur staging qu’on voit si une opération va prendre 30 secondes ou 30 minutes.
Étape 3 : Réparer les tables (CHECK/REPAIR) selon le moteur
Réparer, c’est traiter une table endommagée ou incohérente. Optimiser, c’est autre chose. Mélanger les deux est un anti-pattern que je vois souvent dans des scripts “one-liner”.
1) Cas MyISAM : REPAIR TABLE (le cas “classique”)
Si une table MyISAM est marquée comme crashée, vous verrez des messages du style :
- “Table ‘xxx’ is marked as crashed and should be repaired”
Réparez uniquement les tables concernées :
mysql -h 127.0.0.1 -u votre_user -p -e "
USE votre_db;
REPAIR TABLE wp_comments, wp_commentmeta;
"
Si REPAIR échoue, essayez avec EXTENDED (plus long) :
mysql -h 127.0.0.1 -u votre_user -p -e "
USE votre_db;
REPAIR TABLE wp_comments EXTENDED;
"
2) Cas InnoDB : stratégie réaliste (pas de faux espoirs)
Sur InnoDB, REPAIR TABLE n’est généralement pas la solution. Si vous suspectez une corruption InnoDB :
- regardez les logs InnoDB (error log),
- identifiez la table touchée,
- restaurez depuis sauvegarde si nécessaire,
- ou exportez/réimportez la table (quand c’est possible).
Approche “export / drop / import” (à faire d’abord sur staging) :
# Export d'une table spécifique
mysqldump -h 127.0.0.1 -u votre_user -p
--single-transaction
votre_db wp_options > wp_options.sql
# Puis, en maintenance (site en lecture seule idéalement) :
mysql -h 127.0.0.1 -u votre_user -p -e "
USE votre_db;
DROP TABLE wp_options;
"
# Réimport
mysql -h 127.0.0.1 -u votre_user -p votre_db < wp_options.sql
Risque : si vous droppez la mauvaise table, vous perdez des données. C’est exactement le genre d’erreur “copier-coller trop vite” que je vois en prod. Travaillez avec une liste explicite, et vérifiez deux fois le nom de la base.
3) Alternative serveur : mysqlcheck
mysqlcheck est pratique pour automatiser. Exemple : check + repair sur une base (utile surtout MyISAM).
mysqlcheck -h 127.0.0.1 -u votre_user -p --check votre_db
mysqlcheck -h 127.0.0.1 -u votre_user -p --auto-repair votre_db
Sur InnoDB, --auto-repair ne résout pas les corruptions profondes. Mais ça reste utile pour détecter des incohérences simples.
Étape 4 : Optimiser (OPTIMIZE) sans bloquer le site
Le piège : lancer OPTIMIZE TABLE sur wp_postmeta en pleine journée. Selon votre version MySQL/MariaDB et la taille, ça peut prendre longtemps et provoquer des locks gênants.
1) Comprendre ce que fait OPTIMIZE selon le moteur
- MyISAM : reconstruit la table, récupère l’espace, défragmente.
- InnoDB : selon versions, ça peut être un “table rebuild” (équivalent
ALTER TABLE ...), parfois plus lourd que prévu.
2) Optimiser seulement les tables qui en valent la peine
Repérez les tables avec beaucoup d’espace “perdu” (approximation via data_free) :
mysql -h 127.0.0.1 -u votre_user -p -e "
SELECT
table_name,
engine,
ROUND(data_length/1024/1024,2) AS data_mb,
ROUND(index_length/1024/1024,2) AS index_mb,
ROUND(data_free/1024/1024,2) AS free_mb
FROM information_schema.tables
WHERE table_schema='votre_db'
ORDER BY data_free DESC
LIMIT 20;
"
Ensuite, optimisez une table à la fois (fenêtre de faible trafic) :
mysql -h 127.0.0.1 -u votre_user -p -e "
USE votre_db;
OPTIMIZE TABLE wp_posts;
OPTIMIZE TABLE wp_postmeta;
"
3) Réduire l’impact en production
- Faites-le sur staging d’abord, chronométrez.
- Activez une maintenance applicative (lecture seule) si votre site est très sensible (boutique).
- Sur gros sites, envisagez des outils en ligne (pt-online-schema-change) — mais ça dépasse souvent le niveau “intermédiaire” et demande une vraie discipline DevOps.
4) Optimisation WordPress “DB hygiene” (ciblée)
Ce n’est pas MySQL pur, mais ça change la taille et la performance. Deux actions sûres via WP-CLI :
Nettoyer les transients expirés :
wp transient delete --expired
Limiter les révisions (impact direct sur wp_posts/wp_postmeta). Sur WordPress 6.9.4, c’est toujours via constante :
// wp-config.php
// Limite le nombre de révisions par post (utile sur sites Elementor/Divi/Avada)
define('WP_POST_REVISIONS', 10);
J’ai souvent vu des bases gonflées par des révisions illimitées + autosaves, surtout sur des pages builder où chaque modification génère beaucoup de meta.
Étape 5 : Ajuster MySQL/MariaDB pour WordPress (réglages concrets)
Un WordPress lent n’est pas toujours une table “à optimiser”. Très souvent, c’est un MySQL sous-dimensionné (buffer pool minuscule) ou mal bridé (trop de connexions, query cache mal compris, etc.).
1) Vérifier les variables clés
mysql -h 127.0.0.1 -u root -p -e "
SHOW VARIABLES LIKE 'innodb_buffer_pool_size';
SHOW VARIABLES LIKE 'max_connections';
SHOW VARIABLES LIKE 'tmp_table_size';
SHOW VARIABLES LIKE 'max_heap_table_size';
SHOW VARIABLES LIKE 'innodb_flush_log_at_trx_commit';
SHOW VARIABLES LIKE 'slow_query_log';
SHOW VARIABLES LIKE 'long_query_time';
"
2) Activer un slow query log (temporaire pour diagnostiquer)
Sur un serveur de prod, activez-le avec parcimonie. Mais c’est souvent la seule façon de voir qu’un plugin fait des requêtes monstrueuses sur wp_options.
mysql -h 127.0.0.1 -u root -p -e "
SET GLOBAL slow_query_log = 'ON';
SET GLOBAL long_query_time = 1;
"
Puis observez :
sudo tail -n 200 /var/log/mysql/slow.log
3) Réglages MySQL/MariaDB typiques pour WordPress
Je donne ici des valeurs “point de départ”, pas une vérité universelle. Ajustez selon RAM/CPU et surtout selon votre trafic.
- innodb_buffer_pool_size : souvent trop bas. Sur un serveur dédié WordPress, viser 50–70% de la RAM (si MySQL est le service principal).
- tmp_table_size et max_heap_table_size : évite des temp tables sur disque.
- max_connections : trop haut = OOM possible, trop bas = erreurs 500/DB connect.
Vérifiez la pression mémoire :
free -h
ps aux --sort=-%mem | head -n 15
Sur WordPress, je préfère souvent moins de connexions mais stables, avec un PHP-FPM bien réglé, plutôt qu’un MySQL permissif qui finit par swapper.
4) Point WordPress : autoload dans wp_options
Quand wp_options devient énorme, l’option autoload = 'yes' est souvent le coupable : WordPress charge ces options à chaque requête.
Mesurez :
mysql -h 127.0.0.1 -u votre_user -p -e "
SELECT
ROUND(SUM(LENGTH(option_value))/1024/1024, 2) AS autoload_mb
FROM votre_db.wp_options
WHERE autoload='yes';
"
Listez les plus grosses :
mysql -h 127.0.0.1 -u votre_user -p -e "
SELECT option_name, ROUND(LENGTH(option_value)/1024, 1) AS size_kb
FROM votre_db.wp_options
WHERE autoload='yes'
ORDER BY LENGTH(option_value) DESC
LIMIT 30;
"
Ce que je fais en pratique : je repère l’option, je vérifie à quel plugin elle appartient, puis je corrige côté plugin (réglage) ou je passe l’autoload à no si je suis certain que l’option n’a pas besoin d’être chargée à chaque hit.
Exemple (à manier avec prudence) :
mysql -h 127.0.0.1 -u votre_user -p -e "
UPDATE votre_db.wp_options
SET autoload='no'
WHERE option_name='option_trop_lourde_identifiee'
LIMIT 1;
"
Risque : si vous désactivez l’autoload d’une option critique, vous pouvez casser un plugin (ou provoquer des requêtes supplémentaires). Faites-le sur staging, puis mesurez.
Étape 6 : Automatiser une maintenance sûre (cron + WP-CLI)
Automatiser “OPTIMIZE toutes les tables chaque nuit” est une mauvaise idée. Automatisez plutôt :
- un check régulier,
- un cleanup WordPress (transients expirés),
- et une optimisation ciblée (seulement si
data_freedépasse un seuil, ou sur certaines tables).
1) Script bash de maintenance (safe-by-default)
cat > /usr/local/sbin/wp-db-maintenance.sh <<'BASH'
#!/usr/bin/env bash
set -euo pipefail
# --- Configuration ---
SITE_PATH="/var/www/votre-site"
DB_HOST="127.0.0.1"
DB_NAME="votre_db"
DB_USER="votre_user"
# --- Pré-requis ---
command -v wp >/dev/null 2>&1 || { echo "WP-CLI absent"; exit 1; }
command -v mysql >/dev/null 2>&1 || { echo "mysql client absent"; exit 1; }
cd "$SITE_PATH"
# --- 1) Nettoyage WordPress (sans risque) ---
# Supprime uniquement les transients expirés
wp transient delete --expired --quiet || true
# --- 2) CHECK TABLE (rapide) ---
# On évite de faire un REPAIR automatique en prod.
mysql -h "$DB_HOST" -u "$DB_USER" -p -N -e "
SELECT CONCAT('CHECK TABLE `', table_name, '` QUICK;')
FROM information_schema.tables
WHERE table_schema = '${DB_NAME}';
" | mysql -h "$DB_HOST" -u "$DB_USER" -p "$DB_NAME" > "/var/log/wp-db-check-${DB_NAME}.log" 2>&1
# --- 3) OPTIMIZE ciblé (exemple minimal) ---
# À adapter : ici on optimise seulement wp_options (souvent petite) et wp_posts.
# Attention : sur très grosses tables, ça peut locker selon le moteur.
mysql -h "$DB_HOST" -u "$DB_USER" -p -e "
USE ${DB_NAME};
OPTIMIZE TABLE wp_options;
OPTIMIZE TABLE wp_posts;
" >> "/var/log/wp-db-check-${DB_NAME}.log" 2>&1
BASH
chmod 750 /usr/local/sbin/wp-db-maintenance.sh
Deux erreurs réalistes :
- Mettre le mauvais
SITE_PATHet exécuter WP-CLI dans un autre site (ça arrive sur des serveurs multi-sites). - Oublier le
set -euo pipefailet croire que “tout s’est bien passé” alors que la moitié des commandes ont échoué.
2) Cron (fenêtre de faible trafic)
sudo crontab -e
# Maintenance DB WordPress à 03:20 tous les dimanches
20 3 * * 0 /usr/local/sbin/wp-db-maintenance.sh
Si vous avez un cache serveur (FastCGI cache, Varnish) : prévoyez une purge légère après une grosse maintenance, sinon vous pouvez confondre “amélioration” et “cache qui masque tout”.
Fichiers de configuration complets
Cette section reste volontairement orientée “serveur”. Je fournis des squelettes complets et propres, à adapter. Rien ici ne remplace une stratégie de sauvegarde et de monitoring.
wp-config.php (extrait complet orienté DB)
<?php
/**
* Configuration WordPress 6.9.4+ (extrait orienté base de données)
* PHP 8.1+ recommandé.
*/
define('DB_NAME', 'votre_db');
define('DB_USER', 'votre_user');
define('DB_PASSWORD', 'votre_mot_de_passe');
define('DB_HOST', '127.0.0.1');
define('DB_CHARSET', 'utf8mb4');
define('DB_COLLATE', '');
// Limite les révisions : réduit la croissance de wp_posts/wp_postmeta
define('WP_POST_REVISIONS', 10);
// Désactive l'éditeur de fichiers dans l'admin (réduit le risque en cas de compromission)
define('DISALLOW_FILE_EDIT', true);
// Active un log debug en cas de diagnostic (à désactiver ensuite)
define('WP_DEBUG', false);
define('WP_DEBUG_LOG', true);
define('WP_DEBUG_DISPLAY', false);
// ... le reste du wp-config.php (clés salts, $table_prefix, ABSPATH, etc.)
php.ini (profil court pour éviter des timeouts pendant maintenance)
cat > /etc/php/8.3/fpm/conf.d/99-wp-maintenance.ini <<'INI'
; Ajustements utiles lors d'opérations lourdes (imports, maintenance)
; À adapter selon votre hébergement.
memory_limit = 512M
max_execution_time = 120
max_input_time = 120
post_max_size = 128M
upload_max_filesize = 128M
; Logs d'erreurs : indispensable pour diagnostiquer
log_errors = On
INI
Nginx (extrait complet : timeouts et headers utiles)
cat > /etc/nginx/snippets/wordpress.conf <<'NGINX'
# WordPress - extrait générique
# Objectif : éviter certains timeouts pendant opérations DB et améliorer la sécurité de base.
client_max_body_size 128m;
# Timeouts raisonnables (évite de couper des réponses lentes lors de maintenance)
fastcgi_read_timeout 120s;
fastcgi_send_timeout 120s;
# Headers de sécurité (à valider selon votre site)
add_header X-Content-Type-Options "nosniff" always;
add_header X-Frame-Options "SAMEORIGIN" always;
add_header Referrer-Policy "strict-origin-when-cross-origin" always;
# Ne pas exposer les fichiers sensibles
location ~* /(wp-config.php|readme.html|license.txt) {
deny all;
}
NGINX
MySQL/MariaDB (fichier de conf exemple)
Emplacement selon distro : /etc/mysql/mysql.conf.d/mysqld.cnf ou /etc/my.cnf. Exemple minimal (à adapter à la RAM) :
cat > /etc/mysql/mysql.conf.d/99-wordpress-tuning.cnf <<'CNF'
[mysqld]
# Réglages génériques pour WordPress (à adapter)
# Attention : ne copiez pas ces valeurs sans vérifier la RAM disponible.
# InnoDB (WordPress moderne est majoritairement InnoDB)
innodb_buffer_pool_size = 1G
innodb_log_file_size = 256M
innodb_flush_method = O_DIRECT
# Temp tables (réduit l'usage disque)
tmp_table_size = 128M
max_heap_table_size = 128M
# Connexions : évitez de monter trop haut sans raison
max_connections = 150
# Slow query log (désactivez si inutile)
slow_query_log = 0
long_query_time = 1
CNF
Recharge (selon service) :
sudo systemctl restart mysql
# ou
sudo systemctl restart mariadb
Attention : redémarrer MySQL en prod sans fenêtre peut provoquer une indisponibilité. Planifiez.
Vérification
Après réparation/optimisation/tuning, vérifiez avec des commandes simples et des signaux concrets.
1) Vérifier que WordPress répond et que la DB est joignable
cd /var/www/votre-site
wp core version
wp db check
wp db check doit remonter “Success” (ou une sortie sans erreurs). Si vous voyez des erreurs, ne passez pas à “OPTIMIZE partout”. Identifiez la table.
2) Mesurer la taille des tables
wp db size --all-tables
3) Vérifier les erreurs côté SQL
sudo tail -n 200 /var/log/mysql/error.log
4) Vérifier la latence HTTP (TTFB) rapidement
curl -s -o /dev/null -w "HTTP=%{http_code} TTFB=%{time_starttransfer}s TOTAL=%{time_total}sn" https://votre-domaine.tld/
Si vous avez un cache serveur, faites un test “cache bypass” si possible (cookie, header, URL de purge), sinon vous mesurez surtout le cache.
5) Tableau de diagnostic (symptômes fréquents)
| Symptôme | Cause probable | Vérification | Solution |
|---|---|---|---|
| “table is marked as crashed” | Table MyISAM corrompue après crash | CHECK TABLE + logs MySQL | REPAIR TABLE ciblé + vérifier disque |
| Site lent après migration | Autoload énorme, index manquants, config MySQL faible | Top options autoload + slow query log | Réduire autoload + tuning InnoDB + cache objet |
| Erreurs “Too many connections” | max_connections trop bas ou PHP-FPM trop agressif | SHOW PROCESSLIST + logs | Ajuster PHP-FPM/DB + limiter bots |
| OPTIMIZE bloque le site | Rebuild table + locks sur grosse table | SHOW PROCESSLIST | Faire en heures creuses, table par table, staging d’abord |
| CPU MySQL élevé constant | Requêtes lentes plugin/builder | slow.log | Corriger plugin, index, cache objet, autoload |
Si ça ne marche pas
Quand la réparation/optimisation ne change rien, le problème est souvent ailleurs : disque, RAM, locks, ou requêtes applicatives.
1) Voir ce que MySQL est en train de faire (locks, requêtes longues)
mysql -h 127.0.0.1 -u root -p -e "SHOW FULL PROCESSLIST;"
Si vous voyez des Waiting for table metadata lock ou des requêtes qui durent des minutes, arrêtez les opérations “en masse”.
2) Vérifier l’état InnoDB
mysql -h 127.0.0.1 -u root -p -e "SHOW ENGINE INNODB STATUSG" | sed -n '1,200p'
Vous cherchez :
- deadlocks fréquents,
- buffer pool saturé,
- IO en souffrance (disque lent).
3) Vérifier le disque (souvent la vraie cause)
df -h
sudo dmesg | tail -n 100
sudo smartctl -a /dev/sda | sed -n '1,120p'
Un disque plein pendant un OPTIMIZE/ALTER peut laisser une table dans un état incohérent.
4) Vérifier PHP-FPM (trop de workers = trop de connexions)
sudo systemctl status php8.3-fpm --no-pager
sudo tail -n 200 /var/log/php8.3-fpm.log
5) Vérifier que vous n’avez pas “réparé” la mauvaise base
Erreur classique sur serveur multi-sites : vous lancez vos commandes sur votre_db… mais WordPress pointe vers une autre DB via un DB_HOST différent.
wp config get DB_NAME
wp config get DB_HOST
Pièges et erreurs courantes
| Erreur | Cause | Solution |
|---|---|---|
| Lancer OPTIMIZE sur toutes les tables en prod | Copie d’un “tuto” générique | Optimiser table par table, en heures creuses, après mesure de data_free |
| REPAIR TABLE sur InnoDB en pensant “corriger” une corruption | Confusion MyISAM/InnoDB | Lire les logs, restaurer ou exporter/réimporter, diagnostiquer InnoDB |
| Oublier la sauvegarde | Routine “ça ira” | mysqldump + test gzip + snapshot si possible |
| Se tromper de base (mauvais DB_NAME) | Serveur avec plusieurs sites | Vérifier via wp config get + information_schema |
| Activer slow query log et l’oublier | Diagnostic en urgence | Désactiver après analyse, rotation des logs |
| Utiliser un script trouvé en ligne incompatible | Ancien tutoriel, options obsolètes | Vérifier version MySQL/MariaDB, tester sur staging, lire la doc officielle |
| Confondre “site plus rapide” et “cache qui sert tout” | Tests faits uniquement sur pages cachées | Mesurer TTFB avec et sans cache, analyser slow queries |
Sécurité serveur
La maintenance DB touche à des données sensibles. Les mauvaises pratiques ici finissent en fuite de données ou en compromission.
- Moindre privilège : l’utilisateur MySQL de WordPress ne devrait pas être
root. Donnez uniquement les droits nécessaires. Pour maintenance, utilisez un compte admin séparé. - Backups chiffrés : un dump SQL contient potentiellement des emails, tokens, commandes WooCommerce, etc.
- Accès SSH : clés, pas de mot de passe si possible. Bloquez root login si vous pouvez.
- Limiter l’exposition : MySQL bind sur
127.0.0.1si MySQL est local. - Journaliser : gardez une trace de qui a lancé une opération (sudo logs, shell history contrôlée).
Exemple : vérifier l’écoute réseau MySQL :
sudo ss -lntp | grep -E ":(3306|33060)b" || true
Si MySQL écoute sur 0.0.0.0:3306 sans firewall strict, vous prenez un risque inutile.
Ressources
- WordPress Developer Resources – Advanced Administration
- WP-CLI – Commandes db
- WordPress.org – wp-config.php
- MySQL Reference Manual – CHECK TABLE
- MySQL Reference Manual – OPTIMIZE TABLE
- MariaDB Knowledge Base – REPAIR TABLE
- PHP.net – PDO (pour comprendre les connexions et erreurs côté PHP)
- GitHub – WordPress (miroir du core)
FAQ
Est-ce que “Optimiser les tables” accélère toujours WordPress ?
Non. Sur InnoDB, l’effet peut être nul si le problème est un buffer pool trop petit, des requêtes lentes, ou un autoload démesuré. Optimiser sans diagnostiquer revient souvent à déplacer le problème.
Puis-je lancer OPTIMIZE TABLE sur wp_postmeta sans risque ?
Le risque principal, c’est le lock et la durée. Sur des tables massives (Elementor/Divi/Avada + WooCommerce), ça peut impacter les utilisateurs. Testez sur staging, puis planifiez en heures creuses.
REPAIR TABLE fonctionne-t-il sur InnoDB ?
Dans la pratique, non pour les corruptions InnoDB sérieuses. Il faut s’appuyer sur les logs InnoDB et souvent restaurer/exporter-réimporter.
Dois-je activer WP_ALLOW_REPAIR dans wp-config.php ?
Ça existe toujours, mais je l’évite sur des sites exposés : l’URL de réparation peut être accessible sans authentification selon configuration. Si vous l’utilisez, faites-le brièvement, puis supprimez la constante immédiatement. Préférez WP-CLI et SQL en SSH.
Comment savoir si wp_options est un goulot d’étranglement ?
Mesurez la taille de l’autoload, listez les options les plus lourdes, puis corrigez plugin par plugin. C’est souvent là que se cache la “lenteur mystérieuse”.
mysqlcheck est-il “meilleur” que des commandes SQL ?
Ce n’est pas meilleur, c’est plus automatisable. Pour un diagnostic fin (par table, par engine), les requêtes sur information_schema restent plus précises.
Est-ce que Divi 5 / Elementor / Avada changent quelque chose à la réparation MySQL ?
Ils ne changent pas MySQL, mais ils augmentent beaucoup la volumétrie (posts/meta/options), donc les opérations prennent plus de temps et les locks sont plus visibles. Planifiez vos maintenances en conséquence.
Que faire si OPTIMIZE TABLE reste bloqué ?
Regardez SHOW FULL PROCESSLIST, identifiez le lock, et évitez de tuer au hasard. Tuer une requête pendant une opération DDL peut laisser une table dans un état instable selon le contexte. Si vous devez intervenir, faites-le pendant une fenêtre et avec un plan de restauration.
Faut-il redémarrer MySQL après une optimisation ?
Non. Vous redémarrez MySQL uniquement si vous changez la configuration (buffer pool, etc.) ou si le service est instable. Un redémarrage en prod est un événement.
Comment éviter que le problème revienne ?
Surveillez : taille autoload, croissance de wp_postmeta, slow queries, saturation RAM/disque. Ajoutez une routine cron “check + cleanup” et gardez des sauvegardes testées.