iis服务器助手广告广告
返回顶部
首页 > 资讯 > 数据库 >MySQL参数max_connect_errors分析释疑
  • 291
分享到

MySQL参数max_connect_errors分析释疑

MySQL参数max_connect_errors分析释疑 2016-03-27 10:03:34 291人浏览 猪猪侠
摘要

        最近一Mysql服务器,由于一些特殊因素遇到“ERROR 1129 (00000): Host "xxx" is blocked because of many connection errors. Unblock with

MySQL参数max_connect_errors分析释疑

        最近一Mysql服务器,由于一些特殊因素遇到“ERROR 1129 (00000): Host "xxx" is blocked because of many connection errors. Unblock with "mysqladmin flush-hosts",在问题解决后,在详细了解参数max_connect_errors的过程中,有些不同网络资料的矛盾描述确实让我有点迷惑和混淆(关于这个错误,本质原因是因为同一个IP在短时间内产生太多中断的数据库连接(超过max_connect_errors的最大值)而导致的),下面介绍我的探索问题、分析问题、释疑的一个过程。

         首先,我在网上搜索了一些资料,不少资料信誓旦旦的介绍,密码输入错误的尝试次数超过max_connect_errors变量,Mysql就会阻塞这个客户端登录,然后我找到了官方资料关于max_connect_errors的介绍,如下所示,MySQL 5.6/5.7的介绍一致

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. 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. If a connection 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. The default is 100.

        如上所示,翻译出来的话,大致如下:如果MySQL服务器连续接收到了来自于同一个主机的请求,而且这些连续的请求全部都没有成功的建立连接就被中断了,当这些连续的请求的累计值大于max_connect_errors的设定值时,MySQL服务器就会阻止这台主机后续的所有请求。相信一开始你看到这些资料,也会被“many successive connection requests from a host are interrupted without a successful connection给弄懵,其实这个就是因为由于网络异常而中止数据库连接。网上搜索到这么一个资料: 

        There seems to be confusion around that variable. It does not really block hosts for repeated invalid passWords but for aborted connections due to network errors.

        好吧,那么我们自己动手实验验证一下,就能弄明白到底那个是正确的。在MySQL数据库里面创建一个test账号,然后我们将max_connect_errors变量设置为3.

mysql> show variables like "%max_connect_errors%";
+--------------------+-------+
| Variable_name      | Value |
+--------------------+-------+
| max_connect_errors | 100   |
+--------------------+-------+
1 row in set (0.00 sec)
 
mysql> set global max_connect_errors=3;
Query OK, 0 rows affected (0.00 sec)
 
mysql> show variables like "%max_connect_error%";
+--------------------+-------+
| Variable_name      | Value |
+--------------------+-------+
| max_connect_errors | 3     |
+--------------------+-------+
1 row in set (0.00 sec)

        然后我们在另外一台测试机器,以错误的密码去连接这个MySQL数据库,如下所示,即使前面输入了三次错误密码,第四次输入是也没有碰到上面错误。那么可以排除这个变量与密码错误输入有关系。

[root@mytestlnx02 tmp]# mysql -h10.20.57.24 -utest -p

Enter password:

ERROR 1045 (28000): Access denied for user "test"@"mytestlnx02" (using password: YES)

[root@mytestlnx02 tmp]# mysql -h10.20.57.24 -utest -p

Enter password:

ERROR 1045 (28000): Access denied for user "test"@"mytestlnx02" (using password: YES)

[root@mytestlnx02 tmp]# mysql -h10.20.57.24 -utest -p

Enter password:

ERROR 1045 (28000): Access denied for user "test"@"mytestlnx02" (using password: YES)

[root@mytestlnx02 tmp]# mysql -h10.20.57.24 -utest -p

Enter password:

ERROR 1045 (28000): Access denied for user "test"@"mytestlnx02" (using password: YES)

[root@mytestlnx02 tmp]#

其实,关于某个IP输入了错误密码,MySQL会在perfORMance_schema数据库下的host_cache表中记录。它会累计记录在COUNT_AUTHENTICATION_ERRORS字段,如下所示:

