我在自己的mac上安装了docker,并在docker中运行了mysql5.6容器。启动容器的方式大致如下:
$ 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服务正常启动之后,我想通过客户端连接此服务。于是,我顺理成章地在终端敲下了这样的命令
mysql -u root -p
Enter password:
ERROR 2002 (HY000): Can't connect to local MySQL server through socket '/tmp/mysql.sock' (2)
非常意外,居然报错了。我记得以前都是这样敲的呀?怎么换成跑在docker里就行不通了?不科学!
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
。
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
访问,需要经过网卡,也可能受到防火墙限制。