共计 2408 个字符,预计需要花费 7 分钟才能阅读完成。
这篇文章主要介绍 mysql 中远程连接 mysql 很慢,本地连接 mysql 很快怎么处理,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!
症状:远程连接 mysql 很慢,但是 本地连接 mysql 很快,ping 和 route 网络通信都是正常的。
解决:mysql 的配置文件中增加如下配置参数:
[mysqld]
skip-name-resolve
原理:
作为 MySQL 调优的一部分,很多人都推荐开启 skip_name_resolve。这个参数是禁止域名解析的(当然,也包括主机名)。很多童鞋会好奇,这背后的原理是什么,什么情况下开启这个参数比较合适。
基于以下原因,MySQL 服务端会在内存中维护着一份 host 信息,包括三部分:IP,主机名和错误信息。主要用于非本地 TCP 连接。
1. 通过在第一次建立连接时缓存 IP 和 host name 的映射关系,同一主机的后续连接将直接查看 host cache,而不用再次进行 DNS 解析。
2. host cache 中同样会包含 IP 登录失败的错误信息。可根据这些信息,对这些 IP 进行相应的限制。后面将会具体提到。
host cache 的信息可通过 performance_schema 中 host_cache 表查看。
那么,IP 和 host name 的映射关系是如何建立的呢?
1. 当有一个新的客户端连接进来时,MySQL Server 会为这个 IP 在 host cache 中建立一个新的记录,包括 IP,主机名和 client lookup validation flag,分别对应 host_cache 表中的 IP,HOST 和 HOST_VALIDATED 这三列。第一次建立连接因为只有 IP,没有主机名,所以 HOST 将设置为 NULL,HOST_VALIDATED 将设置为 FALSE。
2. MySQL Server 检测 HOST_VALIDATED 的值,如果为 FALSE,它会试图进行 DNS 解析,如果解析成功,它将更新 HOST 的值为主机名,并将 HOST_VALIDATED 值设为 TRUE。如果没有解析成功,判断失败的原因是永久的还是临时的,如果是永久的,则 HOST 的值依旧为 NULL,且将 HOST_VALIDATED 的值设置为 TRUE,后续连接不再进行解析,如果该原因是临时的,则 HOST_VALIDATED 依旧为 FALSE,后续连接会再次进行 DNS 解析。
另,解析成功的标志并不只是通过 IP,获取到主机名即可,这只是其中一步,还有一步是通过解析后的主机名来反向解析为 IP,判断该 IP 是否与原 IP 相同,如果相同,才判断为解析成功,才能更新 host cache 中的信息。
基于上面的总结,下面谈谈 host cache 的优缺点:
缺点:当有一个新的客户端连接进来时,MySQL Server 都要建立一个新的记录,如果 DNS 解析很慢,无疑会影响性能。如果被允许访问的主机很多,也会影响性能,这个与 host_cache_size 有关,这个参数是 5.6.5 引入的。5.6.8 之前默认是 128,5.6.8 之后默认是 -1, 基于 max_connections 的值动态调整。所以如果被允许访问的主机很多,基于 LRU 算法,先前建立的连接可能会被挤掉,这些主机重新进来时,会再次进行 DNS 查询。
优点:通常情况下,主机名是不变的,而 IP 是多变的。如果一个客户端的 IP 经常变化,那基于 IP 的授权将是一个繁琐的过程。因为你很难确定 IP 什么时候变化。而基于主机名,只需一次授权。而且,基于 host cache 中的失败信息,可在一定程度上阻止外界的暴力破解攻击。
关于阻止外界的暴力破解攻击,涉及到 max_connect_errors 参数,默认为 100,官方的解释如下:
If more than this many successive connection requests from a host are interrupted without a successful connection, the server blocks that host from further connections.
如果某个客户端的连接达到了 max_connect_errors 的限制,将被禁止访问,并提示以下错误:
Host host_name is blocked because of many connection errors.
Unblock with mysqladmin flush-hosts
下面来模拟一下
首先,设置 max_connect_errors 的值
即便后来使用了正确的账号和密码登录,依旧会被阻止。
再来看看 host_cache 表中的信息,sum_connect_errors 为 2 了。
如果该参数设置为 OFF,则上述方式就会报错,通过报错信息可以看出,它直接将 127.0.0.1 转化为 localhost 了。
[root@localhost ~]# mysql -uroot -h227.0.0.1 -p123456 -P3306
Warning: Using a password on the command line interface can be insecure.
ERROR 1045 (28000): Access denied for user root @ localhost (using password: YES)
注意:t1 @ % 中包含 t1 @ 127.0.0.1,如果开启 skip_name_resolve 参数,则 t1 @ % 中定义的密码可用于 t1 @ 127.0.0.1 的登录,如果没有开启该参数,则 t1 @ 127.0.0.1 会转化为 t1 @ localhost 登录,此时 t1 @ % 定义的密码并不适用。
以上是“mysql 中远程连接 mysql 很慢,本地连接 mysql 很快怎么处理”这篇文章的所有内容,感谢各位的阅读!希望分享的内容对大家有帮助,更多相关知识,欢迎关注丸趣 TV 行业资讯频道!