排除性能不足的情况下,连接还是慢,具体表现为
- 登录缓慢
- 读取数据库缓慢,甚至超时
- 返回2003代码,10060代码
- 端口却可以通,网络通畅,数据库返回缓慢
- show processlist 有好多unauthenticated user的用户
- 日志有好多IP Cannot resolve的Warning([Warning] IP address 1.1.1.1 cloud not be resolved: Temporary failure in name resolved.)
解决方案: 在my.conf的mysqld配置节加入 skip-name-resolve 配置项 ,然后重启mysql即可
至于dns反解的作用的一些分析(资料来源于https://blog.csdn.net/u010584271/article/details/80835378 链接中平台是基于windows的,Linux同样适用)
作为MySQL调优的一部分,很多人都推荐开启skip_name_resolve。这个参数是禁止域名解析的(当然,也包括主机名)。很多童鞋会好奇,这背后的原理是什么,什么情况下开启这个参数比较合适。
基于以下原因,MySQL服务端会在内存中维护着一份host信息, 包括三部分:IP,主机名和错误信息。主要用于非本地TCP连接。
-
通过在第一次建立连接时缓存IP和host name的映射关系,同一主机的后续连接将直接查看host cache,而不用再次进行DNS解析。
-
host cache中同样会包含IP登录失败的错误信息。可根据这些信息,对这些IP进行相应的限制。后面将会具体提到。
host cache的信息可通过performance_schema中host_cache表查看。
那么,IP和host name的映射关系是如何建立的呢?
-
当有一个新的客户端连接进来时,MySQL Server会为这个IP在host cache中建立一个新的记录,包括IP,主机名和client lookup validation flag,分别对应host_cache表中的IP,HOST和HOST_VALIDATED这三列。第一次建立连接因为只有IP,没有主机名,所以HOST将设置为NULL,HOST_VALIDATED将设置为FALSE。
-
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'
-
从原理上看,DNS解析一般只针对客户端的第一次连接,客户端数据量比较小的情况下,开销其实不大,完全不必启动skip_name_resolve参数,带来的好处就是,为客户端和多变的IP直接解耦,只需对主机名进行一次授权。
-
在没开启skip_name_resolve情况下,无论是通过# mysql -p123456 走socket连接还是# mysql -p123456 -h127.0.0.1走TCP连接,显示的用户都是root@localhost。如果要显示root@127.0.0.1,必须开启skip_name_resolve参数。
另,可通过\s查看当前连接使用的是socket还是TCP。
禁用后的影响:
- 不能在MySQL的授权表中使用主机名了而只能用ip格式。
- 权限的问题,当用户设置限制只能访问某个数据库,如果这个数据库被删了,再重建这个指定数据库,限制用户还是不能访问这个数据,大概是删除数据库的时间,把该用户的访问权限也级联删除了,详细可以查看mysql.db的记录
如果你有一个很慢的DNS和许多主机,你可以通过用--skip-name-resolve禁用DNS查找或增加HOST_CACHE_SIZE定义(默认值:128)并重新编译mysqld来提高性能。
你可以用--skip-host-cache选项启动服务器来禁用主机名缓存。要想清除主机名缓存,执行FLUSH HOSTS语句或执行mysqladmin flush-hosts命令。
如果你想要完全禁止TCP/IP连接,用--skip-networking选项启动mysqld。
`附:How MySQL uses DNS
When a new thread connects to mysqld, mysqld will spawn a new thread to handle the request. This thread will first check if the hostname is in the hostname cache. If not the thread will call gethostbyaddr_r() and gethostbyname_r() to resolve the hostname.
If the operating system doesn't support the above thread-safe calls, the thread will lock a mutex and call gethostbyaddr() and gethostbyname() instead. Note that in this case no other thread can resolve other hostnames that is not in the hostname cache until the first thread is ready.
You can disable DNS host lookup by starting mysqld with --skip-name-resolve. In this case you can however only use IP names in the MySQL privilege tables.
If you have a very slow DNS and many hosts, you can get more performance by either disabling DNS lookup with --skip-name-resolve or by increasing the HOST_CACHE_SIZE define (default: 128) and recompile mysqld.
You can disable the hostname cache with --skip-host-cache. You can clear the hostname cache with FLUSH HOSTS or mysqladmin flush-hosts.
If you don't want to allow connections over TCP/IP, you can do this by starting mysqld with --skip-networking.`
实际想了下 用localhost可以链接mysql,应该就是与这个有关了,禁用后不知道还能不能用localhost链接数据库,实际最好的解决方案可能就是在hosts中指定个域名了
Comments | NOTHING