mysql> use performance_schema;
Database changed
mysql> select * from host_cacheG;
*************************** 1. row ***************************
                                        IP: 192.168.27.180
                                      HOST: gettestlnx02
                            HOST_VALIDATED: YES
                        SUM_CONNECT_ERRORS: 0
                 COUNT_HOST_BLOCKED_ERRORS: 0
           COUNT_NAMEINFO_TRANSIENT_ERRORS: 0
           COUNT_NAMEINFO_PERMANENT_ERRORS: 0
                       COUNT_FORMAT_ERRORS: 0
           COUNT_ADDRINFO_TRANSIENT_ERRORS: 0
           COUNT_ADDRINFO_PERMANENT_ERRORS: 0
                       COUNT_FCRDNS_ERRORS: 0
                     COUNT_HOST_ACL_ERRORS: 0
               COUNT_NO_AUTH_PLUGIN_ERRORS: 0
                  COUNT_AUTH_PLUGIN_ERRORS: 0
                    COUNT_HANDSHAKE_ERRORS: 0
                   COUNT_PROXY_USER_ERRORS: 0
               COUNT_PROXY_USER_ACL_ERRORS: 0
               COUNT_AUTHENTICATION_ERRORS: 4
                          COUNT_SSL_ERRORS: 0
         COUNT_MAX_USER_CONNECTIONS_ERRORS: 0
COUNT_MAX_USER_CONNECTIONS_PER_HOUR_ERRORS: 0
             COUNT_DEFAULT_DATABASE_ERRORS: 0
                 COUNT_INIT_CONNECT_ERRORS: 0
                        COUNT_LOCAL_ERRORS: 0
                      COUNT_UNKNOWN_ERRORS: 0
                                FIRST_SEEN: 2018-01-31 16:28:19
                                 LAST_SEEN: 2018-01-31 16:28:26
                          FIRST_ERROR_SEEN: 2018-01-31 16:28:19
                           LAST_ERROR_SEEN: 2018-01-31 16:28:26
1 row in set (0.00 sec)
 
ERROR: 
No query specified

官方资料介绍,host_cache的字段是统计被视为阻塞的连接错误的数量(根据max_connect_errors系统变量进行评估)。 只计算协议握手错误,并且仅用于通过验证的主机(HOST_VALIDATED = YES)。

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).

MySQL客户端与数据库建立连接需要发起三次握手协议,正常情况下,这个时间非常短,但是一旦网络异常,网络超时等因素出现,就会导致这个握手协议无法完成,MySQL有个参数connect_timeout,它是MySQL服务端进程mysqld等待连接建立完成的时间,单位为秒。如果超过connect_timeout时间范围内,仍然无法完成协议握手话,MySQL客户端会收到异常,异常消息类似于: Lost connection to MySQL Server at "XXX", system error: errno,该变量默认是10秒: 

mysql> show variables like "connect_timeout";
+-----------------+-------+
| Variable_name   | Value |
+-----------------+-------+
| connect_timeout | 10    |
+-----------------+-------+
1 row in set (0.00 sec)
 
mysql> 

那么我们就构造一个网络超时引起的数据库连接被中断案例吧,我们用linux下的netemtc命令模拟构造出复杂环境下的网络传输延时案例,如下设置后,此时从测试服务器去访问MySQL服务器,都会出现延时11秒:

[root@gettestlnx02 ~]# ping 10.20.57.24

PING 10.20.57.24 (10.20.57.24) 56(84) bytes of data.

64 bytes from 10.20.57.24: icmp_seq=1 ttl=62 time=0.251 ms

64 bytes from 10.20.57.24: icmp_seq=2 ttl=62 time=0.330 ms

64 bytes from 10.20.57.24: icmp_seq=3 ttl=62 time=0.362 ms

64 bytes from 10.20.57.24: icmp_seq=4 ttl=62 time=0.316 ms

64 bytes from 10.20.57.24: icmp_seq=5 ttl=62 time=0.281 ms

64 bytes from 10.20.57.24: icmp_seq=6 ttl=62 time=0.377 ms

^C

--- 10.20.57.24 ping statistics ---

6 packets transmitted, 6 received, 0% packet loss, time 5716ms

rtt min/avg/max/mdev = 0.251/0.319/0.377/0.047 ms

[root@gettestlnx02 ~]# tc qdisc add dev eth0 root netem delay 11000ms

[root@gettestlnx02 ~]# ping 10.20.57.24

PING 10.20.57.24 (10.20.57.24) 56(84) bytes of data.

64 bytes from 10.20.57.24: icmp_seq=1 ttl=62 time=11000 ms

64 bytes from 10.20.57.24: icmp_seq=2 ttl=62 time=11000 ms

