mysql_connect (localhost / 127.0.0.1) медленный на платформе Windows

Я использую Windows 7, Apache 2, PHP 5, MySQL 5, все на одной машине. Я нашел интересную проблему, у меня есть следующий код:

    $sql = "select * from user1";
    $conn = mysql_connect("localhost", "root", "xxxxxxxx");
    mysql_select_db("test1");
    mysql_query("set names utf8");
    $result = mysql_query($sql, $conn);
    while ($row = mysql_fetch_assoc($result)){
        foreach ($row as $key => $value){
            echo $key." => ".$value." || ";
        }
        echo "<br/>";
    }
    mysql_free_result($result);
    mysql_close($conn);

Время выполнения вышеуказанного кода составляет более 1 секунды.

Когда я использую 127.0.0.1 вместо localhostвремя работы составляет около 10 мс.

Я попытался найти основную причину в Интернете, и вот результат:

Недавно я переместил свою разработку с XP на Windows 7 и обнаружил, что разработка веб-страниц занимала 5 секунд. Конечно, это было неприемлемо, поэтому мне пришлось отследить проблему. В конце концов я выследил нарушающую функцию / метод pdo::construct. Я также обнаружил, что mysql_connect занимал около 1 секунды, чтобы установить соединение. После небольшого поиска в Google я нашел объяснение, что у php были проблемы с IPv6 и что вы могли бы решить проблему, отключив IPv6 или переключившись на ipaddress 127.0.0.1 при установлении соединения.

Интересно, в чем проблема IPv6 на PHP, просто хочу глубже понять. Благодарю.

2 ответа

Решение

PHP пытается открыть соединение с localhost. Поскольку ваш компьютер подключен к вашей сети через IPv6, он сначала пробует версию localhost для IPv6, которая является IP-адресом:: 1

http://en.wikipedia.org/wiki/IPv6_address

::1/128 - Адрес обратной связи является одноадресным адресом локального хоста. Если приложение на хосте отправляет пакеты на этот адрес, стек IPv6 будет зацикливать эти пакеты на том же виртуальном интерфейсе (что соответствует 127.0.0.0/8 в IPv4).

Похоже, ваш сервер MySQL не слушает этот адрес, вместо этого он привязан только к IPv4-адресу, и поэтому, если PHP не может открыть соединение, он откатывается назад и пытается открыть localhost через IPv4 или 127.0.0.1

Лично я предпочитаю использовать либо IP-адреса, либо использовать эфирный файл хостов Windows или эквивалент Mac для определения "поддельных" доменных имен, а затем использовать их при подключении к MySQL, которые разрешают IP-адреса. В любом случае я точно знаю, будет ли использоваться адрес IPv4 или IPv6.

И MySQL, и Apache поддерживают IPv6, но вы должны указать им, чтобы они явно использовали IPv6-адрес. Для MySQL см.: http://dev.mysql.com/doc/refman/5.5/en/ipv6-server-config.html

Конфигурацию Apache смотрите: http://httpd.apache.org/docs/2.2/bind.html

Apache поддерживает несколько IP-адресов, поэтому вы можете использовать оба одновременно - если сетевая карта в машине имеет адреса IPv4 и IPv6. MySQL поддерживает только один адрес.

PHP пытается подключиться к "localhost" в Windows 7/8/10, это:: 1, но MySQL не прослушивает сокеты IPv6, вы можете применить несколько исправлений:

1) В вашем хост-файле (C:/windows/system32/drivers/etc/host) установите localhost равным 127.0.0.1

2) В PHP сервер MySQL меняется с localhost на 127.0.0.1

3) В my.ini добавьте или отредактируйте: bind-address =::

Если адрес::, сервер принимает соединения TCP/IP на всех интерфейсах IPv4 и IPv6 хост-сервера. Используйте этот адрес, чтобы разрешить подключения как IPv4, так и IPv6 на всех интерфейсах сервера.

Предлагаемый вариант, если у вас MySQL >= 5.5.3

Другие вопросы по тегам