Zostało to zaczerpnięte niemal dosłownie z mojej odpowiedzi tutaj , ale wiem, że marszczymy brwi w odpowiedziach tylko na link w SO, więc wyobrażam sobie, że wy też tak robicie :-)
Jeśli masz ten problem i używasz wersji systemu Windows wcześniejszej niż Windows 7, prawdopodobnie nie jest to odpowiedź na Twój problem.
Dlaczego to się dzieje?
Przyczyną tego problemu jest IPv4 vs IPv6.
Gdy używasz nazwy hosta zamiast adresu IP, klient MySQL najpierw uruchamia AAAA
wyszukiwanie hosta (IPv6) dla tej nazwy i najpierw próbuje tego adresu, jeśli pomyślnie rozpoznaje nazwę na adres IPv6. Jeśli jeden z kroków nie powiedzie się (rozpoznawanie nazw lub połączenie), nastąpi powrót do IPv4, uruchamiając A
wyszukiwanie i próbując zamiast tego tego hosta.
W praktyce oznacza to, że jeśli localhost
wyszukiwanie IPv6 zakończy się powodzeniem, ale MySQL nie jest związany z pętlą zwrotną IPv6, musisz poczekać na jeden limit czasu połączenia, zanim nastąpi awaria IPv4 i połączenie się powiedzie.
Nie było to problemem przed Windows 7, ponieważ localhost
rozwiązywanie odbywało się za pomocą pliku hosts i zostało wstępnie skonfigurowane tylko z 127.0.0.1
- nie pochodziło z jego odpowiednikiem IPv6 ::1
.
Ponieważ jednak system Windows 7 localhost
ma wbudowaną funkcję rozpoznawania nazw DNS, z powodów opisanych tutaj . Oznacza to, że wyszukiwanie IPv6 zakończy się teraz sukcesem - ale MySQL nie jest powiązany z tym adresem IPv6, więc połączenie nie powiedzie się i zobaczysz opóźnienie opisane w tym pytaniu.
To miłe. Po prostu powiedz mi, jak to naprawić!
Masz kilka opcji. Rozglądając się po Internecie, wydaje się, że ogólnym „rozwiązaniem” jest jawne używanie adresu IP zamiast nazwy, ale istnieje kilka powodów, aby tego nie robić, oba związane z przenośnością, oba prawdopodobnie nieważne:
Jeśli przeniesiesz skrypt na inną maszynę, która obsługuje tylko IPv6, skrypt nie będzie już działał.
Jeśli przeniesiesz skrypt do środowiska hostingowego opartego na * nix, magiczny ciąg localhost
oznaczałby, że klient MySQL wolałby używać gniazda Unix, jeśli jest skonfigurowane, jest to bardziej wydajne niż połączenie oparte na sprzężeniu zwrotnym IP
Brzmią dość ważne?
Nie są. Powinieneś projektować swoją aplikację, aby tego rodzaju rzeczy były zdefiniowane w pliku konfiguracyjnym. Jeśli przeniesiesz skrypt do innego środowiska, są szanse, że inne rzeczy również będą wymagały konfiguracji.
Podsumowując, użycie adresu IP nie jest najlepszym rozwiązaniem, ale najprawdopodobniej jest akceptowalne.
Więc jakie jest najlepsze rozwiązanie?
Najlepszym sposobem jest zmiana adresu powiązania używanego przez serwer MySQL. Nie jest to jednak tak proste, jak mogłoby się to podobać. W przeciwieństwie do Apache, Nginx i prawie każdej innej rozsądnej aplikacji usługi sieciowej, jaką kiedykolwiek stworzono, MySQL obsługuje tylko jeden adres wiązania, więc nie chodzi tylko o dodanie kolejnego. Na szczęście systemy operacyjne obsługują tutaj trochę magii, dzięki czemu możemy umożliwić MySQL jednoczesne używanie zarówno IPv4, jak i IPv6.
Musisz uruchomić MySQL 5.5.3 lub nowszy i uruchomić MySQL z --bind-address=
argumentem wiersza poleceń. Masz 4 opcje dokumentów , w zależności od tego, co chcesz zrobić:
Ten, jesteś prawdopodobnie zna, a jeden, że jesteś najprawdopodobniej (efektywnie) za pomocą, 0.0.0.0
. Powiąże to wszystkie dostępne adresy IPv4 na komputerze. To prawdopodobnie nie jest najlepsza rzecz, nawet jeśli nie zależy ci na IPv6, ponieważ wiąże się to z takimi samymi zagrożeniami bezpieczeństwa jak ::
.
Jawny adres IPv4 lub IPv6 (na przykład 127.0.0.1
lub ::1
do sprzężenia zwrotnego). To wiąże serwer z tym adresem i tylko z tym adresem.
Magiczny sznurek ::
. Spowoduje to powiązanie MySQL z każdym adresem na maszynie, zarówno sprzężeniem zwrotnym, jak i fizycznym adresem interfejsu, w trybie IPv4 i IPv6. Jest to potencjalnie zagrożenie bezpieczeństwa, rób to tylko wtedy, gdy potrzebujesz MySQL do akceptowania połączeń ze zdalnych hostów.
Użyj adresu IPv6 odwzorowanego na IPv4 . Jest to specjalny mechanizm wbudowany w IPv6 w celu zapewnienia wstecznej kompatybilności podczas przejścia 4 -> 6 i pozwala na powiązanie z określonym adresem IPv4 i jego odpowiednikiem IPv6. Jest to mało prawdopodobne, aby było to przydatne dla czegokolwiek innego niż adres „podwójnej pętli zwrotnej” ::ffff:127.0.0.1
. Jest to najprawdopodobniej najlepsze rozwiązanie dla większości ludzi, wiążące się tylko z pętlą zwrotną, ale umożliwiające połączenia zarówno IPv4, jak i IPv6.
Czy muszę zmodyfikować plik hosts?
NO . Nie modyfikuj pliku hosts. Program rozpoznawania nazw DNS wie, co z tym zrobić localhost
, przedefiniowanie go w najlepszym wypadku nie przyniesie żadnego efektu, aw najgorszym przypadku zmyli piekło z usług tłumacza.
Co --skip-name-resolve
?
Może to również rozwiązać problem z pokrewnego, ale nieco innego powodu.
Bez tej opcji konfiguracji MySQL będzie próbował rozwiązać wszystkie adresy IP połączeń klienta z nazwą hosta za pomocą PTR
zapytania DNS. Jeśli Twój serwer MySQL jest już włączony do korzystania z IPv6, ale połączenia wciąż trwają długo, może to być spowodowane tym, że odwrotny PTR
rekord DNS ( ) nie jest poprawnie skonfigurowany.
Wyłączenie rozpoznawania nazw rozwiąże ten problem, ale wiąże się z innymi konsekwencjami, w szczególności że wszelkie uprawnienia dostępu skonfigurowane do używania nazwy DNS w tym Host
stanie nie będą działać.
Jeśli masz zamiar to zrobić, musisz skonfigurować wszystkie granty, aby używały adresów IP zamiast nazw.