从源码解析ERROR 1129 (HY000):Host is blocked because of many connection errors

本文涉及的产品
云数据库 RDS MySQL,集群系列 2核4GB
推荐场景:
搭建个人博客
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
.cn 域名,1个 12个月
简介: 原创水平有限,有错请指出 源码版本5.7.14 今天群里一个朋友出现如下错误: ERROR 1129 (HY000): Host '10.0.0.8' is blocked because of many connection errors; unblock w...
原创水平有限,有错请指出

源码版本5.7.14

今天群里一个朋友出现如下错误:
ERROR 1129 (HY000): Host '10.0.0.8' is blocked because of many connection errors; unblock with 'mysqladmin flush-hosts'
为了找到这个问题原因,首先在源码中找到错误码

点击(此处)折叠或打开

  1. { "ER_HOST_IS_BLOCKED", 1129, "Host \'%-.64s\' is blocked because of many connection errors; unblock with \'mysqladmin flush-hosts\'" }
然后找到抛错地点如下:
位于
sql_connect.cc下的check_connection()函数的

点击(此处)折叠或打开

  1. if (!(specialflag & SPECIAL_NO_RESOLVE))
  2.     {
  3.       int rc;
  4.       char *host;
  5.       LEX_CSTRING main_sctx_host;

  6.       rc= ip_to_hostname(&net->vio->remote,
  7.                          main_sctx_ip.str,
  8.                          &host, &connect_errors); //接受ip_to_hostname的返回值到rc
  9.       ......
  10.       if (rc == RC_BLOCKED_HOST)//判断rc是否为RC_BLOCKED_HOST 1
  11.       {
  12.         /* HOST_CACHE stats updated by ip_to_hostname(). */
  13.         my_error(ER_HOST_IS_BLOCKED, MYF(0),
  14.                  thd->m_main_security_ctx.host_or_ip().str);
  15.         return 1;
  16.       }
  17.     }
这里如果如果rc == RC_BLOCKED_HOST RC_BLOCKED_HOST是一个宏定义为1
#define RC_BLOCKED_HOST 1
为真则抛错,接下来我们需要看rc是函数ip_to_hostname的返回值
位于hostname.cc 的ip_to_hostname函数中

