max_connect_errors
一开始接触这个参数的时候,感受他和max_connections的含义差很少,字面意思简单明了,这个参数的含义是最大链接错误数,翻翻mysql的文档中的解释是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,大意是:若是mysql服务器连续接收到了来自于同一个主机的请求,且这些连续的请求所有都没有成功的创建链接就被断开了,当这些连续的请求的累计值大于 max_connect_errors的设定值时,mysql服务器就会阻止这台主机后续的全部请求。”without a successful connection”那太好办了,故意输错密码不就好了,而且网上搜索了下该参数的说明,大量的文章充斥着” 防止暴力破解密码”的内容,因而兴高采烈的去作了测试。如下测试基于自建的mysql(非rds for mysql),因为rds for mysql没法直接设置set global,设置时须要在"rds控制台-参数这里"里进行设置:https://help.aliyun.com/document_detail/26179.html?spm=5176.11065259.1996646101.searchclickresult.44156de7pLffcVhtml
max_connect_errors
1,建立帐号:mysql
3,故意输错密码3次,第四次使用正确密码登陆进行验证:shell
4,结论是第四次依然能够登陆,即密码不对(认证失败)不属于” ”without a successful connection””的范畴,网上的” 防止暴力破解密码”也不成立了。express
max_connect_errors
再继续看文档,发现还有如下说明:服务器
You can unblock blocked hosts by flushing the host cache. To do so, issue a FLUSH HOSTS
statement or execute a mysqladmin flush-hosts command.网络
大意是:socket
当你遇到主机被阻止的时候,你能够清空host cache来解决,具体的清空方法是执行flush hosts或者在mysql服务器的shell里执行 mysqladmin flush-hosts操做tcp
既然清空host cache能够解决主机被阻止访问的问题,那应该与host cache有些关系,看看host cache的介绍可能会有些眉目,关于host cache,文档解释以下:oop
The MySQL server maintains a host cache in memory that contains information about clients: IP address, host name, and error information. The server uses this cache for nonlocal TCP connections. It does not use the cache for TCP connections established using a loopback interface address (127.0.0.1
or ::1
), or for connections established using a Unix socket file, named pipe, or shared memory.
大意是:
Mysql服务器会在内存里管理一个host cache,host cache里保存了一些客户端的ip地址,主机名,以及这个客户端在与server创建链接时遇到的一些错误信息,host cache对不是本地的TCP链接才有效,因此host cache对127.0.0.1
或者::1
是无效的,而且对于
Unix socket file、named pipe以及 shared memory方式创建的链接也是无效的。而且经过了解,host cache的内容能够经过performance_schema.host_cache来查看,经过performance_schema.host_cache表里的几个列的描述信息,对以前的测试不成立的缘由有些了解了,部分相关列以下:
· IP
The IP address of the client that connected to the server, expressed as a string.
链接到mysql server的主机的链接地址
· HOST
The resolved DNS host name for that client IP, or NULL if the name is unknown.
经过dns解析IP地址获取到的该IP地址对应的mysql client的主机名
· SUM_CONNECT_ERRORS
The number of connection errors that are deemed “blocking” (assessed against the max_connect_errors system variable). Only protocol handshake errors are counted, and only for hosts that passed validation (HOST_VALIDATED = YES).
· COUNT_HANDSHAKE_ERRORS
The number of errors detected at the wire protocol level.
经过SUM_CONNECT_ERRORS(链接错误计数)描述,重点是红色部分:只计算协议握手过程的错误(Only protocol handshake errors are counted),也就是说max_connect_errors 可能记录的是协议(不肯定是tcp协议仍是应用协议,经过抓包以及COUNT_HANDSHAKE_ERRORS的” the wire protocol level”说明多是指应用协议)的握手过程当中出现的错误 ,也就是能够说网络很差(没法顺利握手)会致使该问题。
max_connect_errors
经过以前的说明,须要模拟应用协议握手失败的状况,最后考虑使用telnet一些来作测试
1,建立帐号
2,设置max_connect_errors为3:
3,先使用telnet 10.26.254.217 3306链接3次,第四次使用正确的帐号密码尝试登录:
telnet前查看performance_schema.host_cache的记录为空
第三次telnet 10.26.254.217 3306
第四次执行mysql -h10.26.254.217 -utestcon -p123 -P3306
问题复现了,出现了错误提示ERROR 1129 (HY000): Host '10.24.236.231' is blocked because of many connection errors; unblock with 'mysqladmin flush-hosts'
解决ERROR 1129 (HY000)的方法是执行flush host或者 mysqladmin flush-hosts,其目的是为了清空host cache里的信息,那是否是说不使用host cache就能够了?使host cache不生效的方式有以下两种:
1,设置 host_cache_size
为0/ 打开skip-host-cache
须要经过测试看下推测是否生效
host_cache_size
为0/ 打开skip-host-cache
1,设置host_cache_size
为0
2,再次查询performance_schema.host_cache
3,继续以前的测试:先使用telnet 10.26.254.217 3306链接3次,第四次使用正确的帐号密码尝试登录
更改已经生效,max_connect_errors
的做用无效了
skip-name-resolve
1,在cnf配置文件里设置skip-name-resolve
以此打开skip-name-resolve
2,继续以前的测试:先使用telnet 10.26.254.217 3306链接3次,第四次使用正确的帐号密码尝试登录
3,查询performance_schema.host_cache
更改已经生效,max_connect_errors
的做用无效了,RDS for mysql 的skip_name_resolve是on的状态,
因此不多会出现ERROR 1129 (HY000)的错误