それマグで!

知識はカップより、マグでゆっくり頂きます。 takuya_1stのブログ

習慣に早くから配慮した者は、 おそらく人生の実りも大きい。

mysql locahost の接続では、unix socket かTCPかを明示しないとsock エラーで混乱した

ローカルホストのmysql に接続するときに、次のようにすることが多かった。

mysql -h localhost

正直、これでつながってるから、TCPだと思ってた。

でも、繋がらないので驚いた。エラーをよく見るとmysql.sockって書いてある。 あれれTCP/IP接続じゃなーい?

ERROR 2002 (HY000): Can't connect to local MySQL server through socket '/tmp/mysql.sock' (2)

衝撃の事実。いままでTCPだと思ってたものは unix socketでした。

今日ね、mysql をポート別にdocker で3つ起動てlocalhost側にdocker から公開したんですよ。 つながらないんです。

アレレと思って調べてたら。mysqllocalhost には明示しない限りUNIX ドメインソケットでつなぐんですって。

tcpでつながってると思いこんでたやつ

takuya@:~$ mysql -v -h localhost  
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
MariaDB [(none)]>

しかし、実際はTCPではなかった。

なんかうまくつながらない時があると思ってたけど

ERROR 2003 (HY000): Can't connect to MySQL server on 'localhost' (111 "Connection refused")
ERROR 2002 (HY000): Can't connect to local MySQL server through socket '/tmp/mysql.sock' (2)

あれれれれ、つながらない。

ポートを確認してみる。

つながらないからポートを確認してみると閉じてる。

takuya@:~$ sudo nmap 127.0.0.1 -p  3306

Starting Nmap 7.40 ( https://nmap.org ) at 2019-03-11 11:07 JST
Nmap scan report for localhost (127.0.0.1)
Host is up (0.000060s latency).
PORT     STATE  SERVICE
3306/tcp closed mysql

Nmap done: 1 IP address (1 host up) scanned in 0.34 seconds

ややこしいので整理する。

これはUNIX SOCK ファイル経由

takuya@:~$ mysql -v -h localhost
[mariadb] Password:

この接続はlocalhost にあるデフォルトのパス位置にある、sock ファイル

接続を調べてみた

## これはTCP
takuya@:~$ mysql -v -h localhost --protocol=TCP
## これはTCPじゃなさそう
takuya@:~$ mysql -v -h localhost -P 3306

これは、ポートを明示しているのでTCPと思いきや、UNIXだった(tcpdump で何も見えない。TCP接続に失敗後にフォールバック??)

localhost 宛のパケットを tcpdump -i lo  で見てたけど、パケットを送ってない。まさかのミステリー。

同一ホスト内でIPしてた場合。

これらは全部TCP

takuya@192.168.11.100:~$ mysql -v -h 192.168.11.100
takuya@192.168.11.100:~$ mysql -v -h 192.168.11.100 -P 3306 
takuya@192.168.11.100:~$ mysql -v -h 192.168.11.100 --port 3306 
takuya@192.168.11.100:~$ mysql -v -h 192.168.11.100 --port 3306 --protocol=TCP

tcpdump -i lo  で見てたけど、パケットが出てきたので、TCPだと思われる。

注意点

この実験をする前に、ユーザの接続権限を確認しておくこと。

mysql> select Host,User from mysql.user;
+-----------+------------------+
| Host      | User             |
+-----------+------------------+
| localhost | mysql.infoschema |
| localhost | mysql.session    |
| localhost | mysql.sys        |
| localhost | root             |
+-----------+------------------+
4 rows in set (0.00 sec)

root@localhost のように、localhost 限定だと、そもそもつながらない。

CREATE USEr 'takuya' identified by 'your pass'
RENAME USER 'takuya'@'localhost' TO 'takuya'@'%';
GRANT ALL PRIVILEGES ON * . * TO 'takuya'@'%';

結論

localhost への mysqlTCP接続(ポートを変えるなど)のとき --protocol=TCP をつける。のが今の所無難っぽい

そして、これはドキュメントを読んで、さらに調査が必要。