天天看点

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'

max_connect_errors参数

头一次见这种报错,网上查看是由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;

max_connect_errors参数

连续两次输入错误的密码:

max_connect_errors参数

最后发现还是能登录:

max_connect_errors参数

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

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表:

max_connect_errors参数

主要关注两个列:

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

max_connect_errors参数

2、telnet一次

max_connect_errors参数
max_connect_errors参数

3、telnet二次

max_connect_errors参数
max_connect_errors参数

4、登录MySQL测试

max_connect_errors参数

问题复现。无法登录。

解决方法:

  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服务。

max_connect_errors参数

2、telnet 1次

max_connect_errors参数
max_connect_errors参数

3、telnet 2次

max_connect_errors参数
max_connect_errors参数

4、登录

max_connect_errors参数

可以登录,这时候,max_connect_errors参数没有生效。