Une étude de cas d'interruption de connexion MySQL causée par une surcharge du cache TCP

Comment analyser la possibilité de cibler d’autres facteurs que MySQL lui-même ?

Auteur : Gong Tangjie, membre de l'équipe ACOS DBA, est principalement responsable du support technique MySQL et maîtrise parfaitement MySQL, PG et les bases de données nationales.

Produit par la communauté open source Aikeson, le contenu original ne peut être utilisé sans autorisation. Veuillez contacter l'éditeur et indiquer la source de réimpression.

Cet article compte environ 1 200 mots et devrait prendre 3 minutes à lire.

arrière-plan

Lors de l'exécution de tâches batch, l'application rencontrait un problème : la connexion à la base de données pour certaines tâches était soudainement perdue, ce qui empêchait la réalisation de la tâche. Dans le journal des erreurs de la base de données, des informations de connexion abandonnée ont été trouvées, ce qui indique que la communication entre le client et le serveur a été anormalement interrompue.

analyser

Afin de découvrir la cause du problème, nous avons d'abord analysé plusieurs situations courantes pouvant entraîner l'interruption de la connexion, sur la base de notre expérience :

  1. Le client n'a pas fermé la connexion correctement et n'a pas appelé mysql_close()la fonction.
  2. Si le temps d'inactivité du client dépasse wait_timeoutles interactive_timeoutsecondes du paramètre ou, le serveur se déconnecte automatiquement.
  3. La taille du paquet envoyé ou reçu par le client dépasse max_allowed_packetla valeur du paramètre, provoquant l'interruption de la connexion.
  4. Le client a tenté d'accéder à la base de données mais n'en avait pas l'autorisation, ou un mauvais mot de passe a été utilisé, ou le paquet de connexion ne contenait pas les informations correctes.

Cependant, après enquête, il s’est avéré qu’aucune des situations ci-dessus ne s’applique au problème actuel. Étant donné que les tâches s'exécutaient normalement auparavant et que le programme n'a pas changé, la première situation peut être exclue. J'ai vérifié les paramètres de délai d'attente de MySQL wait_timeoutet interactive_timeoutj'ai constaté qu'ils étaient tous deux de 28 800, soit 8 heures, ce qui dépasse de loin le temps d'exécution de la tâche, la deuxième situation peut donc être exclue. J'ai également vérifié max_allowed_packetles paramètres du client et du serveur et j'ai constaté qu'ils font tous deux 64 Mo et qu'il est peu probable qu'ils dépassent cette limite, la troisième situation peut donc être exclue. Nous avons également confirmé que les droits d'accès à la base de données, le mot de passe, le package de connexion et d'autres informations du client sont tous corrects, la quatrième situation peut donc être exclue.

À ce stade, nous pensons initialement qu’il ne devrait y avoir aucun problème au niveau MySQL, et que le problème peut résider ailleurs.

Afin de mieux localiser le problème, nous avons essayé de modifier certains paramètres pertinents du noyau du serveur, comme suit :

net.ipv4.tcp_keepalive_intvl = 30
net.ipv4.tcp_keepalive_probes = 3
net.ipv4.tcp_keepalive_time = 120
net.core.rmem_default = 2097152
net.core.wmem_default = 2097152
net.ipv4.tcp_tw_reuse = 1
net.ipv4.tcp_max_syn_backlog = 16384

Ces paramètres visent principalement à optimiser les performances et la stabilité de la connexion réseau et à éviter que la connexion ne soit fermée de manière inattendue ou expire. Cependant, les résultats modifiés ne se sont pas améliorés et la connexion sera toujours interrompue anormalement.

Enfin, nous avons tenté l'analyse de capture de paquets. À l'aide de l'outil Wireshark , nous avons découvert un phénomène anormal : le serveur envoyait un grand nombre de paquets ACK au client. Comme indiqué ci-dessous:

Ces paquets ACK sont des paquets de confirmation dans le protocole TCP, indiquant que le serveur a reçu le paquet de données du client et demande au client de continuer à envoyer des données. Mais pourquoi le serveur envoie-t-il autant de paquets ACK ? Nous pensons qu'il peut y avoir une anomalie dans le réseau, empêchant le client de recevoir le paquet ACK renvoyé par le serveur, de sorte que le serveur enverra à plusieurs reprises des paquets ACK jusqu'à ce qu'il expire ou reçoive une réponse du client. Cependant, après enquête menée par le personnel du réseau, aucun problème évident n’a été découvert.

En continuant à analyser la capture du paquet, nous avons découvert un autre phénomène anormal : le client donnera quelques fenêtres d'avertissement au serveur expéditeur. Comme indiqué ci-dessous:

Ces avertissements de fenêtre constituent un mécanisme de contrôle de flux dans le protocole TCP, indiquant que la fenêtre de réception du serveur ou du client est pleine et ne peut pas recevoir davantage de données.

[TCP Window Full] est une fenêtre d'avertissement envoyée par l'expéditeur au destinataire, indiquant que la limite du récepteur de données a été atteinte.

[TCP ZeroWindow] est un avertissement de fenêtre envoyé par l'extrémité réceptrice à l'extrémité émettrice, indiquant à l'expéditeur que la fenêtre de réception de l'extrémité réceptrice est pleine et arrête temporairement l'envoi.

Sur la base des informations ci-dessus, nous pensons que la cause du problème est la suivante : comme les données que MySQL doit envoyer sont trop volumineuses, le cache TCP du client est plein, il doit donc attendre que le client digère les données dans le TCP. cache avant de pouvoir continuer à recevoir des données. Cependant, pendant cette période, MySQL continuera de demander au client de continuer à envoyer des données. Si le client ne répond pas dans un certain délai (la valeur par défaut est de 60 secondes), MySQL considérera que l'envoi de données a expiré et interrompra la connexion.

