暂无图片
暂无图片
1
暂无图片
暂无图片
暂无图片

MySQL应用突然连不上库?一招解除IP拉黑

原创 飞天 2天前
146

MySQL8.4连接被拦截报错:host缓存连接错误超限完整排查方案

一、故障现象

业务应用访问MySQL数据库突然全部连接失败,无法建立数据库会话,程序抛出数据库连接异常日志。
image.png

环境说明

数据库版本:MySQL 8.4.4 Community Server - GPL

二、故障根因原理

MySQL存在两个核心参数控制IP连接拦截逻辑:

  1. max_connect_errors
    默认值100000,代表单个IP累计连接错误次数达到该阈值后,MySQL会永久封禁该IP,拒绝后续所有连接请求
    连接错误包含:密码错误、协议不匹配、网络握手失败、权限校验失败、数据包异常等,只要握手阶段未正常完成,都会计入错误计数。
  2. performance_schema.host_cache
    MySQL内部主机缓存表,实时记录每个来访IP的连接错误累计值SUM_CONNECT_ERRORS,IP封禁判断完全依赖这张表的数据。

登录到数据库中检查:

mysql> SELECT IP,HOST,HOST_VALIDATED,SUM_CONNECT_ERRORS -> FROM performance_schema.host_cache; +---------------+--------+----------------+--------------------+ | IP | HOST | HOST_VALIDATED | SUM_CONNECT_ERRORS | +---------------+--------+----------------+--------------------+ | 192.168.\*.1* | NULL | YES | 100000 | | 192.168.\*.2* | NULL | YES | 100001 | | 192.168.\*.3* | NULL | YES | 34 | | 192.168.\*.4* | NULL | YES | 0 | ...略

三、处理过程

1. 查看系统最大连接错误阈值

登录MySQL客户端执行:

show variables like 'max_connect_errors';
mysql> show variables like 'max_connect_errors'; +--------------------+--------+ | Variable_name | Value | +--------------------+--------+ | max_connect_errors | 100000 | +--------------------+--------+ 1 row in set (0.00 sec)

2. 查询所有IP累计连接错误(定位被封禁IP)

通过性能模式主机缓存,查看全量IP错误统计:

SELECT IP,HOST,HOST_VALIDATED,SUM_CONNECT_ERRORS FROM performance_schema.host_cache;
mysql> SELECT IP,HOST,HOST_VALIDATED,SUM_CONNECT_ERRORS -> FROM performance_schema.host_cache; +---------------+--------+----------------+--------------------+ | IP | HOST | HOST_VALIDATED | SUM_CONNECT_ERRORS | +---------------+--------+----------------+--------------------+ | 192.168.\*.1* | NULL | YES | 100000 | | 192.168.\*.2* | NULL | YES | 100001 | | 192.168.\*.3* | NULL | YES | 34 | | 192.168.\*.4* | NULL | YES | 0 | ...略

输出解读:

  • SUM_CONNECT_ERRORS:该IP累计连接失败次数
  • 数值 ≥ max_connect_errors 的IP,已被数据库拦截,业务无法建立连接

本次查询结果关键信息:
192.168..1 累计100000次错误、192.168..2 累计100001次错误,触发封禁规则。

四、紧急恢复方案

方式1:mysqladmin 清空主机缓存(生产推荐,无需重启库)

在数据库服务器操作系统执行(使用本地socket连接,避免远程连接失效):

# 通过mysql.sock本地登录执行flush-hosts,清空host缓存 mysqladmin -S /data/mysql/mysql.sock -u root -p flush-hosts

输入root密码执行完成后,重新登录MySQL验证:

SELECT IP,HOST,HOST_VALIDATED,SUM_CONNECT_ERRORS FROM performance_schema.host_cache; +--------------+------+----------------+--------------------+ | IP | HOST | HOST_VALIDATED | SUM_CONNECT_ERRORS | +--------------+------+----------------+--------------------+ | 192.168.\*.1* | NULL | YES | 0 | | 192.168.\*.2* | NULL | YES | 0 | | 192.168.\*.3* | NULL | YES | 0 | | 192.168.\*.4* | NULL | YES | 0 | ...略

执行后所有IP的SUM_CONNECT_ERRORS全部清零,被封禁IP自动解除限制,业务连接立刻恢复正常。

补充备选:SQL内部执行清空

登录MySQL后执行,效果与上方命令一致:

FLUSH HOSTS;

注意:MySQL8.0+支持该语句,无需重启数据库。

五、长效优化方案(避免故障重复发生)

方案1:调大max_connect_errors阈值(临时缓解)

  1. 在线临时调整(重启失效)
set global max_connect_errors=1000000;
  1. 永久配置(my.cnf)
[mysqld] max_connect_errors=1000000

重启MySQL服务生效,大幅拉高错误计数上限,减少误封概率。

方案2:定位根源,消除大量连接报错(治本)

频繁触发连接超限,本质是业务侧持续产生大量失败握手,需排查源头:

  1. 应用配置:数据库账号密码、端口、地址配置错误;
  2. 程序重连逻辑:短时间疯狂重试,持续刷错误计数;
  3. 网络/中间件:代理、防火墙、连接池异常断连;
  4. 扫描爆破行为:外部恶意扫描数据库端口,高频密码错误。

方案3:高危场景直接关闭主机缓存(内网可信环境)

内网纯信任业务网段,无外部扫描风险,可关闭host缓存,彻底规避IP封禁问题:

[mysqld] skip_host_cache

风险提示:公网对外提供数据库服务禁止开启该参数,会失去暴力破解防护能力。

六、DBA运维总结

  1. 业务突现数据库连接失败,优先排查max_connect_errorshost_cache表,大概率是IP连接错误超限封禁;
  2. 紧急止血命令flush-hosts无停机、秒级恢复,线上故障优先使用;
  3. 清空缓存仅临时恢复业务,必须溯源大量连接报错的源头,否则会再次触发封禁;
  4. MySQL8.4性能模式performance_schema.host_cache是定位IP错误的核心视图,日常巡检可加入监控;
  5. 区分内网/公网环境选择优化策略,公网不可随意关闭host缓存,兼顾可用性与数据库安全。

关于作者

网名:飞天,墨天轮2024年度、2025年度优秀原创作者,拥有 Oracle 10g OCM 认证、PGCE认证、MySQL 8.0 OCP认证以及OBCA、KCP、KCSM、ACP、YCP、HCIP-openGauss、HCCDP-GaussDB、磐维等众多国产数据库认证证书,目前从事Oracle、Mysql、PostgreSQL、磐维数据库管理运维工作,喜欢结交更多志同道合的朋友,热衷于研究、分享数据库技术。
微信公众号:飞天online
墨天轮:https://www.modb.pro/u/15197
如有任何疑问,欢迎大家留言,共同探讨~~~

最后修改时间:2026-08-13 09:41:02
「喜欢这篇文章,您的关注和赞赏是给作者最好的鼓励」
关注作者
【版权声明】本文为墨天轮用户原创内容,转载时必须标注文章的来源(墨天轮),文章链接,文章作者等基本信息,否则作者和墨天轮有权追究责任。如果您发现墨天轮中有涉嫌抄袭或者侵权的内容,欢迎发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

文章被以下合辑收录

评论