MySQL 连接时尽量使用 127.0.0.1 而不是 localhost

2019-11-27 14:37:49 +08:00
 lihongjie0209

原因

Whenever you specify "localhost" or "localhost:port" as server, the MySQL client library will override this and try to connect to a local socket (named pipe on Windows). If you want to use TCP/IP, use "127.0.0.1" instead of "localhost". If the MySQL client library tries to connect to the wrong local socket, you should set the correct path as in your PHP configuration and leave the server field blank.

localhost 使用的 Linux socket,127.0.0.1 使用的是 tcp/ip

为什么我使用 localhost 一直没出问题

因为你的本机中只有一个 mysql 进程, 如果你有一个 node1 运行在 3306, 有一个 node2 运行在 3307

mysql -u root -h localhost -P 3306
mysql -u root -h localhost -P 3307

都会连接到同一个 mysql 进程, 因为 localhost 使用 Linux socket, 所以 -P 字段直接被忽略了, 等价于

mysql -u root -h localhost 
mysql -u root -h localhost 

而 -h 默认是 localhost, 又等价于

mysql -u root 
mysql -u root 

为了避免这种情况(比如你在本地开发只有一个 mysql 进程,线上或者 qa 环境有多个 mysql 进程)最好的方式就是使用 IP

mysql -u root -h 127.0.0.1 -P 3307
15517 次点击
所在节点    MySQL
70 条回复
lihongjie0209
2019-11-27 15:49:23 +08:00
@lululau #20 历史遗留问题, 之前的 IPC 只局限在单机
sagaxu
2019-11-27 15:54:41 +08:00
@lululau unix 套接字性能更高
tomychen
2019-11-27 17:39:09 +08:00
所以一台服务(主机)跑两个实例是不被推荐的做法
因为很多 localhost 不出现的 bug 在实际环境中,可能就出来了
ddzzhen
2019-11-27 17:42:32 +08:00
当年踩了这个坑,搞了很久
salamanderMH
2019-11-27 17:51:48 +08:00
是的,当年也是这个坑,Linux 上 localhost 会用`unix socket`
laminux29
2019-11-27 17:56:47 +08:00
不要在一个 OS 里,跑 1 个以上的数据库实例,这是你的错误,别怪 mysql。你不按照业界共识去做,必然会遇到各种各样的花式 bug。
lihongjie0209
2019-11-27 18:06:01 +08:00
@laminux29 #26 什么叫业界共识? 我测试主从同步还需要建立两个虚拟机?要不两个物理机?

我要测试一个 k8s 集群我需要多少台虚拟机 /物理机?



回到正题:一个软件使用 TCP 通讯, 只要有 IP+端口, 你是地球两端的物理机还是在同一个物理机上的两个进程都应该是表现一致的, 这是网络层带给我们的抽象,我们要合理的利用这个抽象来达到我们的目的: 比如说在一个 OS 中搭建一个 MySQL/Redis 集群用于测试。

MySQL 的这个问题和所谓的‘业界共识’没有任何关系, 这只是一个历史遗留问题导致的反常识的现象, 我记录出来也是为了给遇到同样问题的人提个醒。
lihongjie0209
2019-11-27 18:09:48 +08:00
@laminux29 #26 在一个 OS 中跑两个数据实例我还是能想到一些应用场景的。
1. 对于 Redis 这种单线程的数据库, 只有多进程才能完整利用高性能的服务器。
2. Mysql 也是同样的, 有一台性能极高的物理服务器, 系统负载只有 10%, 那么这时候需要再搭建一个数据库,你是选择再买一个服务器还是在同样的服务器上再跑一个 Mysql ?
zzzmode
2019-11-27 18:13:47 +08:00
好像用 localhost 流量不需要经过网卡性能更高
ganymedenil590
2019-11-27 18:19:27 +08:00
@lihongjie0209 测试无所谓,但是生产环境肯定是拆分两个 vps。按照程序的特点来合理选择配置购买。
不然其中一个把系统打爆,另一个一起遭殃。
superrichman
2019-11-27 19:08:47 +08:00
生产环境上一台服务器跑两个数据库实例也真是不怕死。你把鸡蛋都放一个篮子里了,一摔全得碎。
lihongjie0209
2019-11-27 19:11:15 +08:00
@superrichman #31
这么做的目的绝对不是为了高可用, 只是为了压榨物理服务器的性能而已。

最起码我知道 redis 是这么做的。

其次, 数据库也分重要性, 不重要的几个放一台服务器我觉得没什么问题
junbaor
2019-11-27 19:19:24 +08:00
学习了
opengps
2019-11-27 19:20:47 +08:00
不光是这种高级的问题,我还遇到过 hosts 里没有把 localhost 解析到 127.0.0.1 的情况,新装的系统竟然能遇到这种鬼
lihongjie0209
2019-11-27 19:22:38 +08:00
@opengps #34 所以我以后能用 127.0.0.1 的绝对不用 localhost
ccalywm
2019-11-27 19:25:30 +08:00
学到了
xuanbg
2019-11-27 19:31:36 +08:00
只有一个 node 的就不会受影响。话说,一个主机上多个 mysql node,同时应用也在上面跑的情况还真是罕见
xuanbg
2019-11-27 19:33:13 +08:00
@lihongjie0209 数据不重要的话,也就没必要做主从了吧。
laminux29
2019-11-27 19:58:34 +08:00
@lihongjie0209

1.业界共识,是虽未以文档告知,但无论是软件开发者,还是用户,都会这么去做的约定俗成。

2.测试主从同步当然至少需要建立两个虚拟机,如果有多台物理机必然更好。

3.测试集群,必然需要用更多的虚拟机甚至物理机。其次,如果当硬件条件都不具备时,不应该硬着头皮上集群。

4.这个问题与 IP +端口的定义没任何关系,这只是 mysql 对于业界共识的一种硬编码 bug 而已。如果是按照业界共识去做,就不会踩到这个 bug,仅此而已。

5.Redis 不是纯粹的单线程程序,并且它也并不总是 CPU 密集型问题的解决方案。

6.正规公司,招聘的合格的 DBA 与系统管理员,在配置数据库服务器前,必然会对其负载有准确的预算。如果这种场景下,他们仍然选择让服务器在大部分时间以超低负荷运行,那么他们必然有特殊安排,比如首要目标是稳定,而不是资产利用率。
panzhc
2019-11-27 20:12:26 +08:00
感谢分享,用 docker 也能解决单机多实例的问题

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/623596

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX