max_connect_errors参数-阿里云开发者社区

开发者社区> 数据库> 正文

max_connect_errors参数

简介: 一次ERROR 1129 (HY000): Host 'xxx.xxx.xxx.xxx' is blocked because of many connection errors; unblock with 'mysqladmin flush-hosts'报错,重新认识max_connect_errors参数。

问题原因:

抽取数据job,通过proxy连接mysql,数据库侧报错:ERROR 1129 (HY000): Host 'xxx.xxx.xxx.xxx' is blocked because of many connection errors; unblock with 'mysqladmin flush-hosts'
image
头一次见这种报错,网上查看是由max_connect_errors参数控制。顾名思义,就是限制连接报错的次数。
官方文档对这个参数的解释:

After max_connect_errors successive connection requests from a host are interrupted without a successful connection, the server blocks that host from further connections. If a connection from a host is established successfully within fewer than max_connect_errors attempts after a previous connection was interrupted, the error count for the host is cleared to zero. However, once a host is blocked, flushing the host cache is the only way to unblock it. To flush the host cache, execute a FLUSH HOSTS statement, a TRUNCATE TABLE statement that truncates the Performance Schema host_cache table, or a mysqladmin flush-hosts command.

大概意思就是:超过max_connect_errors个连接MySQL的请求没有成功被中断后,server会阻止再次连接。如果在max_connect_errors内连接成功,那错误次数的计次器被清0。
看解释很简单,那我把这个参数设置为2,密码错误2次后不就可以了?测试一下。
登录数据库,设置max_connect_errors=2;

image
连续两次输入错误的密码:
image
最后发现还是能登录:
image
这里测试就明白了,确实跟想的不一样。官网说的请求中断跟密码错误的连接是两码事。有些文章说的这个参数“防止暴力破解密码”也就是错误的。官网这个报错也有说明:

B.6.2.5 Host 'host_name' is blocked
If the following error occurs, it means that mysqld has received many connection requests from the given host that were interrupted in the middle:
Host 'host_name' is blocked because of many connection errors.
Unblock with 'mysqladmin flush-hosts'

参数是如何实现的?

那这个参数到底是怎么实现的,官网上提到了host_cache,先看下host_cache是做什么的。

The MySQL server maintains a host cache in memory that contains information about clients: IP address, host name, and error information. The Performance Schema host_cache table exposes the contents of the host cache so that it can be examined using SELECT statements.

MySQL在内存中维护了一个host cache来缓存客户端的连接信息,如:IP、hostname、报错信息等。在MySQL的Performance Schema库的 host_cache表里记录了这些信息。这样同一用户登录的时候,MySQL不用每次都去解析DNS,而是直接用缓存的信息。
官方文档介绍的很详细,这里挑重点说明这个缓存跟max_connect_errors参数的联系:

The cache contains information about errors that occur during the connection process. Some errors are considered “blocking.” If too many of these occur successively from a given host without a successful connection, the server blocks further connections from that host. The max_connect_errors system variable determines the permitted number of successive errors before blocking occurs (see Section B.6.2.5, “Host 'host_name' is blocked”).

这里就说明了,host cache会记录连接MySQL时的错误信息,如果错误连接次数过多,那么MySQL就会阻止这个host再次连接,怎么阻止?就是通过max_connect_errors参数来定义错误连接次数的上限。

重新测试:

明白了max_connect_errors参数的作用
在重新测试之前,先来了解下记录了block连接的host_cache表:
image
主要关注两个列:
SUM_CONNECT_ERRORS:被block的连接的数量。
关于这个列的说明:
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).
这里就标明了,只计算协议握手错误,以及通过验证的主机。通过这个列的值判断是否超过max_connect_errors 的值。
COUNT_AUTHENTICATION_ERRORS:身份认证失败的错误数

下面开始测试MySQL连接中断的情况,通过telnet的方式:
1、设置max_connect_errors =2
image
2、telnet一次
image
image
3、telnet二次
image
image
4、登录MySQL测试
image
问题复现。无法登录。

解决方法:

  1. MySQL已经提示,可以执行flush-hosts来清空host_cache。

    1、mysqladmin flush-hosts
    2、mysql> flush hosts;
    3、truncate table performance_schema.host_cache;
  2. 可以考虑调整max_connect_errors的大小
  3. 设置skip-name-resolve=on(RDS默认是打开的),测试设置参数后,max_connect_errors参数会失效。

注意:这些都不是根除的办法,首先应该排除网络连接的问题。为什么会出现连接断开

测试skip-name-resolve参数

1、开启skip-name-resolve=on
不能动态修改,在my.cnf文件中添加skip_name_resolve=on,然后重启MySQL服务。

image
2、telnet 1次
image
image
3、telnet 2次
image
image
4、登录
image
可以登录,这时候,max_connect_errors参数没有生效。

版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。

分享:
数据库
使用钉钉扫一扫加入圈子
+ 订阅

分享数据库前沿,解构实战干货,推动数据库技术变革

其他文章