Questo è preso quasi alla lettera dalla mia risposta qui , ma so che aggrottiamo le sopracciglia solo su link, quindi immagino che facciate anche voi ragazzi :-)
Se stai riscontrando questo problema e stai utilizzando una versione di Windows precedente a Windows 7, questa probabilmente non è la risposta al tuo problema.
Perché sta succedendo?
La causa di questo problema è IPv4 vs IPv6.
Quando si utilizza un nome host anziché un indirizzo IP, il client MySQL esegue innanzitutto una AAAA
ricerca host (IPv6) per il nome e prova prima questo indirizzo se risolve correttamente il nome in un indirizzo IPv6. Se uno dei due passaggi ha esito negativo (risoluzione dei nomi o connessione), verrà eseguito il fallback a IPv4, eseguendo una A
ricerca e provando invece questo host.
Ciò significa in pratica che se la localhost
ricerca IPv6 ha esito positivo ma MySQL non è associato al loopback IPv6, sarà necessario attendere un ciclo di timeout della connessione prima che si verifichi il fallback IPv4 e la connessione abbia esito positivo.
Non si trattava di un problema precedente a Windows 7, poiché la localhost
risoluzione veniva eseguita tramite il file hosts ed era preconfigurata solo con 127.0.0.1
- non veniva fornita con la sua controparte IPv6 ::1
.
Da Windows 7, tuttavia, la localhost
risoluzione è integrata nel resolver DNS, per i motivi descritti qui . Ciò significa che la ricerca IPv6 ora avrà esito positivo, ma MySQL non è associato a quell'indirizzo IPv6, quindi la connessione fallirà e vedrai il ritardo delineato in questa domanda.
Bello. Dimmi solo come risolverlo già!
Hai alcune opzioni. Guardando in giro per Internet, la "soluzione" generale sembra essere quella di utilizzare esplicitamente l'indirizzo IP anziché il nome, ma ci sono un paio di ragioni per non farlo, sia legate alla portabilità, sia probabilmente non importanti:
Se sposti lo script su un altro computer che supporta solo IPv6, lo script non funzionerà più.
Se sposti lo script in un ambiente di hosting basato su * nix, la stringa magica localhost
significherebbe che il client MySQL preferirebbe utilizzare un socket Unix se configurato, questo è più efficiente della connettività basata su loopback IP
Sembrano piuttosto importanti però?
Non lo sono. Dovresti progettare la tua applicazione in modo che questo genere di cose sia definito in un file di configurazione. Se sposti lo script in un altro ambiente, è probabile che anche altre cose debbano essere configurate.
In sintesi, l'uso dell'indirizzo IP non è la soluzione migliore , ma è molto probabilmente accettabile.
Quindi qual è la soluzione migliore?
Il modo migliore sarebbe cambiare l'indirizzo di bind utilizzato dal server MySQL. Tuttavia, questo non è così semplice come si potrebbe desiderare. A differenza di Apache, Nginx e quasi ogni altra applicazione di servizio di rete sana mai realizzata, MySQL supporta solo un singolo indirizzo di bind, quindi non si tratta solo di aggiungerne un altro. Fortunatamente, i sistemi operativi supportano un po 'di magia qui, quindi possiamo consentire a MySQL di utilizzare contemporaneamente sia IPv4 che IPv6.
Devi eseguire MySQL 5.5.3 o versioni successive e avviare MySQL con l' --bind-address=
argomento della riga di comando. Hai 4 documenti opzionali , a seconda di cosa vuoi fare:
Quello con cui probabilmente hai familiarità e quello che molto probabilmente (effettivamente) stai usando 0.0.0.0
,. Questo si lega a tutti gli indirizzi IPv4 disponibili sulla macchina. Questa in realtà non è probabilmente la cosa migliore da fare anche se non ti interessa IPv6, poiché subisce gli stessi rischi di sicurezza di ::
.
Un indirizzo IPv4 o IPv6 esplicito (ad esempio 127.0.0.1
o ::1
per loopback). Ciò vincola il server a quell'indirizzo e solo a quell'indirizzo.
La corda magica ::
. Ciò vincolerà MySQL a tutti gli indirizzi sulla macchina, sia quelli di loopback che quelli di interfaccia fisica, in modalità IPv4 e IPv6. Questo è potenzialmente un rischio per la sicurezza, fallo solo se hai bisogno di MySQL per accettare connessioni da host remoti.
Utilizzare un indirizzo IPv6 mappato IPv4 . Questo è un meccanismo speciale incorporato in IPv6 per la compatibilità con le versioni precedenti durante la transizione 4 -> 6 e ti consente di associare un indirizzo IPv4 specifico ed è equivalente a IPv6. È molto improbabile che ciò ti sia utile per qualcosa di diverso dall'indirizzo "dual loopback" ::ffff:127.0.0.1
. Questa è probabilmente la soluzione migliore per la maggior parte delle persone, vincolando solo al loopback ma consentendo entrambe le connessioni IPv4 e IPv6.
Devo modificare il file hosts?
NO . Non modificare il file hosts. Il risolutore DNS sa cosa fare localhost
, ridefinirlo nella migliore delle ipotesi non avrà alcun effetto e, nella peggiore delle ipotesi, confondere il risolutore.
Che dire --skip-name-resolve
?
Ciò può anche risolvere il problema, per un motivo correlato ma leggermente diverso.
Senza questa opzione di configurazione, MySQL tenterà di risolvere tutti gli indirizzi IP di connessione client in un nome host tramite una PTR
query DNS. Se il tuo server MySQL è già abilitato all'uso di IPv6 ma le connessioni impiegano ancora molto tempo, è possibile che il record DNS ( PTR
) inverso non sia configurato correttamente.
La disabilitazione della risoluzione dei nomi risolverà questo problema, ma ha altre ramificazioni, in particolare che eventuali autorizzazioni di accesso configurate per utilizzare un nome DNS nella Host
condizione ora falliranno.
Se hai intenzione di farlo, dovrai configurare tutte le tue sovvenzioni per usare indirizzi IP anziché nomi.