mysqladmin flush-hosts能立刻解封,因它清空MySQL内存中的host_cache,重置所有IP错误计数器,不重启服务、不改配置,仅清除黑名单记录;但需SUPER权限,主从须分别执行,且不解决密码错误等根本原因。

直接执行 mysqladmin flush-hosts 就能立刻恢复连接,但不查清原因,10分钟后可能又挂。
为什么 flush-hosts 能立刻解封?
MySQL 内部用内存结构 host_cache 记录每个 IP 的失败连接次数,flush-hosts 命令会清空这个缓存,把所有 IP 的错误计数重置为 0。它不重启服务、不改配置、不删用户,只是“擦掉黑名单记录”。
注意:flush-hosts 不影响已建立的连接,只重置后续连接的准入判断;它也不清理 DNS 缓存或系统 hosts 文件——名字容易误导,实际跟系统级 hosts 无关。
- 必须用有 SUPER 权限的账号(通常是
root)执行 - 如果 MySQL 启用了 socket 连接,建议加
-S /var/lib/mysql/mysql.sock避免走网络协议失败 - 主从架构下,要分别在主库和从库上都执行一次
max_connect_errors 改大就能一劳永逸?
不能。默认值是 100,改成 1000 或 10000 只是推迟报错时间,治标不治本。而且调太高会削弱安全防护能力——真有暴力扫密行为时,MySQL 就没法及时拉黑了。
更关键的是:这个参数只管“连续失败连接”,而失败原因往往出在应用侧。比如:
- 连接池配置了错误的
username或password,每次获取连接都失败 - 应用没正确关闭连接,连接池不断新建连接直到超时,触发大量“连接超时”错误
- DNS 解析不稳定,
host_cache把解析失败也记为连接错误(尤其在用域名而非 IP 连接时)
所以先别急着 SET GLOBAL max_connect_errors = 10000,先看日志确认是不是你自己的程序在疯狂试错。
怎么快速定位到底是哪个 IP 在狂连失败?
MySQL 8.0+ 可以直接查 performance_schema.host_cache 表:
SELECT HOST, SUM_CONNECT_ERRORS, FIRST_SEEN, LAST_SEEN FROM performance_schema.host_cache WHERE SUM_CONNECT_ERRORS > 0;
结果里 SUM_CONNECT_ERRORS 非零的行,就是正在被计数的异常来源。注意该表需要 PROCESS 权限,且默认可能被禁用(performance_schema=ON 且相关消费者开启)。
如果是 MySQL 5.7 或更低版本,只能靠错误日志反推:
- 打开
log_error指向的错误日志文件(如/var/log/mysqld.log) - 搜关键词
Access denied或Connection refused,配合时间戳看密集出现的 IP - 注意区分:日志里 “Aborted connection” 类错误不计入
host_cache,只有“连接建立阶段失败”才算
最容易被忽略的三个点
第一,flush-hosts 命令本身也会失败——如果 MySQL 配置了 skip-name-resolve,但你用 -h hostname 而非 -h IP 执行,mysqladmin 可能卡在 DNS 解析上,看起来像命令没反应。
第二,某些云数据库(如阿里云 RDS、腾讯云 CDB)不开放 flush-hosts 权限,也不能执行 FLUSH HOSTS,只能提工单或通过控制台重置主机缓存。
第三,应用代码里如果用了连接字符串带 autoReconnect=true(JDBC)或类似重试逻辑,且底层密码/权限一直错,就会形成“失败→重试→再失败”的死循环,几秒内就打满 100 次——这种必须改代码,不是 DBA 能解决的。


















