mysqladmin flush-hosts 能立刻解封被阻塞的IP,是因为它清空了MySQL内存中的host cache,重置所有IP的错误计数器,该操作无需重启服务、不修改配置,但需SUPER权限且为全局清空。

MySQL 报错 Host is blocked 不是数据库崩了,而是它主动拉黑了你的 IP —— 本质是连接认证阶段失败次数超限触发的防御机制。
为什么 mysqladmin flush-hosts 能立刻解封?
因为 MySQL 内部维护了一个内存中的 host cache(主机缓存),记录每个 IP 的连接错误计数。一旦某个 IP 的错误数 ≥ max_connect_errors(默认 100),该 IP 就被标记为“blocked”,后续所有连接请求在认证前就被拒绝。
mysqladmin flush-hosts 做的事很简单:清空这个 host cache,重置所有 IP 的错误计数器。它不重启服务、不改配置、不查日志,纯内存操作,所以秒生效。
- 必须用有 SUPER 权限的账号执行(通常是
root) - 命令本身不带 IP 参数,是全局清空;不能只解封某一个 IP
- 如果 MySQL 启用了
skip_name_resolve=ON,host cache 实际按 IP 地址匹配,否则可能按 DNS 反解后的主机名匹配(更难排查)
flush hosts 和 mysqladmin flush-hosts 有什么区别?
两者效果完全一样,都是清空 host cache。区别只在执行入口:
-
flush hosts是 SQL 语句,需先连上 MySQL(比如用mysql -u root -p登录后执行) -
mysqladmin flush-hosts是客户端工具命令,只要网络可达、凭据正确,哪怕当前连不上数据库也能跑(因为它走的是 MySQL 管理协议,不是普通连接) - 如果已经连不上了,
mysqladmin是唯一能用的途径;而flush hosts此时根本执行不了
为什么刚 flush 完,过几分钟又报 blocked?
说明底层连接失败问题没解决,错误计数器很快又涨到阈值。常见原因包括:
- 应用代码里写了死循环重试连接,且用户名/密码错误或未配置 SSL
- 连接池初始化参数(如
initialSize)设得过大,MySQL 还没准备好就猛发建连请求 - DNS 解析不稳定,导致 TCP 握手成功但认证阶段因 hostname 反解失败而记为错误
- 防火墙或代理中断了部分 TLS 握手,MySQL 认为是“协议错误”计入计数
临时 flush 只是止痛,max_connect_errors 调高(比如设成 1000)也只是延缓问题——真正要盯的是应用日志里反复出现的首次连接失败原因。
哪些情况 mysqladmin flush-hosts 会失败?
最常见的不是权限或网络问题,而是以下两种:
- MySQL 配置了
skip_networking=ON,此时mysqladmin无法通过 TCP 连接,必须走本地 socket(加-S /var/lib/mysql/mysql.sock) - MySQL 用户没开远程管理权限:
mysqladmin默认走 TCP,如果root@'%'没授权,或者只给了root@'localhost',就会提示Access denied - SELinux 或 AppArmor 限制了
mysqladmin的网络能力(少见但生产环境真发生过)
别急着调大 max_connect_errors,先确认是不是连接链路本身有问题——比如中间 LB 超时、客户端证书过期、MySQL 已满连接数(max_connections 耗尽)导致新连接直接被拒,这类错误也会被误计入 host cache。


















