Isso foi tirado quase literalmente da minha resposta aqui , mas eu sei que nos desaprovamos em respostas somente para links no SO, então imagino que vocês também :-)
Se você está tendo esse problema e está usando uma versão do Windows anterior ao Windows 7, provavelmente esta não é a resposta para o seu problema.
Por que isso está acontecendo?
A causa desse problema é IPv4 vs IPv6.
Quando você usa um nome de host em vez de um endereço IP, o cliente MySQL executa primeiro uma AAAA
pesquisa de host (IPv6) para o nome e tenta esse endereço primeiro se resolver com êxito o nome para um endereço IPv6. Se uma das etapas falhar (resolução de nome ou conexão), ela retornará ao IPv4, executando uma A
pesquisa e tentando este host.
O que isso significa na prática é que, se a localhost
pesquisa do IPv6 for bem-sucedida, mas o MySQL não estiver vinculado ao loopback do IPv6, será necessário aguardar um ciclo de tempo limite da conexão antes que ocorra o fallback do IPv4 e a conexão tenha êxito.
Isso não foi um problema anterior ao Windows 7, porque a localhost
resolução foi feita através do arquivo hosts e veio pré-configurada apenas 127.0.0.1
- ela não veio com sua contraparte do IPv6 ::1
.
Desde o Windows 7, no entanto, a localhost
resolução está incorporada no resolvedor de DNS, pelos motivos descritos aqui . Isso significa que a pesquisa do IPv6 agora terá êxito - mas o MySQL não está vinculado a esse endereço IPv6, portanto a conexão falhará e você verá o atraso descrito nesta pergunta.
Isso é bom. Apenas me diga como consertar já!
Você tem poucas opções. Olhando pela Internet, a "solução" geral parece ser o uso explícito do endereço IP, e não o nome, mas existem algumas razões para não fazer isso, tanto relacionadas à portabilidade, quanto sem dúvida importantes:
Se você mover seu script para outra máquina que suporte apenas IPv6, seu script não funcionará mais.
Se você mover seu script para um ambiente de hospedagem baseado em * nix, a string mágica localhost
significaria que o cliente MySQL preferiria usar um soquete Unix se um estiver configurado, isso é mais eficiente que a conectividade baseada em loopback IP
Eles parecem muito importantes?
Eles não são. Você deve projetar seu aplicativo para que esse tipo de coisa seja definido em um arquivo de configuração. Se você mover seu script para outro ambiente, é provável que outras coisas também precisem ser configuradas.
Em resumo, usar o endereço IP não é a melhor solução, mas é provavelmente uma solução aceitável.
Então, qual é a melhor solução?
A melhor maneira seria alterar o endereço de ligação que o servidor MySQL usa. No entanto, isso não é tão simples quanto se pode gostar. Ao contrário do Apache, Nginx e quase todos os outros aplicativos de serviços de rede sãos já criados, o MySQL suporta apenas um único endereço de ligação, portanto, não é apenas o caso de adicionar outro. Felizmente, os sistemas operacionais suportam um pouco de mágica aqui, para que possamos permitir que o MySQL use IPv4 e IPv6 simultaneamente.
Você precisa estar executando o MySQL 5.5.3 ou posterior e iniciar o MySQL com o --bind-address=
argumento de linha de comando. Você tem quatro opções de documentos , dependendo do que você deseja fazer:
Aquele com quem você provavelmente está familiarizado e o que você provavelmente (efetivamente) está usando 0.0.0.0
,. Isso se liga a todos os endereços IPv4 disponíveis na máquina. Na verdade, isso provavelmente não é a melhor coisa a se fazer, mesmo que você não se importe com o IPv6, pois ele sofre os mesmos riscos de segurança que ::
.
Um endereço IPv4 ou IPv6 explícito (por exemplo 127.0.0.1
ou ::1
para loopback). Isso liga o servidor a esse endereço e somente a esse endereço.
A corda mágica ::
. Isso ligará o MySQL a todos os endereços da máquina, tanto os endereços de loopback quanto os da interface física, no modo IPv4 e IPv6. Isso é potencialmente um risco de segurança, apenas faça isso se você precisar do MySQL para aceitar conexões de hosts remotos.
Use um endereço IPv6 mapeado para IPv4 . Esse é um mecanismo especial incorporado ao IPv6 para compatibilidade com versões anteriores durante a transição 4 -> 6, e permite a ligação a um endereço IPv4 específico e seu equivalente ao IPv6. É pouco provável que seja útil a você para algo que não seja o endereço de "loopback duplo" ::ffff:127.0.0.1
. Essa é provavelmente a melhor solução para a maioria das pessoas, vinculando apenas o loopback, mas permitindo conexões IPv4 e IPv6.
Preciso modificar o arquivo hosts?
NÃO . Não modifique o arquivo hosts. O resolvedor de DNS sabe com o que fazer localhost
, redefini-lo na melhor das hipóteses não terá efeito e, na pior das hipóteses, confundir o inferno com o resolvedor.
Que tal --skip-name-resolve
?
Isso também pode resolver o problema, por um motivo relacionado, mas um pouco diferente.
Sem essa opção de configuração, o MySQL tentará resolver todos os endereços IP da conexão do cliente com um nome de host por meio de uma PTR
consulta DNS. Se o seu servidor MySQL já estiver habilitado para usar o IPv6, mas as conexões ainda estiverem demorando muito, pode ser porque o registro DNS ( PTR
) reverso não está configurado corretamente.
Desabilitar a resolução de nomes corrigirá esse problema, mas ele tem outras ramificações, principalmente porque agora todas as permissões de acesso configuradas para usar um nome DNS na Host
condição falharão.
Se você fizer isso, precisará configurar todas as suas concessões para usar endereços IP em vez de nomes.