64 bytes from 10.20.57.24: icmp_seq=3 ttl=62 time=11000 ms

64 bytes from 10.20.57.24: icmp_seq=4 ttl=62 time=11000 ms

64 bytes from 10.20.57.24: icmp_seq=5 ttl=62 time=11000 ms

64 bytes from 10.20.57.24: icmp_seq=6 ttl=62 time=11000 ms

64 bytes from 10.20.57.24: icmp_seq=7 ttl=62 time=11000 ms

我们在测试服务器gettestlnx02连接MySQL数据库,如下所示(注意,如果你是在通过ssh连接这台服务器的话,此时在gettestlnx02上操作会相当慢。当然你也可以在MySQL服务器模拟网络延时,或者你将connect_timeout和网络延时都设小一点)

[root@gettestlnx02 ~]# mysql -h10.20.57.24 -utest -p

Enter password:

ERROR 2013 (HY000): Lost connection to MySQL server at "reading authorization packet", system error: 0

[root@gettestlnx02 ~]#

如上所示,由于网络延时超过10秒,导致连接MySQL失败,此时,你在MySQL服务器上查询host_cache表时,那么你就会看到SUM_CONNECT_ERRORS变成1了,COUNT_HANDSHAKE_ERRORS也变成了1.

那么我们反复这样折腾三次,那么你会看到SUM_CONNECT_ERRORS变成3了,COUNT_HANDSHAKE_ERRORS也变成了3.

mysql> select * from host_cacheG;
*************************** 1. row ***************************
                                        IP: 192.168.27.180
                                      HOST: gettestlnx02
                            HOST_VALIDATED: YES
                        SUM_CONNECT_ERRORS: 3
                 COUNT_HOST_BLOCKED_ERRORS: 1
           COUNT_NAMEINFO_TRANSIENT_ERRORS: 0
           COUNT_NAMEINFO_PERMANENT_ERRORS: 0
                       COUNT_FORMAT_ERRORS: 0
           COUNT_ADDRINFO_TRANSIENT_ERRORS: 0
           COUNT_ADDRINFO_PERMANENT_ERRORS: 0
                       COUNT_FCRDNS_ERRORS: 0
                     COUNT_HOST_ACL_ERRORS: 0
               COUNT_NO_AUTH_PLUGIN_ERRORS: 0
                  COUNT_AUTH_PLUGIN_ERRORS: 0
                    COUNT_HANDSHAKE_ERRORS: 3
                   COUNT_PROXY_USER_ERRORS: 0
               COUNT_PROXY_USER_ACL_ERRORS: 0
               COUNT_AUTHENTICATION_ERRORS: 4
                          COUNT_SSL_ERRORS: 0
         COUNT_MAX_USER_CONNECTIONS_ERRORS: 0
COUNT_MAX_USER_CONNECTIONS_PER_HOUR_ERRORS: 0
             COUNT_DEFAULT_DATABASE_ERRORS: 0
                 COUNT_INIT_CONNECT_ERRORS: 0
                        COUNT_LOCAL_ERRORS: 0
                      COUNT_UNKNOWN_ERRORS: 0
                                FIRST_SEEN: 2018-01-31 16:28:19
                                 LAST_SEEN: 2018-01-31 17:02:10
                          FIRST_ERROR_SEEN: 2018-01-31 16:28:19
                           LAST_ERROR_SEEN: 2018-01-31 17:02:10
1 row in set (0.00 sec)
 
ERROR: 
No query specified

然后我们用netemtc 命令在测试服务器上取消网络延迟模拟,然后去测试连接MySQL数据库,如下测试所示:

[root@gettestlnx02 ~]# tc qdisc del dev eth0 root netem delay 11000ms

[root@gettestlnx02 ~]# mysql -h10.20.57.24 -utest -p

Enter password:

ERROR 1129 (HY000): Host "192.168.27.180" is blocked because of many connection errors; unblock with "mysqladmin flush-hosts"

[root@gettestlnx02 ~]#

此时就能构造出ERROR 1129 (HY000): Host "192.168.27.180" is blocked because of many connection errors; unblock with "mysqladmin flush-hosts"错误了。

解决方案

 解决ERROR 1129 (00000): Host "xxx" is blocked because of many connection errors. Unblock with "mysqladmin flush-hosts"这个错误的方法比较多,不过有些方案都是临时方案。临时方案是指标不治本。关键还是需要解决网络错误(这个往往需要求助网络管理人员或系统管理员)

 解决方法:

  1、将变量max_connection_errors的值设置为一个更大的值

