MySQL Host is blocked because of many connection errors 导致 JDBC 连接失败排查与解决

一、问题现象

XXL-Job 登录时报错:

复制代码
org.springframework.jdbc.CannotGetJdbcConnectionException:
Failed to obtain JDBC Connection

继续查看 XXL-Job 应用日志,发现底层异常:

复制代码
Caused by: com.mysql.cj.exceptions.CJException:
Host '10.0.0.10' is blocked because of many connection errors;
unblock with 'mysqladmin flush-hosts'

XXL-Job 是一个 Java 任务调度应用,xxl-job-admin 通过 JDBC 连接 MySQL。


二、问题原因

MySQL 参数:

复制代码
SHOW VARIABLES LIKE 'max_connect_errors';

默认通常为:

复制代码
max_connect_errors = 100

当某个来源 IP 连续发生较多连接异常,达到该阈值后,MySQL 会通过 Host Cache 临时封锁该 IP。

例如:

复制代码
Host '10.0.0.10' is blocked

这里封锁的是 来源 IP,不是某个数据库账号,也不是某一条 JDBC 连接。

该 IP 被封后,从这个 IP 发起的后续新连接都会受到影响。


三、排查过程

先排除最大连接数问题:

复制代码
SHOW VARIABLES LIKE 'max_connections';
SHOW GLOBAL STATUS LIKE 'Threads_connected';
SHOW GLOBAL STATUS LIKE 'Max_used_connections';
SHOW GLOBAL STATUS LIKE 'Connection_errors_max_connections';

如果当前连接很少、历史峰值也没有达到 max_connections,则说明不是连接数打满。

继续查看应用日志中的最底层:

复制代码
Caused by:

最终发现:

复制代码
Host '10.0.0.10' is blocked because of many connection errors

即可确认是 Host Block。


四、处理方法

建议先查看 Host Cache 留证:

复制代码
SELECT
    IP,
    SUM_CONNECT_ERRORS,
    COUNT_HOST_BLOCKED_ERRORS,
    COUNT_HANDSHAKE_ERRORS,
    COUNT_AUTHENTICATION_ERRORS
FROM performance_schema.host_cache;

然后解除封锁:

复制代码
TRUNCATE TABLE performance_schema.host_cache;

也可以使用:

复制代码
FLUSH HOSTS;

二选一即可,不需要重启 MySQL。


五、调整参数

为避免少量连接异常过快触发封锁,可以适当提高:

复制代码
SET GLOBAL max_connect_errors = 1000;

验证:

复制代码
SHOW VARIABLES LIKE 'max_connect_errors';

同时写入 /etc/my.cnf:

复制代码
[mysqld]
max_connect_errors=1000

这样当前立即生效,并保证 MySQL 重启后仍然生效。


六、恢复验证

查看应用是否重新连接数据库:

复制代码
SELECT
    USER,
    HOST,
    DB,
    COMMAND
FROM information_schema.PROCESSLIST
WHERE DB='xxl_job';

然后重新访问 XXL-Job 页面验证。


七、注意事项

max_connections 和 max_connect_errors 不是一个概念:

参数 作用
max_connections MySQL 最大并发连接数
max_connect_errors 某来源 IP 连续连接异常的封锁阈值

本次故障真正相关的是:

复制代码
max_connect_errors

提高到 1000 只是降低再次被快速封锁的概率,真正根因还需要继续排查:

  • JDBC 连接池频繁重试

  • 网络短暂异常

  • MySQL 短暂不可用

  • 数据库账号或 Host 授权异常

  • JDBC 握手或 SSL 异常


八、快速排查 SOP

以后再次遇到:

复制代码
Failed to obtain JDBC Connection

直接按以下顺序:

复制代码
检查 MySQL 服务
    ↓
检查当前连接数
    ↓
排除 max_connections
    ↓
查看应用日志最底层 Caused by
    ↓
发现 Host is blocked
    ↓
查询 host_cache 留证
    ↓
清理 host_cache
    ↓
调整 max_connect_errors
    ↓
验证应用恢复

总结

本次问题本质是:

XXL-Job 连续出现 MySQL 连接异常,达到 max_connect_errors 阈值后,MySQL 封锁了来源 IP,导致后续新的 JDBC 连接被拒绝。

应急恢复:

复制代码
TRUNCATE TABLE performance_schema.host_cache;

优化:

复制代码
max_connect_errors=1000

最后记住一点:

遇到 Failed to obtain JDBC Connection,不要只看页面报错,要继续找最底层 Caused by。

相关推荐
Decay__15 分钟前
VMware 安装 SQL Server 双节点 AlwaysOn 可用性组教程 —— WSFC、AG 与侦听器完整部署(系列核心篇)
运维·数据库·sql·mysql·架构
测试界的小码农20 分钟前
【Linux 命令实战(06):Linux 文件权限管理,掌握 chmod、chown、chgrp】
linux·运维·服务器
茶栀(*´I`*)1 小时前
SQL 性能分析:从慢查询日志到执行计划的完整定位方法
数据库·sql
艺杯羹1 小时前
1Panel 装好后 ufw 仍是 inactive:一次服务器安全盲区复盘
服务器·数据库·安全·网络安全·系统架构·实战·1panel
陈希1231 小时前
负载均衡与高可用:LVS、HAProxy、Keepalived 实战
运维·负载均衡·lvs
一条破秋裤2 小时前
【1114】【并发控制】【笔记】
linux
code2cat2 小时前
【随笔】MCP工具重试:任务已经创建,响应丢了怎么办
数据库·mcp
2035去旅行3 小时前
ADB的底层原理
linux·adb·嵌入式·arm·soc
武子康4 小时前
单卡 A6000 跑 Qwen-Drive:怎样留下可比较的第一条基线?
linux·人工智能·深度学习
女神下凡4 小时前
芯参谋(107):杰理AC_中科蓝讯_开发指南
linux·服务器·网络·单片机·嵌入式硬件