Ceci est pris presque mot pour mot de ma réponse ici , mais je sais que nous fronçons les sourcils sur les réponses uniquement sur SO donc j'imagine que vous le faites aussi :-)
Si vous rencontrez ce problème et utilisez une version de Windows antérieure à Windows 7, ce n'est probablement pas la réponse à votre problème.
Pourquoi cela arrive-t-il?
La cause de ce problème est IPv4 vs IPv6.
Lorsque vous utilisez un nom d'hôte au lieu d'une adresse IP, le client MySQL exécute d'abord une AAAA
recherche d'hôte (IPv6) pour le nom et essaie d'abord cette adresse s'il réussit à résoudre le nom en adresse IPv6. Si l'une des étapes échoue (résolution de nom ou connexion), elle reviendra à IPv4, exécutant une A
recherche et essayant cet hôte à la place.
En pratique, cela signifie que si la localhost
recherche IPv6 réussit mais que MySQL n'est pas lié au bouclage IPv6, vous devrez attendre un cycle d'expiration de connexion avant que le repli IPv4 ne se produise et que la connexion réussisse.
Ce n'était pas un problème avant Windows 7, car la localhost
résolution était effectuée via le fichier hosts, et il était préconfiguré uniquement 127.0.0.1
- il n'était pas fourni avec son homologue IPv6 ::1
.
Depuis Windows 7, cependant, la localhost
résolution est intégrée au résolveur DNS, pour les raisons décrites ici . Cela signifie que la recherche IPv6 va maintenant réussir - mais MySQL n'est pas lié à cette adresse IPv6, donc la connexion échouera et vous verrez le délai décrit dans cette question.
C'est zonte. Dites-moi simplement comment y remédier déjà!
Vous avez quelques options. En regardant autour d'Internet, la «solution» générale semble être d'utiliser explicitement l'adresse IP au lieu du nom, mais il y a quelques raisons de ne pas le faire, toutes deux liées à la portabilité, sans doute sans importance:
Si vous déplacez votre script vers une autre machine qui ne prend en charge que IPv6, votre script ne fonctionnera plus.
Si vous déplacez votre script vers un environnement d'hébergement basé sur * nix, la chaîne magique localhost
signifierait que le client MySQL préférerait utiliser une socket Unix si une est configurée, c'est plus efficace que la connectivité basée sur le bouclage IP
Ils semblent assez importants cependant?
Ils ne le sont pas. Vous devez concevoir votre application pour que ce genre de chose soit défini dans un fichier de configuration. Si vous déplacez votre script vers un autre environnement, il est probable que d'autres choses devront également être configurées.
En résumé, l'utilisation de l'adresse IP n'est pas la meilleure solution, mais elle est probablement acceptable.
Quelle est donc la meilleure solution?
La meilleure façon serait de changer l'adresse de liaison utilisée par le serveur MySQL. Cependant, ce n'est pas aussi simple qu'on pourrait le souhaiter. Contrairement à Apache, Nginx et à presque toutes les autres applications de service réseau sensées jamais créées, MySQL ne prend en charge qu'une seule adresse de liaison, il ne s'agit donc pas simplement d'en ajouter une autre. Heureusement, les systèmes d'exploitation prennent en charge un peu de magie ici, nous pouvons donc permettre à MySQL d'utiliser simultanément IPv4 et IPv6.
Vous devez exécuter MySQL 5.5.3 ou une version ultérieure, et vous devez démarrer MySQL avec l' --bind-address=
argument de ligne de commande. Vous avez 4 documents d' options , selon ce que vous voulez faire:
Celui que vous connaissez probablement, et celui que vous êtes le plus susceptible (efficace) en utilisant 0.0.0.0
. Cela se lie à toutes les adresses IPv4 disponibles sur la machine. En fait, ce n'est probablement pas la meilleure chose à faire même si vous ne vous souciez pas d'IPv6, car il souffre des mêmes risques de sécurité que ::
.
Une adresse IPv4 ou IPv6 explicite (par exemple 127.0.0.1
ou ::1
pour le bouclage). Cela lie le serveur à cette adresse et uniquement à cette adresse.
La chaîne magique ::
. Cela liera MySQL à chaque adresse de la machine, à la fois les adresses de bouclage et les interfaces physiques, en mode IPv4 et IPv6. C'est potentiellement un risque pour la sécurité, ne le faites que si vous avez besoin de MySQL pour accepter les connexions des hôtes distants.
Utilisez une adresse IPv6 mappée IPv4 . Il s'agit d'un mécanisme spécial intégré à IPv6 pour une compatibilité descendante pendant la transition 4 -> 6, et il vous permet de vous lier à une adresse IPv4 spécifique et à son équivalent IPv6. Il est peu probable que cela vous soit utile pour autre chose que l'adresse de "double bouclage" ::ffff:127.0.0.1
. Il s'agit probablement de la meilleure solution pour la plupart des gens, ne se liant qu'au bouclage mais autorisant les connexions IPv4 et IPv6.
Dois-je modifier le fichier hosts?
Non . Ne modifiez pas le fichier hosts. Le résolveur DNS sait quoi faire localhost
, le redéfinir n'aura au mieux aucun effet, et au pire confondra l'enfer du résolveur.
Et alors --skip-name-resolve
?
Cela peut également résoudre le problème, pour une raison connexe mais légèrement différente.
Sans cette option de configuration, MySQL tentera de résoudre toutes les adresses IP de connexion client en un nom d'hôte via une PTR
requête DNS. Si votre serveur MySQL est déjà activé pour utiliser IPv6 mais que les connexions prennent encore du temps, cela peut être dû au fait que l'enregistrement DNS inversé ( PTR
) n'est pas correctement configuré.
La désactivation de la résolution de noms résoudra ce problème, mais elle a d'autres ramifications, notamment que toutes les autorisations d'accès configurées pour utiliser un nom DNS dans la Host
condition échouent désormais.
Si vous comptez le faire, vous devrez configurer toutes vos autorisations pour utiliser des adresses IP au lieu de noms.