L’erreur « MySQL server has gone away » signifie que le serveur MySQL (mysqld) s’est arrêté et a fermé la connexion. Par défaut, MySQL ferme les connexions au bout de huit heures (28800 secondes) si rien ne se passe. Cependant, dans certains cas, votre hébergeur, DBA ou développeur d’applications peut avoir diminué ce paramètre de temporisation, dont il est question ci-dessous.

Le serveur MySQL a disparu, ce qui peut être une erreur frustrante à résoudre. Cela est dû en partie au fait que pour faire disparaître cette erreur, la solution implique parfois de multiples modifications de la configuration du serveur, de l’application ou du service. Cet article présente des solutions que j’ai vues pour cette erreur générale du serveur MySQL. Si vous avez trouvé une solution qui ne figure pas dans la liste ou qui n’est pas liée à cette page, veuillez m’envoyer une note ou laisser un commentaire.

Le serveur MySQL a disparu

Le serveur MySQL a disparu Exemples de journaux d’erreurs
N’oubliez pas que cette erreur peut être enregistrée de plusieurs façons, comme indiqué ci-dessous. En outre, l’erreur n’est parfois qu’une indication d’un problème sous-jacent plus profond. Cela signifie que l’erreur peut être due à un problème ou à un bogue dans votre application de connexion ou votre service à distance. Dans ce cas, vous devez vérifier TOUS les journaux d’erreurs associés avec le même horodatage, afin de déterminer si un autre problème peut être à l’origine de l’erreur. Les solutions de surveillance des performances des applications et les outils de suivi de la pile PHP peuvent vous aider. Dans cette optique, voici des exemples de journaux d’erreurs du serveur MySQL dont l’erreur a disparu :

Erreur générale : le serveur MySQL 2006 a disparu
Code d’erreur : 2013. Perte de connexion au serveur MySQL lors de la requête
Avertissement : Erreur lors de l’envoi d’un paquet QUERY
Exception AOP : SQLSTATE [HY000] : Erreur générale : le serveur MySQL 2006 a disparu

MySQL wait_timeout
La raison pour laquelle l’erreur du serveur MySQL a disparu, est souvent que le wait_timeout de MySQL a été dépassé. Le wait_timeout de MySQL est le nombre de secondes pendant lesquelles le serveur attend une activité sur une connexion non interactive avant de la fermer. Vous devez vous assurer que le wait_timeout n’est pas réglé trop bas. Le délai d’attente par défaut pour MySQL est de 28800 secondes. Souvent, il est abaissé arbitrairement. Cela dit, plus le wait_timeout est bas sans affecter les connexions à la base de données, ce qui peut être un bon signe de l’efficacité de la base de données MySQL. Vérifiez également les variables : net_read_timeout, net_write_timeout et interactive_timeout. Ajustez ou ajoutez les lignes suivantes dans my.cnf pour répondre à vos besoins :

wait_timeout=90
net_read_timeout=90
net_write_timeout=90
interactive_timeout=300
connect_timeout=90

Délai de connexion MySQL dans la configuration PHP
Regardez dans votre fichier de configuration php.ini. Vous y trouverez les options de configuration de MySQL. Assurez-vous que le paramètre mysql.connect_timeout n’est pas inférieur à MySQL wait_timeout, dont il est question ci-dessus. L’option PHP mysql.connect_timeout n’est pas seulement utilisée pour le délai de connexion, mais aussi pour attendre la première réponse du serveur MySQL. Essayez d’augmenter mysql.connect_timeout pour qu’il corresponde ou dépasse votre MySQL wait_timeout et assurez-vous que mysql.allow_persistent est activé (par défaut = activé).

mysql.connect_timeout=90
mysql.allow_persistent=1
IMPORTANT : Lisez d’abord ce qui concerne les connexions de base de données persistantes PHP pour en comprendre les avantages et les inconvénients.

Ajustez également le délai d’attente par défaut de PHP (default_socket_timeout). Par exemple, un script PHP pourrait exécuter une requête lente. Créer une attente qui utilise le default_socket_timeout. Il finit par s’arrêter avec l’erreur « MySQL server has gone away ». Avant d’envoyer des messages haineux, veuillez lire ce qui suit. En voici un extrait :

