好久都没有更新了,最近在写一个小项目,遇到的问题还是挺多的,就分享一下吧。今天刚学怎么用 Docker Mysql 就踩了一个坑。
起因
“怎么使用 Docker Mysql” 是我今天刚学 Docker x Mysql 搜的第一个问题。Google 出来一堆,我当时看的就是这个 使用docker运行mysql实例。感觉简单得一批啊,运行下面命令好像就OK了。
sudo docker run --name second-mysql -p 3308:3306 -e MYSQL_ROOT_PASSWORD=123456 -d
果然成功(注意,这里我将 container 的 3306 端口影射到主机的 3308 端口,简单来说就是,本机 mysql 通过 3308 端口就可以访问 container 里的 mysql 了)。
然而当我
mysql -P 3308 -u root -p
// 输入密码
竟然访问了我 Mac 上的数据库!讲到道理应该访问我 container 上的数据库啊!!我刚进新手材就暴毙了??(不想看吐槽的可以直接看总结)
这是我 Mac 上的数据库
这是我 container 的数据库,可以看得出我本机上是有一个以前建的叫 "hello" 的数据库。
搜索
然后我就开始了漫长的搜索,关键这个问题不好搜,“docker 访问不了 container 而是访问了 Mac 上的数据库” 这个关键词也太长了吧,而且这么长的关键词肯定搜不出好东西。
果然,牛头不对马嘴。
那就英文搜吧 "mac mysql cant connect to docker mysql",英文搜好多了。所以少用中文搜,多练练英语。
排名第一的小哥现在还没搞得定。见原贴
排名第二的虽然解决不了问题,但是他确定了一件事:访问不成功可能因为用了 local socket 而不是通过 tcp 来访问。见原贴
排名第三的解决了问题,但是并没给出合理解释,见原贴最后的讨论
这里的意思就是除了指定端口,你还得指定 host,而 host=127.0.0.1。也就是说要运行命令
mysql -h 127.0.0.1 -P 3308 -u root -p
结果是成功访问到了 container 的数据库了。
分析
在我的认知中,应该是这样的 localhost=127.0.0.1。所以我又试了
mysql -h localhost -P 3308 -u root -p
但是还是访问了 Mac 上的数据库。为了找到这个答案我就搜了一下 localhost vs 127.0.0.1。然后在这篇帖子中说了这两者的区别。
这里转述一下 :localhost(local)是不经网卡传输!这点很重要,它不受网络防火墙和网卡相关的的限制。127.0.0.1是通过网卡传输,依赖网卡,并受到网络防火墙和网卡相关的限制。
还记得刚刚第二个帖子里说的要通过 tcp 才能正常访问 container 的 mysql 么?所以,这里我猜测一下(极其不负责!如果知道原因的大哥可以在评论里指出!),命令行里指定 localhost 时调用了 local socket 去访问了 container 的 mysql,而指定 host 为 127.0.01 时会通过 tcp 去远程访问数据库。
而我在用 WebStorm 的时候用了他们家的数据库工具,配置如下
可以看到这里指定 localhost 也是可以的,这里我猜测这具工具本质上可能也是通过 tcp 远程访问了数据库,而不是通过 local socket。毕竟这个工具本来就应该用来远程访问数据库的,可能 JetBrains 把 localhost 解析了。
总结
对于 输入 mysql 命令只访问到 Mac 上的 mysql 数据库,而不能访问 docker 的 container 里的 mysql 数据库的解决方法就是要指定端口号的同时,也要指定 host=127.0.0.1,注意指定 host=localhost 或者用默认host 都是不行的,即应输入命令:
mysql -h 127.0.0.1 -P 3308 -u root -p
完