ローカルで TCP 経由で MySQL に接続できない - 接続タイムアウト - Ubuntu 9.04

ローカルで TCP 経由で MySQL に接続できない - 接続タイムアウト - Ubuntu 9.04

私は Ubuntu を実行しており、最終的には JDBC を使用して Tomcat を MySQL データベースに接続しようとしています。

以前はうまくいったしかし、再起動後、インスタンスは接続に失敗します。

  • Tomcat 6とMySQL 5.0.75は同じマシン上にある
  • 接続文字列: jdbc:mysql:///localhost:3306
  • コマンドラインでMySQLに接続するには、次のmysqlコマンドを使用します。
  • my.cnf ファイルはかなり標準的です (リクエストに応じて利用可能) バインド アドレスは 127.0.0.1 です
  • netstat が MySQL が listen していると表示しているにもかかわらず、MySQL ポートに Telnet できません
  • 80 -> 8080 に転送する IpTables ルールが 1 つありますが、ファイアウォールは認識していません。

私はこの分野にかなり不慣れで、他に何をテストすればよいかわかりません。etc/interfaces を調べる必要があるかどうか、また何を調べるべきかがわかりません。以前は機能していたのに再起動後に機能しなくなったのは奇妙です。何かを変更したに違いありません.... :)。

タイムアウトはサーバーが応答していないことを示していると認識しており、リクエストが実際に通過していないことが原因であると考えています。MySQL は apt-get 経由でインストールし、Tomcat は手動でインストールしました。

MySqldプロセス

root@88:/var/log/mysql#  ps -ef | grep mysqld
root     21753     1  0 May27 ?        00:00:00 /bin/sh /usr/bin/mysqld_safe
mysql    21792 21753  0 May27 ?        00:00:00 /usr/sbin/mysqld --basedir=/usr --datadir=/var/lib/mysql --user=mysql --pid-file=/var/run/mysqld/mysqld.pid --skip-external-locking --port=3306 --socket=/var/run/mysqld/mysqld.sock
root     21793 21753  0 May27 ?        00:00:00 logger -p daemon.err -t mysqld_safe -i -t mysqld
root     21888 13676  0 11:23 pts/1    00:00:00 grep mysqld

ネットスタット

root@88:/var/log/mysql# netstat -lnp | grep mysql
tcp        0      0 0.0.0.0:3306            0.0.0.0:*               LISTEN      21792/mysqld
unix  2      [ ACC ]     STREAM     LISTENING     1926205077 21792/mysqld        /var/run/mysqld/mysqld.sock

おもちゃのつながり教室

root@88:~# cat TestConnect/TestConnection.java

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;

public class TestConnection {

  public static void main(String args[]) throws Exception {
    Connection con = null;

    try {
      Class.forName("com.mysql.jdbc.Driver").newInstance();
      System.out.println("Got driver");
      con = DriverManager.getConnection(
                "jdbc:mysql:///localhost:3306",
                "uname", "pass");
      System.out.println("Got connection");

      if(!con.isClosed())
        System.out.println("Successfully connected to " +
          "MySQL server using TCP/IP...");

    } finally {
        if(con != null)
          con.close();
    }
  }
}

おもちゃ接続クラスの出力

注: これは Tomcat から受け取るエラーと同じです。

root@88:~/TestConnect# java -cp mysql-connector-java-5.1.12-bin.jar:. TestConnection
Got driver
                Exception in thread "main" com.mysql.jdbc.exceptions.jdbc4.CommunicationsException: Communications link failure

The last packet sent successfully to the server was 1 milliseconds ago. The driver has not received any packets from the server.
        at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
        at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:39)
        at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:27)
        at java.lang.reflect.Constructor.newInstance(Constructor.java:513)
        at com.mysql.jdbc.Util.handleNewInstance(Util.java:409)
        at com.mysql.jdbc.SQLError.createCommunicationsException(SQLError.java:1122)            
        at TestConnection.main(TestConnection.java:14)
Caused by: 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.
        at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
        at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:39)
        at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:27)
        at java.lang.reflect.Constructor.newInstance(Constructor.java:513)
        at com.mysql.jdbc.Util.handleNewInstance(Util.java:409)
        at com.mysql.jdbc.SQLError.createCommunicationsException(SQLError.java:1122)
        at com.mysql.jdbc.MysqlIO.<init>(MysqlIO.java:344)
        at com.mysql.jdbc.ConnectionImpl.createNewIO(ConnectionImpl.java:2181)
        ... 12 more
