Połączenie MySQL działa z localhost, ale nie z 127.0.0.1

9

Mam dość standardową instalację MySQL na Debian Wheezy ( apt-get install mysql-server mysql-client), którą robiłem z powodzeniem wiele razy wcześniej.

Kiedy próbuję się połączyć localhost, wszystko działa. Ale połączenie za pośrednictwem 127.0.0.1wyświetla komunikat o błędzie:

$ 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

Podczas próby połączenia z aplikacji Java pojawiają się podobne błędy, chociaż używam localhostjako nazwy hosta:

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.

Zazwyczaj ten wyjątek występuje, gdy serwer MySQL zamknął bezczynne połączenie lub został zrestartowany. Jednak dzieje się to teraz podczas uruchamiania aplikacji, gdy aplikacja próbuje połączyć się po raz pierwszy.

Zabawne, że działało to zaledwie kilka godzin wcześniej. Niestety nie pamiętam, aby cokolwiek zmienić na serwerze. :-(

Szczerze mówiąc, ten post zawiera dwa pytania: Dlaczego nie mogę się połączyć 127.0.0.1? I dlaczego moje aplikacje nie mogą się połączyć, localhostchociaż mogę za pomocą 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"

EDYTOWAĆ

Próbowałem powiązać serwer 0.0.0.0i ::bezskutecznie.

Serwer obsługuje IPv6 i jest odpowiednio skonfigurowany:

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

Ten sam problem, jak opisano powyżej, występuje, gdy próbuję się połączyć ::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

EDYCJA 2

Łączenie przez telnetnie daje zbyt wielu informacji, ale pokazuje, że połączenie jest natychmiast zamykane.

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

Nawiasem mówiąc, pliki logów MySQL są całkowicie ciche, nawet przy włączonym logowaniu.

Philipp Jardas
źródło
Powodem, dla którego otrzymuję błędy z mojej aplikacji Java, jest to, że sterownik JDBC nie rozpoznaje localhostgniazda, ale używa sieci. Jak można się było naturalnie spodziewać ... Ale pierwotne pytanie pozostaje.
Philipp Jardas

Odpowiedzi:

1

Sprawcą zdawało się być hosts.denyi hosts.allowktóry domyślnie ma tryb pliku 0x600. MySQL nie mógł ich odczytać, aby ustalić, czy zezwalać na połączenia. Zmieniłem tryby plików na 0x644i teraz wszystko działa płynnie. Nadal zastanawiam się, dlaczego MySQL nie rejestrował żadnych błędów ...

Philipp Jardas
źródło
0

To pytanie jest bardzo podobne do tego, że MySQL nie może połączyć się przez „localhost”, tylko 127.0.0.1 . Jak stwierdzono tutaj, prawdopodobnie skonfigurowałeś MySQL tak, aby nasłuchiwał tylko gniazda sieciowego, a nie gniazda systemu plików.

Nebu
źródło
Opublikowana odpowiedź odpowiada na pytanie, które jest dokładnie przeciwne do mojego. Mam aktywne gniazda sieciowe i gniazda plików.
Philipp Jardas
Tak masz rację. Przepraszamy, źle przeczytałem twoje pytanie.
Nebu,
0

Możliwe, że masz włączony IPv6, jego bardzo prawdopodobny lokalny host rozwiązuje się do lokalnego hosta ipv6, który nie jest zdefiniowany w konfiguracji mysql.

Możesz to sprawdzić, sprawdzając, czy „host localhost” w wierszu polecenia zwraca :: 1, a także 127.0.0.1. Jeśli tak, możesz usunąć mapowanie :: 1 lub ponownie skonfigurować MySQL, aby nasłuchiwał na adresie IPv6 :: 1 oraz 127.0.0.1

TBI Infotech
źródło
Rzeczywiście localhost rozwiązuje oba 127.0.0.1i ::1. Próbowałem powiązać MySQL ::1, bez zmian. Próbowałem nawet powiązać MySQL 0.0.0.0i ::bez różnicy.
Philipp Jardas
0

Niedawno zepsułem działającą instalację, w której większość klientów jest oparta na Javie. Narzędzia CLI działałyby, ale wszyscy klienci Java przestali działać. W moim przypadku sprawcą było nowe ustawienie, które umożliwiłem „poprawie wydajności”:

skip-name-resolve       = on

Kiedy to zrobisz, MySQL już używa rDNS do rozwiązania 127.0.0.1->, localhosta ponieważ wszystkie moje GRANTuser@localhost, użytkownik nie może połączyć się z hosta 127.0.0.1.

Istnieją dwa rozwiązania tego konkretnego problemu:

  1. Wyłączyć skip-name-resolve
  2. Rozwiń swoje GRANTs, aby uwzględnić, 127.0.0.1jak równieżlocalhost
Christopher Schultz
źródło