Mysql
 sql >> Base de données >  >> RDS >> Mysql

mysql_ping se bloque avec Amazon RDS

Je ne trouve pas de citation dans la documentation, mais mon expérience suggère que l'infrastructure réseau d'EC2 en général (qui inclurait RDS et probablement tout autre service AWS qui s'exécute sur des machines virtuelles provisionnées par client, sinon tous AWS, et ne semble certainement pas se limiter strictement aux "instances EC2") implémente l'inspection de paquets avec état, et "oubliera" qu'une connexion TCP est valide après quelques minutes d'inactivité absolue... provoquant le comportement que vous décrivez.

Les machines aux deux extrémités de la connexion peuvent être convaincues que la connexion existe toujours, mais le réseau ne permettra pas au trafic de passer entre elles, car les sessions TCP dans un environnement SPI ne sont pas découvertes, elles sont créées et ne peuvent que être créé lorsque le réseau voit la connexion au tout début (SYN, SYN/ACK, ACK ). J'ai initialement rencontré ce problème avec les serveurs MySQL dans EC2 (pas RDS), mais je serais très surpris si la cause sous-jacente n'était pas la même.

Il existe deux approches possibles pour contourner ce problème.

Si votre machine PHP est Linux, configurez le noyau pour maintenir les connexions actives à la couche 4. Ce changement sera invisible pour vous dans le sens où ces keepalives ne changeront pas la valeur dans le Time colonne dans SHOW PROCESSLIST pour les connexions en Sleep car cela ne réinitialisera pas le temps pendant lequel la connexion a été inactive à la couche 7 ... mais cela devrait éviter les délais d'attente de l'infrastructure AWS si les bibliothèques gérant les connexions MySQL définissent correctement les options de socket pour en tirer parti.

http://tldp.org/HOWTO/TCP-Keepalive-HOWTO/usingkeepalive .html explique comment le configurer en direct et comment le rendre persistant lors des redémarrages.

A défaut, l'autre option est de forcer MySQL à fermer la connexion plus tôt que le délai d'attente du réseau afin que la machine PHP reconnaisse immédiatement qu'elle essaie de parler sur un socket fermé. Il peut sembler contre-intuitif de raccourcir un délai d'attente plutôt que de le prolonger, mais raccourcir le délai d'attente devrait entraîner l'échec très rapide de votre test ping si une session est restée inactive trop longtemps, ce qui "résout" également (essentiellement) le problème, en supposant que la santé mentale dans la bibliothèque client PHP. Une fois que votre application est plus occupée, les connexions seront probablement rarement inactives assez longtemps pour atteindre le délai d'expiration.

Le serveur MySQL a deux paramètres de délai d'inactivité différents : wait_timeout (pour les sessions non interactives, c'est-à-dire les connexions à partir du code, comme PHP) et interactive_timeout (à partir des navigateurs de requêtes et du client en ligne de commande) mais le serveur ne connaît la différence que parce que la bibliothèque cliente doit notifier au serveur le type de connexion qu'elle établit. En supposant que votre bibliothèque cliente utilise la configuration correcte, alors wait_timeout est celui que vous cherchez. Le définir sur une valeur inférieure à 900 devrait résoudre le problème si la modification des paramètres TCP keepalive dans le noyau Linux ne le fait pas. Notez cependant qu'après avoir effectué la modification, seules les connexions futures seront affectées - les connexions déjà établies lors de la modification seront toujours exécutées avec la valeur actuelle, qui est par défaut de 8 heures (28800 secondes). Ceux-ci sont configurables dans le groupe de paramètres RDS pour votre instance.

Il existe des indices de comportement similaire dans la documentation AWS ici , ainsi que les paramètres de registre Windows qui doivent être ajustés pour modifier les keepalives TCP si vous exécutez le serveur PHP sous Windows, au lieu de Linux, comme je l'ai supposé ci-dessus ... même si l'article concerne spécifiquement Redshift et les connexions externes à EC2 semble toujours valider le problème sous-jacent, comme indiqué ci-dessus.