mysql> show variables like "max_connect_errors";
+--------------------+-------+
| Variable_name      | Value |
+--------------------+-------+
| max_connect_errors | 3     |
+--------------------+-------+
1 row in set (0.01 sec)
 
mysql> set global max_connect_errors=150;
Query OK, 0 rows affected (0.00 sec)
 
mysql> 

这个临时方案只是延迟触发IP被禁止访问的条件而已,而且在复杂情况或高并发的情况下,需要设置一个很大的值,否则很容易就会再次被触发。另外,变量只对当前环境生效,如果重启就会失效,如果需要永久有效,可以在my.cnf配置文件里面配置。

2:使用flush hosts

mysql> flush hosts;

Query OK, 0 rows affected (0.00 sec)

 

mysql> select * from performance_schema.host_cache;

Empty set (0.00 sec)

 

mysql>

当然你也可以mysqladmin flush-hosts 命令清理一下hosts cache信息

[root@DB-Server ~]# mysqladmin  --port=3306 -uroot -p flush-host

Enter password:

那么host cache是什么呢? 官方介绍如下:

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服务器在内存中维护一个包含客户端信息的缓存IP地址,主机名和错误信息等。 服务器会将非本地TCP连接信息缓存起来。它不会缓存使用环回接口地址(127.0.0.1或者:: 1)建立的TCP连接,或者使用Unix套接字文件,命名管道或共享内存建立的连接。host cache信息可以通过performance_schema数据库下的host_cache表查询。

3:将变量host_cache_size设置为0

其实我想说这是一个最不靠谱的解决方法,只是让MySQL服务器不记录host cache信息而已。完全可以忽略这个方法。

mysql> show variables like "%host_cache_size%";
+-----------------+-------+
| Variable_name   | Value |
+-----------------+-------+
| host_cache_size | 279   |
+-----------------+-------+
1 row in set (0.00 sec)
 
mysql> set global host_cache_size=0;
Query OK, 0 rows affected (0.00 sec)
 
mysql> select * from performance_schema.host_cache;
Empty set (0.00 sec)
 
mysql> 

知识点延伸

    关于参数max_connect_errors,不要误解其功能,这个不能作为防止穷举密码攻击的手段。如果您担心SYN泛滥攻击,max_connect_errors可能会在特定情况下帮助您。 MySQL 5.6中的PERFORMANCE_SCHEMA改进提供了有关潜在强力攻击的有意义的信息,但是只有在涉及主机缓存的情况下。关于这个可以参考博文Understanding max_connect_errors

参考资料:

Http://mysqlblog.fivefarmers.com/2013/08/08/understanding-max_connect_errors/

https://dev.mysql.com/doc/refman/5.6/en/host-cache.html

https://dev.mysql.com/doc/refman/5.7/en/server-system-variables.html#sysvar_max_connect_errors

https://dev.mysql.com/doc/refman/5.7/en/blocked-host.html

 

 

作者: 潇湘隐者 出处: http://www.cnblogs.com/kerrycode/
如果你真心觉得文章写得不错,而且对你有所帮助,那就不妨小小打赏一下吧,如果囊中羞涩,不妨帮忙“推荐"一下,您的“推荐”和”打赏“将是我最大的写作动力!
本文版权归作者所有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接.
您可能感兴趣的文档:

--结束END--

本文标题: MySQL参数max_connect_errors分析释疑

