应查询performance_schema.host_cache表确认主机是否被阻塞,执行SELECT HOST, IP, SUM_CONNECT_ERRORS, COUNT_HOST_BLOCKED_ERRORS FROM performance_schema.host_cache WHERE SUM_CONNECT_ERRORS > 0(需PROCESS权限);若返回空,则非host block问题,需排查max_connections耗尽等其他原因。

查 performance_schema.host_cache 确认是否真被 block
MySQL 8.0+ 的 host block 状态只存在 performance_schema.host_cache 里,SHOW VARIABLES LIKE 'max_connect_errors' 只告诉你阈值,不反映实际谁超了。执行以下语句需有 PROCESS 权限:
SELECT HOST, IP, SUM_CONNECT_ERRORS, COUNT_HOST_BLOCKED_ERRORS FROM performance_schema.host_cache WHERE SUM_CONNECT_ERRORS > 0;
如果返回空,说明不是 host block,得去查 max_connections 耗尽、wait_timeout 中断或 SSL 握手失败等其他问题。
确认 max_connect_errors 是否被调得过低
很多云数据库(如阿里云 RDS)默认把 max_connect_errors 设为 10,内部测试网 DNS 慢一点、连接池预热时多试两次就直接封 IP。检查当前值:
SHOW VARIABLES LIKE 'max_connect_errors';
常见误操作是临时 SET GLOBAL max_connect_errors = 1000,但重启后失效。永久生效必须写进配置文件 [mysqld] 段并重启 mysqld:
-
max_connect_errors = 200是较稳妥的生产值 - 设成 10000 会削弱暴力破解防护,公网暴露实例慎用
- 别和
connect_timeout混——后者控制单次握手秒数,不影响 host block 计数
排查应用层是否持续触发失败连接
刚 FLUSH HOSTS 就又 block,说明错误源没停。重点盯三类行为:
- 应用配置写死错密码或错用户名,每次启动/重连都失败一次
- 连接池(如 HikariCP)开了
connection-test-query,但 SQL 语法错或表不存在,建连后立刻报错 → 计入错误次数 - 防火墙、SLB 或 Nginx TCP proxy 主动断开空闲连接,MySQL 收不到 FIN,判定为异常中断
特别注意:主从架构下,应用连的是从库,但你只在主库上执行了 FLUSH HOSTS,从库的 host_cache 仍是 blocked 状态。
验证 skip_name_resolve 是否干扰匹配逻辑
如果 MySQL 启用了 skip_name_resolve = ON,host cache 按原始 IP 匹配;否则会尝试反解 DNS 主机名再匹配——这会导致日志里显示 HOST='example.com',但你查 IP='192.168.1.100' 却找不到记录。
查当前设置:
SHOW VARIABLES LIKE 'skip_name_resolve';
若为 OFF,且你用域名连接数据库,DNS 解析慢或失败也会计入错误计数,建议开发/测试环境统一用 IP 连接,避免 hostname 层面的不确定性。


