« PHP, par défaut, fixe un délai d’attente de lecture de 60 secondes pour les flux. Ce délai est défini via le fichier php.ini, default_socket_timeout. Cette valeur par défaut s’applique à tous les flux qui ne définissent aucune autre valeur de délai. mysqlnd ne définit aucune autre valeur et, par conséquent, les connexions des requêtes de longue durée peuvent être déconnectées après les secondes de default_socket_timeout, ce qui entraîne un message d’erreur 2006 – MySQL Server has gone away ».

default_socket_timeout=90
Pour être complet, ajustez également max_execution_time et max_input_time toujours dans php.ini, si nécessaire. Si le temps d’exécution de PHP est plus long que max_execution_time, le serveur MySQL peut se déconnecter.

max_execution_time = 90
max_input_time = 90

MySQL max_allowed_packet
max_allowed_packet est la taille maximale d’un paquet. La taille par défaut de 4MB aide le serveur MySQL à capturer les paquets de grande taille (éventuellement incorrects). À partir de MySQL 8, la valeur par défaut a été portée à 16 Mo. Si mysqld reçoit un paquet trop volumineux, il suppose que quelque chose ne va pas et ferme la connexion. Pour résoudre ce problème, vous devez augmenter le paquet max_allowed_packet dans my.cnf, puis redémarrer MySQL. Le maximum pour ce paramètre est de 1 Go. Par exemple :

max_allowed_packet = 512M

MySQL innodb_log_file_size
Vous devrez peut-être augmenter la variable MySQL innodb_log_file_size dans votre configuration my.cnf. La taille du fichier innodb_log de MySQL devrait être égale à 25 % de la taille du pool innodb_buffer_pool (si possible, pas moins de 20 %). Gardez à l’esprit que plus cette valeur est élevée, plus il faudra de temps pour récupérer d’un crash de la base de données. (Source : Phpmyadmin Advisor)

Appoptique des vents solaires
Cela signifie par exemple que si la taille de votre pool de tampons est fixée à innodb_buffer_pool_size=16G et que votre paramètre innodb_log_files_in_group est toujours fixé à la valeur par défaut recommandée de 2 fichiers (innodb_log_files_in_group=2), alors votre taille innodb_log_file_size devrait être fixée à 2G. Cela créera deux (2) fichiers journaux de 2 Go chacun, ce qui équivaut à 25 % de innodb_buffer_pool_size=16G.

ATTENTION : Vous devez arrêter le serveur MySQL afin de modifier la taille de innodb_log_file_size ou innodb_log_files_in_group. Si vous ne le faites pas, vous risquez la catastrophe ! (Lire : Instructions pour la refonte du logo MySQL).

Les autres causes de la disparition du serveur MySQL
Connexions MySQL à distance
Rappelez-vous que j’ai déjà mentionné que l’erreur, parfois, n’est que le signe d’un problème sous-jacent plus profond. Par exemple, les connexions MySQL à distance à des services tiers. Utilisation d’un plugin de traitement des paiements de tiers pour osCommerce, Magento, etc.

Jeu de caractères et collationnement de la base de données MySQL
Changer le jeu de caractères par défaut de la base de données en latin1 et la collation par défaut en latin1_general_ci semble avoir résolu le problème. Le serveur MySQL a disparu pour certains.

Dépassement du paramètre max_connections de MySQL
Le nombre maximum autorisé de connexions simultanées de clients est fixé par max_connections. Faites attention à ce réglage ! L’épuisement de la mémoire et d’autres ressources peut se produire lorsque le paramètre est trop élevé et que la surcharge de planification augmente également. À titre indicatif, fixez max_connections à environ le double du nombre précédent de connexions client simultanées maximum. Par exemple, si après un mois de fonctionnement, le nombre maximum de connexions client simultanées était de 114, alors réglez max_connections=250. Avant de devenir fou avec ce réglage, veuillez lire : Comment MySQL gère les connexions clients.

Toujours pas résolu ? Voir la page d’aide de MySQL
Oracle a mis en place une belle page d’auto-assistance pour le serveur MySQL a supprimé les erreurs. Sur cette page, ils vous suggèrent également de vous assurer que MySQL ne s’est pas arrêté/redémarré pendant la requête. Extrait :

« Vous pouvez vérifier si le serveur MySQL est mort et a redémarré en exécutant la version mysqladmin et en examinant le temps de fonctionnement du serveur. Si la connexion du client a été interrompue parce que mysqld a planté et redémarré, vous devez vous concentrer sur la recherche de la raison du plantage ».