Это почти дословно взято из моего ответа здесь , но я знаю, что мы недовольны ответами только для ссылок на SO, так что я думаю, что вы, ребята, тоже так делаете :-)
Если у вас возникла эта проблема и вы используете версию Windows до Windows 7, это, вероятно, не ответ на вашу проблему.
Почему это происходит?
Причиной этой проблемы является IPv4 против IPv6.
Когда вы используете имя хоста вместо IP-адреса, клиент MySQL сначала запускает AAAA
поиск хоста (IPv6) для имени и сначала пробует этот адрес, если он успешно разрешает имя в адрес IPv6. Если какой-либо шаг завершится неудачно (разрешение имени или соединение), он вернется к IPv4, запустив A
поиск и попробовав этот хост.
На практике это означает, что если localhost
поиск IPv6 успешен, но MySQL не связан с обратной связью IPv6, вам нужно будет подождать один цикл тайм-аута соединения, прежде чем произойдет откат IPv4 и соединение установится успешно.
Это не было проблемой до Windows 7, потому что localhost
разрешение было сделано через файл hosts, и он был предварительно сконфигурирован только с 127.0.0.1
- он не шел с его аналогом IPv6 ::1
.
Однако, поскольку в Windows 7 localhost
разрешение встроено в распознаватель DNS по причинам, изложенным здесь . Это означает, что поиск IPv6 теперь будет успешным, но MySQL не привязан к этому IPv6-адресу, поэтому соединение не будет установлено, и вы увидите задержку, описанную в этом вопросе.
Это мило. Просто скажи мне, как это исправить уже!
У вас есть несколько вариантов. Оглядываясь в Интернете, можно сказать, что общим «решением» является явное использование IP-адреса вместо имени, но есть несколько причин не делать этого, обе связаны с переносимостью, обе, возможно, не важны:
Если вы переместите свой скрипт на другой компьютер, который поддерживает только IPv6, ваш скрипт больше не будет работать.
Если вы переместите свой сценарий в среду размещения * nix, волшебная строка localhost
будет означать, что клиент MySQL предпочтет использовать сокет Unix, если он настроен, это более эффективно, чем возможность подключения на основе петли IP
Они звучат довольно важно, хотя?
Это не так. Вы должны разрабатывать свое приложение так, чтобы такого рода вещи определялись в файле конфигурации. Если вы переместите свой сценарий в другую среду, скорее всего, другие вещи также потребуются в настройке.
Таким образом, использование IP-адреса не является лучшим решением, но, скорее всего, приемлемым.
Так что же является лучшим решением?
Лучшим способом было бы изменить адрес привязки, который использует сервер MySQL. Однако это не так просто, как хотелось бы. В отличие от Apache, Nginx и почти любого другого приложения для работы с сетевыми службами, MySQL поддерживает только один адрес привязки, поэтому это не просто случай добавления другого. К счастью, операционные системы поддерживают магию, поэтому мы можем позволить MySQL одновременно использовать как IPv4, так и IPv6.
Вам необходимо запустить MySQL 5.5.3 или более позднюю версию и запустить MySQL с --bind-address=
аргументом командной строки. У вас есть 4 варианта документации , в зависимости от того, что вы хотите сделать:
Тот, с которым вы, вероятно, знакомы, и тот, который вы наиболее вероятно (эффективно) используете 0.0.0.0
. Это привязывает ко всем доступным IPv4-адресам на машине. На самом деле это, вероятно, не лучшая вещь, даже если вы не заботитесь об IPv6, поскольку он несет те же риски безопасности, что и ::
.
Явный адрес IPv4 или IPv6 (например, 127.0.0.1
или ::1
для обратной связи). Это связывает сервер с этим адресом и только с этим адресом.
Волшебная строка ::
. Это свяжет MySQL с каждым адресом на машине, как с обратной связью, так и с адресами физического интерфейса, в режимах IPv4 и IPv6. Это потенциально угроза безопасности, делайте это только в том случае, если вам нужен MySQL для приема соединений от удаленных хостов.
Используйте IPv4-сопоставленный IPv6-адрес . Это специальный механизм, встроенный в IPv6 для обратной совместимости при переходе 4 -> 6, и он позволяет вам привязываться к определенному адресу IPv4 и его эквиваленту IPv6. Это вряд ли пригодится вам для чего-либо, кроме адреса «двойной петли» ::ffff:127.0.0.1
. Скорее всего, это лучшее решение для большинства людей, только связывание с обратной связью, но допускающее как IPv4, так и IPv6-соединения.
Нужно ли изменять файл hosts?
NO . Не изменяйте файл hosts. DNS-распознаватель знает, что делать localhost
, переопределение его в лучшем случае не даст никакого эффекта, а в худшем - запутает его.
Как насчет --skip-name-resolve
?
Это также может решить проблему по связанной, но немного другой причине.
Без этой опции конфигурации MySQL будет пытаться разрешить все IP-адреса клиентских подключений к имени хоста через PTR
запрос DNS. Если ваш сервер MySQL уже включен для использования IPv6, но соединения все еще занимают много времени, это может быть связано с PTR
неправильной настройкой обратной записи DNS ( ).
Отключение разрешения имен решит эту проблему, но оно имеет и другие последствия, в частности, что любые разрешения доступа, настроенные для использования DNS-имени в Host
условии, теперь не будут выполнены.
Если вы собираетесь это сделать, вам нужно будет настроить все свои права на использование IP-адресов вместо имен.