Caused by: java.net.ConnectException: Connection timed out
        at java.net.PlainSocketImpl.socketConnect(Native Method)
        ... 13 more

Telnet出力

root@88:~/TestConnect# telnet localhost 3306
Trying 127.0.0.1...
telnet: Unable to connect to remote host: Connection timed out

iptables の

注: NAT 用のルールを設定していましたが、削除しても問題は解決しません。

root@88:~# iptables -nL
Chain INPUT (policy ACCEPT)
target     prot opt source               destination

Chain FORWARD (policy ACCEPT)
target     prot opt source               destination

Chain OUTPUT (policy ACCEPT)
target     prot opt source               destination

root@88:~# iptables -t nat -nL
Chain PREROUTING (policy ACCEPT)
target     prot opt source               destination

Chain POSTROUTING (policy ACCEPT)
target     prot opt source               destination

Chain OUTPUT (policy ACCEPT)
target     prot opt source               destination

iptables の設定に使用するコマンド

iptables -t nat -I PREROUTING --src 0/0 --dst 88.198.31.14 -p tcp --dport 80 -j REDIRECT --to-ports 8080

その後、NAT 用にこの設定を行ったルールを削除したので、このコマンドに副作用がない限りは関係ありません。

更新 - ローカルホストにpingできない

ip a

root@88:~/TestConnect# ip a
1: lo: <LOOPBACK> mtu 16436 qdisc noop state DOWN
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
3: venet0: <BROADCAST,POINTOPOINT,NOARP,UP,LOWER_UP> mtu 1500 qdisc noqueue state UNKNOWN
    link/void
    inet 127.0.0.1/32 scope host venet0
    inet 88.198.31.14/32 scope global venet0:0

ip r

root@88:~/TestConnect# ip r
    192.0.2.1 dev venet0  scope link
    default via 192.0.2.1 dev venet0

IPルール

root@88:~/TestConnect# ip rule
0:      from all lookup local
32766:  from all lookup main
32767:  from all lookup default

ping -c 1 ローカルホスト

root@88:~/TestConnect# ping -c 1 localhost
PING localhost.localdomain (127.0.0.1) 56(84) bytes of data.

--- localhost.localdomain ping statistics ---
1 packets transmitted, 0 received, 100% packet loss, time 0ms

/etc/hosts を cat する

root@88:~/TestConnect# cat /etc/hosts
127.0.0.1 localhost.localdomain localhost
# Auto-generated hostname. Please do not remove this comment.
88.198.31.14 88.198.31.14  88 88

ifconfig

root@88:/var/log/mysql# ifconfig
venet0    Link encap:UNSPEC  HWaddr 00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00
          inet addr:127.0.0.1  P-t-P:127.0.0.1  Bcast:0.0.0.0  Mask:255.255.255.255
          UP BROADCAST POINTOPOINT RUNNING NOARP  MTU:1500  Metric:1
          RX packets:144432 errors:0 dropped:0 overruns:0 frame:0
          TX packets:153825 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:0
          RX bytes:37896766 (37.8 MB)  TX bytes:28722595 (28.7 MB)

venet0:0  Link encap:UNSPEC  HWaddr 00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00
          inet addr:88.198.31.14  P-t-P:88.198.31.14  Bcast:0.0.0.0  Mask:255.255.255.255
          UP BROADCAST POINTOPOINT RUNNING NOARP  MTU:1500  Metric:1

pQd のおかげで、エラーの原因を絞り込むことができたと思います。これが何を意味するのか、そしてなぜ localhost が ping できないのかについて調べる必要があります。

答え1

tcp/3306 トラフィックを阻止する iptables ルールがないことは確かですか? 一時的な回避策としてこれを試してください:

iptables -I INPUT -p tcp --dport 3306 -i lo -j ACCEPT
iptables -A OUTPUT -p tcp --sport 3306 -o lo -j ACCEPT

あるいは、NAT ルールが期待するよりも少し厳しくなっているのでしょうか?

わかりました。ループバックがダウンしているだけでなく、127.0.0.1 がバインドされていません。/etc/network/interfaces に以下を追加します。

auto lo
iface lo inet loopback

そして、一体なぜそれを vnet0 にバインドしたのでしょうか? そこから削除してください。

簡単なワンタイムコマンドライン修正:

ip a d 127.0.0.1/32 dev venet0
ip a a 127.0.0.1/32 dev lo
ip link set dev lo up

関連情報