点击(此处)折叠或打开

  1. if (!(specialflag & SPECIAL_NO_HOST_CACHE))
  2.   {
  3.     mysql_mutex_lock(&hostname_cache->lock);//这里注意一下整个在cache中查找的过程是有MUTEX的
  4.     Host_entry *entry= hostname_cache_search(ip_key);//在cache中查找
  5.    
  6.     if (entry)
  7.     {
  8.       entry->m_last_seen= now;
  9.       *connect_errors= entry->m_errors.m_connect;
  10.       if (entry->m_errors.m_connect >= max_connect_errors) //max_connect_errors就是参数我们设置的参数
  11.       {
  12.         entry->m_errors.m_host_blocked++;
  13.         entry->set_error_timestamps(now);
  14.         mysql_mutex_unlock(&hostname_cache->lock);//这里解锁
  15.         DBUG_RETURN(RC_BLOCKED_HOST);
  16.       }
到这里我们找到了和这个报错相关的一些事实:
1、max_connect_errors和这个报错有关
2、SPECIAL_NO_RESOLVE和这个报错有关
3、SPECIAL_NO_HOST_CACHE和这个报错有关

max_connect_errors参数不用再解释,如果!(specialflag & SPECIAL_NO_RESOLVE)返回为假则不会调用
ip_to_hostname做IP域名反解析,如果!(specialflag & SPECIAL_NO_HOST_CACHE)返回为假则不会调用if
以后报错的内容。换句话说这里的位与后然后取反关系到了这个报错的是否触发,那么我们就用必要看看
specialflag和SPECIAL_NO_RESOLVE以及SPECIAL_NO_HOST_CACHE的关系了。
下面是源码参数
MYSQLD.CC

点击(此处)折叠或打开

  1. case (int) OPT_SKIP_HOST_CACHE:
  2.     opt_specialflag|= SPECIAL_NO_HOST_CACHE;
  3.     break;
  4.   case (int) OPT_SKIP_RESOLVE:
  5.     opt_skip_name_resolve= 1;
  6.     opt_specialflag|=SPECIAL_NO_RESOLVE;
  7.     break;
其实这里是受到OPT_SKIP_HOST_CACHE、OPT_SKIP_RESOLVE的控制就是我们的参数
skip-host-cache
skip-name-resolve
那么我们起码能够通过skip-host-cache和skip-name-resolve来解决问题,但是这也带来一个问题
建立用户的时候将不能使用域名,如果有UNIX网络编程基础的朋友应该知道客户端通过socket连接
服务端得到的是IP地址和客户端的端口如果一旦关闭IP->DNS的反解析,user@domain这种用户将是
不能连接的,只能是user@ip,这点异常重要。本来是可以连接的:

 create user testuuu@'test' identified by '123';
 /etc/hosts设置为:
 192.168.190.60 test
 
root@test1 ~]# mysql -utestuuu -p123 -h192.168.190.93 -P13001
Warning: Using a password on the command line interface can be insecure.
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 17
Server version: 5.7.14-7-debug-log Source distribution

Copyright (c) 2000, 2014, Oracle and/or its affiliates. All rights reserved.

Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

mysql> exit

但是设置skip-host-cache、skip-name-resolve后
[root@test1 ~]# mysql -utestuuu -p123 -h192.168.190.93 -P13001
Warning: Using a password on the command line interface can be insecure.
ERROR 1045 (28000): Access denied for user 'testuuu'@'192.168.190.60' (using password: YES)
明显这里没有通过192.168.190.60去做反解析.

其实关于很多解析的报错都是在函数ip_to_hostname函数中,如果skip-name-resolve将不会发生这些
包含如下:
 sql_print_warning("IP address '%s' could not be resolved: %s",ip_key,gai_strerror(err_code));
 sql_print_warning("IP address '%s' has been resolved " "to the host name '%s', which resembles " "IPv4-address itself.",ip_key,hostname_buffer);
 sql_print_warning("Host name '%s' could not be resolved: %s",hostname_buffer,gai_strerror(err_code));
 sql_print_warning("Hostname '%s' does not resolve to '%s'.",hostname_buffer,ip_key);
 如果遇到问题类似问题紧急情况下先设置skip-name-resolve再说。

注意:
1、
在整个解析期间可能还会出现下面的用户
unauthenticated user
也就是TCP/IP 握手已经成功,数据已经开始交互,线程已经建立,但是还没有通过MYSQL 权限认证的用户(不知这句结论正确与否,自我理解)。

mysql> show processlist;
+----+----------------------+----------------------+------+---------+------+----------+------------------+-----------+---------------+
| Id | User                 | Host                 | db   | Command | Time | State    | Info             | Rows_sent | Rows_examined |
+----+----------------------+----------------------+------+---------+------+----------+------------------+-----------+---------------+
|  5 | unauthenticated user | 192.168.190.60:12770 | NULL | Connect |   35 | login    | NULL             |         0 |             0 |
|  6 | root                 | localhost            | NULL | Query   |    0 | starting | show processlist |         0 |             0 |
+----+----------------------+----------------------+------+---------+------+----------+------------------+-----------+---------------+
如果出现这种用户优先考虑一下是否是DNS解析缓慢问题,如开启了mysql 反解析,没有设置合适的/etc/hosts
2、测试期间,未关闭skip-name-resolve首先使用了user@ip进行了连接,然后删除用户建立一个user@domain的用户
   并且设置了/etc/hosts,这个时候客户端连接不上服务端,一直报密码不对,这个问题flush hosts后解决,这是
   因为最开始使用IP反解析的时候得到的域名和我设置的/etc/hosts的域名不一致,虽然得到了正确的IP,但是在
   host cache中,得到的domain并不一致,也就是说本来是username@domain1被反解析为了username@domain2这种
   情况当然在mysql.user中找不到相应的权限用户记录了,这个时候flush hosts后清空了host cache,得以重新
   生成相应的host cache后正常,这点在前面的代码
   Host_entry *entry= hostname_cache_search(ip_key);//在cache中查找
   也有体现。
3、select * from performance_schema.host_cache 这里记录了IP->DOMAIN的类容
如下:
mysql> select * from performance_schema.host_cache \G;
*************************** 1. row ***************************
                                        IP: 192.168.190.60
                                      HOST: test
                            HOST_VALIDATED: YES
..................
                                FIRST_SEEN: 2017-05-31 17:17:40
                                 LAST_SEEN: 2017-05-31 17:17:40
                          FIRST_ERROR_SEEN: NULL
                           LAST_ERROR_SEEN: NULL
4、反解析的作用
如前面所讲述,反解析IP->DOMAIN的作用就在于,在建立如下用户的时候
create user testuuu@'test' identified by '123';
的时候MYSQL能够通过ip地址判断出他的权限信息,因为在MYSQL.USER中存储的是域名(DOMAIN),而为了加速反解析的速度,而有了HOST CACHE
那就是
第一次连接
1、拿到客户端IP地址(socket连接客户端IP地址信息)
2、进行DNS反解析 (如/etc/hosts)
3、存储反解析信息到host cache
4、从host cache中拿到这个反解析出来的domain进行权限验证
如果不是第一次连接跳过第二步,也正是因为跳过了第二步,产生了注意2中的问题
flush host就是来清理host cache从而解决这种问题,重新进行DNS反解析                        
其实整个定位问题的过程还是比较简单,但是我至今没有找到entry->m_errors.m_connect什么时候增加,而且源码中
还有很多地方 没有理解由于时间原因我没有去仔细看(因为这要消耗很多很多的时间),这里只能抛砖了,同时也记录
了我的分析过程。
   
下面是MYSQL官方手册的解释:   
9.12.6.2 DNS Lookup Optimization and the Host Cache   
The server handles entries in the host cache like this:
1. When the first TCP client connection reaches the server from a given IP address, a new entry is
created to record the client IP, host name, and client lookup validation flag. Initially, the host name is
set to NULLand the flag is false. This entry is also used for subsequent client connections from the
same originating IP.
2. If the validation flag for the client IP entry is false, the server attempts an IP-to-host name DNS
resolution. If that is successful, the host name is updated with the resolved host name and the
validation flag is set to true. If resolution is unsuccessful, the action taken depends on whether the error
is permanent or transient. For permanent failures, the host name remains NULLand the validation flag
is set to true. For transient failures, the host name and validation flag remain unchanged. (Another DNS
resolution attempt occurs the next time a client connects from this IP.)
3. If an error occurs while processing an incoming client connection from a given IP address, the server
updates the corresponding error counters in the entry for that IP. For a description of the errors
recorded, see Section 23.9.16.1, “The host_cache Table”.
The server uses the host cache for several purposes:
? By caching the results of IP-to-host name lookups, the server avoids doing a DNS lookup for each client
connection. Instead, for a given host, it needs to perform a lookup only for the first connection from that
host.
? 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_errorssystem
variable determines the number of permitted errors before blocking occurs. See Section B.5.2.6, “Host
'host_name' is blocked”.
To unblock blocked hosts, flush the host cache by issuing a FLUSH HOSTSstatement or executing a
mysqladmin flush-hostscommand.

作者微信:

               


相关文章
|
2月前
|
监控 Java 应用服务中间件
高级java面试---spring.factories文件的解析源码API机制
【11月更文挑战第20天】Spring Boot是一个用于快速构建基于Spring框架的应用程序的开源框架。它通过自动配置、起步依赖和内嵌服务器等特性,极大地简化了Spring应用的开发和部署过程。本文将深入探讨Spring Boot的背景历史、业务场景、功能点以及底层原理,并通过Java代码手写模拟Spring Boot的启动过程,特别是spring.factories文件的解析源码API机制。
103 2
|
20天前
|
存储 设计模式 算法
【23种设计模式·全精解析 | 行为型模式篇】11种行为型模式的结构概述、案例实现、优缺点、扩展对比、使用场景、源码解析
行为型模式用于描述程序在运行时复杂的流程控制,即描述多个类或对象之间怎样相互协作共同完成单个对象都无法单独完成的任务,它涉及算法与对象间职责的分配。行为型模式分为类行为模式和对象行为模式,前者采用继承机制来在类间分派行为,后者采用组合或聚合在对象间分配行为。由于组合关系或聚合关系比继承关系耦合度低,满足“合成复用原则”,所以对象行为模式比类行为模式具有更大的灵活性。 行为型模式分为: • 模板方法模式 • 策略模式 • 命令模式 • 职责链模式 • 状态模式 • 观察者模式 • 中介者模式 • 迭代器模式 • 访问者模式 • 备忘录模式 • 解释器模式
【23种设计模式·全精解析 | 行为型模式篇】11种行为型模式的结构概述、案例实现、优缺点、扩展对比、使用场景、源码解析
|
20天前
|
设计模式 存储 安全
【23种设计模式·全精解析 | 创建型模式篇】5种创建型模式的结构概述、实现、优缺点、扩展、使用场景、源码解析
结构型模式描述如何将类或对象按某种布局组成更大的结构。它分为类结构型模式和对象结构型模式,前者采用继承机制来组织接口和类,后者釆用组合或聚合来组合对象。由于组合关系或聚合关系比继承关系耦合度低,满足“合成复用原则”,所以对象结构型模式比类结构型模式具有更大的灵活性。 结构型模式分为以下 7 种: • 代理模式 • 适配器模式 • 装饰者模式 • 桥接模式 • 外观模式 • 组合模式 • 享元模式
【23种设计模式·全精解析 | 创建型模式篇】5种创建型模式的结构概述、实现、优缺点、扩展、使用场景、源码解析
|
20天前
|
设计模式 存储 安全
【23种设计模式·全精解析 | 创建型模式篇】5种创建型模式的结构概述、实现、优缺点、扩展、使用场景、源码解析
创建型模式的主要关注点是“怎样创建对象?”,它的主要特点是"将对象的创建与使用分离”。这样可以降低系统的耦合度,使用者不需要关注对象的创建细节。创建型模式分为5种:单例模式、工厂方法模式抽象工厂式、原型模式、建造者模式。
【23种设计模式·全精解析 | 创建型模式篇】5种创建型模式的结构概述、实现、优缺点、扩展、使用场景、源码解析
|
2月前
|
缓存 监控 Java
Java线程池提交任务流程底层源码与源码解析
【11月更文挑战第30天】嘿,各位技术爱好者们,今天咱们来聊聊Java线程池提交任务的底层源码与源码解析。作为一个资深的Java开发者,我相信你一定对线程池并不陌生。线程池作为并发编程中的一大利器,其重要性不言而喻。今天,我将以对话的方式,带你一步步深入线程池的奥秘,从概述到功能点,再到背景和业务点,最后到底层原理和示例,让你对线程池有一个全新的认识。
61 12
|
1月前
|
PyTorch Shell API
Ascend Extension for PyTorch的源码解析
本文介绍了Ascend对PyTorch代码的适配过程,包括源码下载、编译步骤及常见问题,详细解析了torch-npu编译后的文件结构和三种实现昇腾NPU算子调用的方式:通过torch的register方式、定义算子方式和API重定向映射方式。这对于开发者理解和使用Ascend平台上的PyTorch具有重要指导意义。
|
21天前
|
安全 搜索推荐 数据挖掘
陪玩系统源码开发流程解析,成品陪玩系统源码的优点
我们自主开发的多客陪玩系统源码,整合了市面上主流陪玩APP功能,支持二次开发。该系统适用于线上游戏陪玩、语音视频聊天、心理咨询等场景,提供用户注册管理、陪玩者资料库、预约匹配、实时通讯、支付结算、安全隐私保护、客户服务及数据分析等功能,打造综合性社交平台。随着互联网技术发展,陪玩系统正成为游戏爱好者的新宠,改变游戏体验并带来新的商业模式。
|
2月前
|
存储 安全 Linux
Golang的GMP调度模型与源码解析
【11月更文挑战第11天】GMP 调度模型是 Go 语言运行时系统的核心部分,用于高效管理和调度大量协程(goroutine)。它通过少量的操作系统线程(M)和逻辑处理器(P)来调度大量的轻量级协程(G),从而实现高性能的并发处理。GMP 模型通过本地队列和全局队列来减少锁竞争,提高调度效率。在 Go 源码中,`runtime.h` 文件定义了关键数据结构,`schedule()` 和 `findrunnable()` 函数实现了核心调度逻辑。通过深入研究 GMP 模型,可以更好地理解 Go 语言的并发机制。
|
2月前
|
消息中间件 缓存 安全
Future与FutureTask源码解析,接口阻塞问题及解决方案
【11月更文挑战第5天】在Java开发中,多线程编程是提高系统并发性能和资源利用率的重要手段。然而,多线程编程也带来了诸如线程安全、死锁、接口阻塞等一系列复杂问题。本文将深度剖析多线程优化技巧、Future与FutureTask的源码、接口阻塞问题及解决方案,并通过具体业务场景和Java代码示例进行实战演示。
67 3
|
3月前
|
存储
让星星⭐月亮告诉你,HashMap的put方法源码解析及其中两种会触发扩容的场景(足够详尽,有问题欢迎指正~)
`HashMap`的`put`方法通过调用`putVal`实现,主要涉及两个场景下的扩容操作:1. 初始化时,链表数组的初始容量设为16,阈值设为12;2. 当存储的元素个数超过阈值时,链表数组的容量和阈值均翻倍。`putVal`方法处理键值对的插入,包括链表和红黑树的转换,确保高效的数据存取。
70 5

推荐镜像

更多