我在自己的mac上安装了docker,并在docker中运行了mysql5.6容器。启动容器的方式大致如下:
1
2
3
4
5
|
$ docker run --name mydb -d \
-p 3306:3306 \
-v /Users/voidint/dockerV/mysql/data:/var/lib/mysql \
-e MYSQL_ROOT_PASSWORD=xxxxx \
mysql:5.6
|
mysql服务正常启动之后,我想通过客户端连接此服务。于是,我顺理成章地在终端敲下了这样的命令
1
2
3
|
$ mysql -u root -p
Enter password:
ERROR 2002 (HY000): Can't connect to local MySQL server through socket '/tmp/mysql.sock' (2)
|
非常意外,居然报错了。我记得以前都是这样敲的呀?怎么换成跑在docker里就行不通了?不科学!
1
2
3
|
$ mysql -h localhost -uroot -p
Enter password:
ERROR 2002 (HY000): Can't connect to local MySQL server through socket '/tmp/mysql.sock' (2)
|
加上-h
选项还是不行,气急败坏。气归气,问题还是要解决的,那就查查资料。然后,看到了这篇,在粗粗浏览过之后,发现有人建议用-h 127.0.0.1
。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
|
$ mysql -h 127.0.0.1 -u root -p
Enter password:
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A
Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 3823
Server version: 5.6.35 MySQL Community Server (GPL)
Copyright (c) 2000, 2015, Oracle and/or its affiliates. All rights reserved.
Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
mysql>
|
试过之后,发现效果立竿见影。这简直颠覆了我的既有观念!
- 难道localhost和127.0.0.1不是同一个东西?OMG!
- 那个socket文件/tmp/mysql.sock又是怎么一回事,指定了127.0.0.1怎么就正常了?
在查阅了一些资料之后,终于对于这几个问题有了稍深入的理解:
localhost和127.0.0.1的区别
- localhost和127.0.0.1,前者是域名,后者是IP地址中特殊的一类回还地址。
- 许多时候localhost和127.0.0.1给人感觉是等价的,是由于在多数系统的/etc/hosts文件中,两者存在映射关系。
- 本机上的服务,如果通过localhost访问,可以不经过网卡,并且不受防火墙的限制。如果不经过网卡,那客户端和服务端要如何通信?答案就是socket。比如上面例子中的/tmp/mysql.sock。也因为不需要经过网卡,不需要TCP/IP协议的层层封包和层层解包过程,性能上会更出色一些。
- 本机上的服务,如果通过127.0.0.1访问,需要经过网卡,也可能受到防火墙限制。
参考资料