Afin de vérifier la spéculation, j'ai vérifié le journal lent de MySQL et j'ai trouvé de nombreux enregistrements Last_errno: 1161 .

Ces enregistrements indiquent que MySQL a rencontré une erreur de délai d'attente lors de l'envoi des données et que le nombre d'occurrences est très proche du nombre de tâches d'application ayant échoué. Selon le site officiel de MySQL, la signification de cette erreur est la suivante :

Numéro d'erreur : 1161 ; Symbole : ER_NET_WRITE_INTERRUPTED ; ÉTAT SQL : 08S01

Message : Le délai d'écriture des paquets de communication a expiré

On peut voir que cela signifie que l'écriture réseau est interrompue, et il existe un paramètre au niveau MySQL pour contrôler cela, alors essayez de changer le paramètre net_write_timeout sur 600, et la tâche par lots s'exécutera normalement.

Par conséquent, la raison pour laquelle la connexion MySQL est anormalement interrompue est que la base de données obtenue par le client est trop volumineuse et dépasse le cache TCP du client. Le client doit d'abord traiter les données dans le cache. Pendant cette période, MySQL continuera à demander. le client a continué à envoyer des données, mais le client n'a pas répondu dans les 60 secondes, ce qui a provoqué l'expiration du délai d'envoi des données par MySQL et l'interruption de la connexion.

en conclusion

Grâce à l’analyse et aux tentatives ci-dessus, nous sommes parvenus aux conclusions suivantes :

  • Dans les informations de capture de paquets, il y a beaucoup d'informations ACK car le cache du client est plein et ne peut pas envoyer de retour au serveur à temps, donc le serveur enverra à plusieurs reprises des informations ACK jusqu'à plus de 60 secondes ( net_write_timeoutla valeur par défaut est 60), provoquant MySQL pour interrompre la connexion.
  • Dans le journal lent, il y a beaucoup d' enregistrements Last_errno: 1161 car le SQL a en fait été exécuté dans MySQL, mais lors de l'envoi de données au client, la quantité de données dépasse le cache TCP du client, puis le client L'application n'a pas traité le données dans le cache dans les 60 secondes, ce qui entraîne l'expiration du délai d'attente de MySQL lors de l'envoi des données au client.
  • L'ajustement net_write_timeoutdes paramètres au niveau MySQL ne peut qu'atténuer ce phénomène. La cause première est que la quantité de données obtenues par un seul SQL est trop importante et dépasse la taille du cache du client. L'application ne peut pas traiter les données dans le cache en peu de temps. ce qui entraîne l'expiration du délai d'envoi des données ultérieures.

Suggestions d'optimisation

  • Les données sont traitées par lots au niveau métier pour éviter qu'une seule requête SQL n'obtienne une grande quantité de données du serveur, ce qui entraînerait un cache TCP insuffisant côté client.
  • Augmenter les paramètres dans MySQL net_write_timeoutou augmenter le cache TCP du client peut atténuer cette situation, mais cela ne peut pas résoudre complètement le problème car trop de données affecteront toujours les performances et la stabilité.
  • Optimisez les instructions SQL pour réduire les retours de données inutiles, comme l'utilisation de LIMIT, WHERE et d'autres conditions, ou l'utilisation de fonctions d'agrégation, de fonctions de regroupement, etc., pour réduire la quantité de données et améliorer l'efficacité des requêtes.

Pour des articles plus techniques, veuillez visiter : https://opensource.actionsky.com/

À propos de SQLE

SQLE est une plateforme complète de gestion de la qualité SQL qui couvre l'audit et la gestion SQL, du développement aux environnements de production. Il prend en charge les bases de données open source, commerciales et nationales grand public, fournit des capacités d'automatisation des processus pour le développement, l'exploitation et la maintenance, améliore l'efficacité en ligne et améliore la qualité des données.

SQLE obtenir

taper adresse
Dépôt https://github.com/actiontech/sqle
document https://actiontech.github.io/sqle-docs/
publier des nouvelles https://github.com/actiontech/sqle/releases
Documentation de développement du plug-in d'audit des données https://actiontech.github.io/sqle-docs/docs/dev-manual/plugins/howtouse
Linus a pris les choses en main pour empêcher les développeurs du noyau de remplacer les tabulations par des espaces. Son père est l'un des rares dirigeants capables d'écrire du code, son deuxième fils est directeur du département de technologie open source et son plus jeune fils est un noyau. contributeur à l'open source. Huawei : Il a fallu 1 an pour convertir 5 000 applications mobiles couramment utilisées Migration complète vers Hongmeng Java est le langage le plus sujet aux vulnérabilités tierces Wang Chenglu, le père de Hongmeng : l'open source Hongmeng est la seule innovation architecturale. dans le domaine des logiciels de base en Chine, Ma Huateng et Zhou Hongyi se serrent la main pour « éliminer les rancunes ». Ancien développeur de Microsoft : les performances de Windows 11 sont « ridiculement mauvaises » " Bien que ce que Laoxiangji est open source, ce ne soit pas le code, les raisons qui le sous-tendent. sont très réconfortants. Meta Llama 3 est officiellement publié. Google annonce une restructuration à grande échelle.
{{o.name}}
{{m.nom}}

Je suppose que tu aimes

Origine my.oschina.net/actiontechoss/blog/11054532
conseillé
Classement