Назад | Перейти на главную страницу

Соединение MySQL работает с localhost, но не с 127.0.0.1

У меня довольно стандартная установка MySQL на Debian Wheezy (apt-get install mysql-server mysql-client), что я уже много раз успешно делал.

Когда я пытаюсь подключиться через localhost, все работает. Но подключение через 127.0.0.1 выдает сообщение об ошибке:

$ mysql -h localhost -P 3306 -u xxx -p
-- works

$ mysql -h 127.0.0.1 -P 3306 -u xxx -p
ERROR 2013 (HY000): Lost connection to MySQL server at 'reading initial communication packet', system error: 0

Когда я пытаюсь подключиться из приложения Java, я получаю аналогичные ошибки, хотя использую localhost как имя хоста:

com.mysql.jdbc.exceptions.jdbc4.CommunicationsException: Communications link failure. The last packet sent successfully to the server was 0 milliseconds ago. The driver has not received any packets from the server.
Caused by: java.io.EOFException: Can not read response from server. Expected to read 4 bytes, read 0 bytes before connection was unexpectedly lost.

Я обычно получаю это исключение, когда сервер MySQL закрыл простаивающее соединение или был перезапущен. Однако теперь это происходит при запуске приложения, когда приложение пытается подключиться в первый раз.

Достаточно забавно это сделал работайте всего за несколько часов до этого. К сожалению, я не могу вспомнить, чтобы что-либо менял на сервере. :-(

Честно говоря, этот пост содержит два вопроса: Почему я не могу подключиться через 127.0.0.1? И почему мои приложения не могут подключиться через localhost хотя можно через CLI?

# mysqld -V
mysqld  Ver 5.5.37-0+wheezy1-log for debian-linux-gnu on x86_64 ((Debian))

# mysql -V
mysql  Ver 14.14 Distrib 5.5.37, for debian-linux-gnu (x86_64) using readline 6.2

# grep bind /etc/mysql/my.cnf
bind-address = 127.0.0.1

# grep socket /etc/mysql/my.cnf
socket = /var/run/mysqld/mysqld.sock

# ping localhost
PING localhost (127.0.0.1) 56(84) bytes of data.
64 bytes from localhost (127.0.0.1): icmp_req=1 ttl=64 time=0.022 ms

# grep localhost /etc/hosts
127.0.0.1 localhost
::1     ip6-localhost ip6-loopback

# iptables -L
Chain INPUT (policy ACCEPT)
target     prot opt source               destination
ACCEPT     tcp  --  anywhere             anywhere             tcp

Chain FORWARD (policy ACCEPT)
target     prot opt source               destination

Chain OUTPUT (policy ACCEPT)
target     prot opt source               destination

# netstat -ln | grep 3306
tcp        0      0 127.0.0.1:3306          0.0.0.0:*               LISTEN

tomcat # grep mysql conf/server.xml
driverClassName="com.mysql.jdbc.Driver"
url="jdbc:mysql://localhost:3306/dbname"

РЕДАКТИРОВАТЬ

Я пробовал привязать сервер к 0.0.0.0 и ::, но безрезультатно.

Сервер поддерживает IPv6 и настроен соответственно:

# host localhost
localhost has address 127.0.0.1
localhost has IPv6 address ::1

Та же проблема, что описана выше, возникает, когда я пытаюсь подключиться к ::1.

# ping6 ::1
64 bytes from ::1: icmp_seq=1 ttl=64 time=0.020 ms

# ping6 localhost
64 bytes from ip6-localhost: icmp_seq=1 ttl=64 time=0.018 ms

РЕДАКТИРОВАТЬ 2

Подключение через telnet дает не много информации, но показывает, что соединение сразу закрывается.

# telnet localhost 3306
Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.
Connection closed by foreign host.

Между прочим, файлы журналов MySQL полностью молчат, даже если ведение журнала включено.

Казалось, виноват hosts.deny и hosts.allow которые по умолчанию имеют файловый режим 0x600. MySQL не смог их прочитать, чтобы определить, разрешить ли соединения. Я изменил режимы файлов на 0x644, и теперь все идет гладко. Мне все еще интересно, почему MySQL не регистрирует никаких ошибок ...

Этот вопрос очень похож на MySQL не может подключиться через localhost, только 127.0.0.1 . Как указано здесь, вы, вероятно, настроили MySQL только на прослушивание сетевого сокета, а не сокета файловой системы.

Возможно, у вас включен IPv6, его очень возможный localhost преобразуется в localhost ipv6, который не определен в вашей конфигурации mysql.

Вы можете проверить это, посмотрев, возвращает ли "host localhost" в командной строке :: 1, а также 127.0.0.1. Если это так, вы можете либо удалить отображение :: 1, либо перенастроить MySQL для прослушивания адреса IPv6 :: 1, а также 127.0.0.1

Недавно я сломал рабочую установку, в которой большинство клиентов основаны на Java. Инструменты CLI работали бы, но все клиенты Java остановились как вкопанные. В моем случае виновником была новая настройка, которую я включил «для повышения производительности»:

skip-name-resolve       = on

Когда вы это сделаете, MySQL больше не использует rDNS для разрешения 127.0.0.1 -> localhost и, поскольку все мои GRANTs предназначены для user@localhost, пользователю не разрешено подключаться с хоста 127.0.0.1.

Для этой конкретной проблемы существует два решения:

  1. Отключить skip-name-resolve
  2. Расширьте свой GRANTs включить 127.0.0.1 так же как localhost