Le moyen le moins cher de déterminer si une connexion MySQL est toujours en vie
J'ai un pool de connexions MySQL pour un web-base de données du service. Quand il commence à une requête, il faut une connexion à partir de la piscine à utiliser. Le problème est que si il y a eu une longue pause depuis cette connexion particulière a été utilisé, le serveur peut avoir expiré et fermé à son extrémité. Je aimerais être en mesure de le détecter dans la piscine de gestion de code.
Le truc, c'est que L'environnement dans lequel je code me donne seulement un très abstraite de l'API dans la connexion. Je ne peut en principe exécuter des instructions SQL. Je n'ai pas accès à la réelle prise ou d'un accès direct à la base de l'API client.
Donc, la question est: Ce qui est le moins cher MySQL déclaration je peux les exécuter sur la connexion afin de déterminer si elle est en travail. Par exemple SELECT 1;
devrait fonctionner, mais je me demandais si il y a quelque chose d'encore moins cher? Peut-être quelque chose qui ne va même pas dans le fil, mais est gérée dans le client MySQL lib et efficacement des réponses à la même question?
Précisions: je ne suis pas concerné, il s'agit de vérifier si le serveur MySQL est en cours d'exécution, ou si c'est la configuration de base de données est suffisante pour répondre aux requêtes. Si ces choses sont en bas, puis par la suite SQL que le service s'exécute permettra d'obtenir et de gérer l'erreur approprié. Je ne suis vraiment intéressé à si la connexion TCP est ouvert... car si le serveur a fermé, puis le service web de SQL obtiendrez un message d'erreur qui signifie "juste rebranchez-le et essayez à nouveau", et qui serait un inconvénient à faire une fois dans la fange du code de service.
Fermeture: La /* ping */
hack est exactement le genre de chose que je cherchais, mais hélas n'est disponible que via JDBC. La lecture par le biais de la documentation pour ce hack, il est clair qu'il a été mis là pour exactement la même raison que je l'ai voulu. Pour les curieux, je travaille dans Haskelà l'aide de HDBC et HDBC-mysql. Je vais demander à l'auteur de HDBC-mysql pour ajouter un moyen d'appeler mysql_ping()
soit directement ou par l'intermédiaire d'un semblable hack.
Vlad DO 1
était aussi le genre de chose que je recherchais, et comme les autres hack n'est pas disponible à l'extérieur de JDBC, je vais être en utilisant.
Merci à tous pour le grand débat, en particulier par @Vlad!
source d'informationauteur MtnViewMark
Vous devez vous connecter pour publier un commentaire.
Vous ne va pas connaître le véritable état de la connexion sans aller sur le filet
SELECT 1
est un assez bon candidat (sans doute vous pourriez en venir à une commande plus courte qui prend moins de temps à l'analyse, mais par rapport au réseau ou même de bouclage de latence de ces économies seraient insignifiants.)Ceci étant dit, je dirais que ping une connexion avant de contrôle de la piscine n'est pas la meilleure approche.
Vous devriez probablement tout simplement avoir votre gestionnaire de pool de connexion de faire appliquer ses propres keep-alive (timeout) politique pour éviter d'être déconnecté par le serveur (court plus sérieuses intervenant problème de connectivité, ce qui pourrait vous toucher en plein milieu de leur fonctionnement habituel de toute façon, et que votre gestionnaire de pool de connexion serait pas en mesure d'aider avec tout de même), ainsi que afin de ne pas monopoliser la base de données (pensez descripteurs et l'utilisation de la mémoire) inutilement.
Il est donc permis de se demander, à mon avis, ce que le test de la valeur de la connectivité en condition avant de vérifier une connexion de la piscine. Il peut être intéressant de tester l'état de connexion avant qu'une connexion est cochée dans le dos dans la piscinemais qui peut être fait de façon implicite en marquant simplement la connexion en tant que sales quand un SQL erreur de disque dur (ou l'équivalent exception) se pose (à moins que l'API que vous utilisez déjà expose un
is-bad
-comme l'appel pour vous.)Je recommande donc:
Mise à JOUR
Il semblerait, d'après vos commentaires que vous avez vraiment vraiment pour la requête ping de la connexion (je suppose que c'est parce que vous n'avez pas le plein contrôle, ou de la connaissance, de délai d'expiration de caractéristiques sur le serveur MySQL ou intervenant équipements de réseau tels que les procurations, etc.)
Dans ce cas, vous pouvez utiliser
1
comme une alternative àSELECT 1
; il est légèrement plus vite-moins de temps pour analyser, et il ne renvoie pas de données réelles (bien que vous sera obtenir le TCPack
s, de sorte que vous aurez toujours à faire l'aller-retour pour valider que le lien est encore mis en place.)Mise à JOUR 2
Concernant Joshua postvoici la capture de paquets des traces pour les différents scénarios:
Comme vous pouvez le voir, sauf pour le fait que le
mysql_ping
paquet de 5 octets au lieu deDO 1;
s 9 octets, le nombre d'allers-retours (et, par conséquent, réseau induite par la latence) est exactement le même. Le seul coût supplémentaire que vous payez avecDO 1
par opposition àmysql_ping
est de l'analyse deDO 1
ce qui est trivial.Je ne suis pas sûr de ce que l'API que vous utilisez actuellement (ou quelle langue), mais pour Java, il y a un truc spécial le pilote JDBC peut faire.
Le test standard de requête est:
comme vous l'avez indiqué. Si vous le modifiez à:
le pilote JDBC avis de ce, et à envoyer un seul paquet au serveur MySQL pour obtenir une réponse.
Je l'ai appris au Soleil 'Plongée' épisode intitulé MySQL Conseils pour les Développeurs Java Avec Mark Matthews.
Même si vous n'êtes pas à l'aide de Java, peut-être que cette astuce a été mis en œuvre dans d'autres pilotes mysql? Je suppose que le serveur doit être au courant de ce paquet spécial de sorte qu'il peut envoyer une réponse...
"Connexion" dans ce cas, a des significations multiples. MySQL écoute sur une socket, c'est le réseau "au niveau de la connexion." MySQL gère "connexions de base de données", qui comprend un cadre pour l'exécution de la requête et d'autres frais généraux.
Si vous voulez simplement savoir si le service est à l'écoute, vous devriez être en mesure d'exécuter un réseau au niveau de l'appeler pour voir si le port (vous ne savez pas ce qu'est la valeur par défaut) est en écoute sur l'IP cible. Si vous voulez obtenir le MySQL moteur de répondre, je pense que votre
SELECT 1
idée est bonne - il ne fait pas l'extraction des données à partir de la base de données, mais ne confirme que le moteur est en rotation et de répondre.