本文链接: https://www.lsjlt.com/news/5622.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • Mysql my.cnf部分参数分析
    本篇内容介绍了“Mysql my.cnf部分参数分析”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!Msyq...
    99+
    2024-04-02
  • mysql中innodb_force_recovery参数分析
    这篇文章主要讲解了“mysql中innodb_force_recovery参数分析”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“mysql中innodb_f...
    99+
    2024-04-02
  • MySQL中Innodb Handler_read_*参数分析
    这篇文章主要介绍“MySQL中Innodb Handler_read_*参数分析”,在日常操作中,相信很多人在MySQL中Innodb Handler_read_*参数分析问题上存在疑惑,小编查阅了各式资料...
    99+
    2024-04-02
  • mysql参数的示例分析
    这篇文章给大家分享的是有关mysql参数的示例分析的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。慢查询是否开启select @@log_slow_queries; 慢查...
    99+
    2024-04-02
  • mysql中innodb_flush_log_at_trx_commit参数的示例分析
    这篇文章主要介绍mysql中innodb_flush_log_at_trx_commit参数的示例分析,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!一、参数解释0:log buffe...
    99+
    2024-04-02
  • MySQL中slave_exec_mode参数的示例分析
    这篇文章主要介绍MySQL中slave_exec_mode参数的示例分析,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!无意当中看到参数slave_exec_mode,从手册里的说明看...
    99+
    2024-04-02
  • MySQL性能参数的示例分析
    这篇文章主要介绍MySQL性能参数的示例分析,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完! max_connect_errors是一个MySQL中与安全有关的计数器值,它负责阻止过...
    99+
    2024-04-02
  • MYSQL中my.cnf参数的示例分析
    这篇文章主要介绍了MYSQL中my.cnf参数的示例分析,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。mysql常用配置文件参数介绍和使用方...
    99+
    2024-04-02
  • 如何进行mysql的innodb_flush_log_at_trx_commit参数分析
    这期内容当中小编将会给大家带来有关如何进行mysql的innodb_flush_log_at_trx_commit参数分析,文章内容丰富且以专业的角度为大家分析和叙述,阅读完这篇文章希望大家可以有所收获。 ...
    99+
    2024-04-02
  • 分析Oracle COMPATIBLE参数
    这篇文章主要介绍“分析Oracle COMPATIBLE参数”,在日常操作中,相信很多人在分析Oracle COMPATIBLE参数问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解...
    99+
    2024-04-02
  • 参数SQL_SLAVE_SKIP_COUNTER的分析
    本篇内容介绍了“参数SQL_SLAVE_SKIP_COUNTER的分析”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够...
    99+
    2024-04-02
  • MySQL并发参数调整的示例分析
    这篇文章主要介绍了MySQL并发参数调整的示例分析,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。Mysql并发参数调整从实现上来说,MySQ...
    99+
    2024-04-02
  • mysql存储中in参数的示例分析
    这篇文章主要介绍mysql存储中in参数的示例分析,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!1.in输入参数概念:表示调用者向过程传入值(传入值可以是字面量或变量)2.使用示例:mysql> de...
    99+
    2023-06-14
  • 怎么分析MySQL性能优化的参数
    怎么分析MySQL性能优化的参数,很多新手对此不是很清楚,为了帮助大家解决这个难题,下面小编将为大家详细讲解,有这方面需求的人可以来学习下,希望你能有所收获。MySQL的优化我分为两个部分,一是服务器物理硬...
    99+
    2024-04-02
  • 数据库mysql存储中入参出参的示例分析
    这篇文章主要介绍数据库mysql存储中入参出参的示例分析,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!入参出参语法: in|out|inout 参数名 数据类型 , ...in 定义出参; out 定义入参; ino...
    99+
    2023-06-14
  • Mysql中并发参数调整的示例分析
    这篇文章将为大家详细讲解有关Mysql中并发参数调整的示例分析,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。查询缓存优化不建议使用,一般是在应用服务做缓存层,毕竟数据并发能力是有限的概述当开始Mysql的...
    99+
    2023-06-21
  • ADO.NET参数举例分析
    本篇内容主要讲解“ADO.NET参数举例分析”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“ADO.NET参数举例分析”吧!我们假设数据可的结构如下图(设置的数据库为Oracle10g):crea...
    99+
    2023-06-17
  • 解析MySQL relay log参数
    这篇文章主要讲解了“解析MySQL relay log参数”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“解析MySQL relay log参数”吧!root...
    99+
    2024-04-02
  • Mysql的Procedure参数如何为NULL问题分析
    本篇文章给大家分享的是有关Mysql的Procedure参数如何为NULL问题分析,小编觉得挺实用的,因此分享给大家学习,希望大家阅读完这篇文章后可以有所收获,话不多说,跟着小编一起来看看吧。 最近写过程...
    99+
    2024-04-02
  • MySQL中query_cache_type参数与使用的示例分析
    这篇文章主要为大家展示了“MySQL中query_cache_type参数与使用的示例分析”,内容简而易懂,条理清晰,希望能够帮助大家解决疑惑,下面让小编带领大家一起研究并学习一下“MySQL中query_cache_type参数与使用的示...
    99+
    2023-06-20
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作