« MySQL server has gone away » : ce message apparaît, invariablement, au pire moment possible, en plein milieu d’un import de plusieurs milliers de fiches produits WooCommerce lancé depuis un fichier CSV volumineux. L’import s’arrête net, sans que la cause ne soit évidente à la première lecture du message, qui ne dit rien d’une erreur de syntaxe SQL mais bien d’une rupture de connexion entre le client et le serveur MySQL.
Ce type d’interruption ne relève pas d’un problème de mémoire PHP, souvent confondu avec cette erreur par réflexe : le processus PHP tourne toujours au moment de l’erreur, c’est bien la connexion à la base de données qui a été coupée, soit par le serveur MySQL lui-même, soit par un intermédiaire réseau entre les deux.
Les deux causes les plus fréquentes
Deux réglages serveur expliquent la très grande majorité des cas rencontrés en production. Le premier est max_allowed_packet, qui définit la taille maximale d’une requête ou d’un résultat échangé entre le client et le serveur MySQL. Un import qui insère une ligne produit avec une description longue et enrichie en HTML peut facilement dépasser une valeur historiquement fixée à seulement quelques mégaoctets.
Le second est wait_timeout, qui définit la durée maximale d’inactivité tolérée sur une connexion avant que le serveur ne la ferme automatiquement. Un import qui traite chaque ligne avec un traitement PHP lourd entre deux insertions (génération de vignette, appel à une API externe de traduction ou de tarification) peut dépasser ce délai sans qu’aucune requête ne soit envoyée entre-temps, provoquant la fermeture de la connexion côté serveur.
Diagnostiquer lequel des deux est en cause

Le journal d’erreur MySQL, une fois consulté juste après l’incident, donne souvent une indication directe :
tail -50 /var/log/mysql/error.log
# [Warning] Aborted connection 4821 to db: 'wp_boutique' user: 'wp_user'
# host: 'localhost' (Got a packet bigger than 'max_allowed_packet' bytes)
Si le message mentionne explicitement max_allowed_packet, la cause est confirmée directement. En l’absence de cette mention précise, il faut regarder le temps écoulé entre les dernières requêtes réussies dans le journal général de requêtes, s’il est activé, pour vérifier si un délai anormalement long précède l’interruption.
Corriger max_allowed_packet
# my.cnf, dans la section [mysqld]
max_allowed_packet = 64M
Après modification, un redémarrage du service MySQL est nécessaire pour appliquer la nouvelle valeur, qui peut également être vérifiée à chaud sans redémarrage via une commande SQL, bien que la persistance après redémarrage impose la modification du fichier de configuration :
SHOW VARIABLES LIKE 'max_allowed_packet';
SET GLOBAL max_allowed_packet = 67108864;
Corriger wait_timeout côté serveur et applicatif
# my.cnf, dans la section [mysqld]
wait_timeout = 300
interactive_timeout = 300
Sur un mutualisé où l’accès à la configuration serveur MySQL n’est pas possible, la solution consiste à découper l’import en lots plus petits plutôt que de dépendre d’un réglage serveur inaccessible. Avec WP-CLI, cela s’écrit simplement via un script qui traite les lignes du CSV par paquets de cinq cents, avec une nouvelle connexion à chaque lot :
wp eval-file importer-par-lots.php --lot=500
Prévention pour les prochains imports
- Vérifier
max_allowed_packetavant tout import volumineux, jamais après le premier échec - Découper systématiquement les imports de plus de mille lignes en lots gérables
- Éviter les traitements lents (appels API externes) entre deux insertions dans une même transaction ouverte
Un import volumineux ne doit jamais dépendre d’une connexion unique maintenue ouverte pendant toute sa durée : découper en lots protège autant contre les timeouts que contre une interruption réseau ponctuelle, qui ne perd alors qu’un seul lot à rejouer, pas l’import entier.
En résumé
« MySQL server has gone away » pendant un import volumineux pointe presque toujours vers l’un de deux réglages serveur, max_allowed_packet ou wait_timeout, jamais vers une erreur de mémoire PHP malgré la ressemblance apparente des symptômes. Le journal d’erreur MySQL confirme rapidement lequel des deux est en cause, et un import découpé en lots reste la protection la plus robuste, y compris sur un serveur où les réglages ne peuvent pas être modifiés directement.