Host '*****' is blockedbecause of many connection errors; unblock with 'mysqladmin flush-hosts'?error.:1129这个报错是 MySQL 针对 “恶意 / 异常连接攻击” 的安全防护机制触发的结果,核心含义是:指定客户端主机(IP / 域名)因连续多次连接失败,被 MySQL 服务器临时拉黑,error:1129 是该防护逻辑的专属错误码。下面是我采集的资料,有解决办法
一、报错本质与核心机制
1. 防护逻辑
MySQL 内置 max_connect_errors 系统参数(默认值 100),用于限制 “单个主机的连续失败连接次数”:
- 当某主机的失败连接次数超过
max_connect_errors阈值时,MySQL 会将该主机加入 “黑名单”,拒绝其所有后续连接; - 失败连接包括:密码错误、权限不足、连接超时、网络中断等导致的连接建立失败(注意:连接成功后执行 SQL 报错不计入)。
2. 关键参数
| 参数名 | 默认值 | 作用 |
|---|---|---|
max_connect_errors | 100 | 单个主机允许的最大失败连接次数,超过则拉黑主机 |
host_cache_size | -1 | 主机连接缓存大小(默认自动调整),缓存中记录各主机的失败连接次数 |
二、核心报错原因分析
| 原因分类 | 具体说明 |
|---|---|
| 密码 / 权限错误(最常见) | 客户端使用错误的用户名 / 密码、或用户无 “主机 @IP” 的访问权限(如 user@localhost 无法从远程 IP 连接) |
| 网络波动 / 连接超时 | 客户端与服务器网络不稳定,连接请求频繁超时,被判定为失败连接 |
| 程序 / 连接池配置错误 | 应用程序 / 连接池(如 Druid、C3P0)配置错误(如连接参数写错),导致批量连接失败 |
| 恶意连接攻击 | 黑客尝试暴力破解 MySQL 密码,短时间内发起大量失败连接 |
| 参数配置过小 | max_connect_errors 设为过小值(如 10),正常的少量失败连接就触发拉黑 |
三、快速排查步骤(按优先级)
步骤 1:确认被拉黑的主机和失败连接次数
-- 1. 查看当前 max_connect_errors 配置
SHOW VARIABLES LIKE 'max_connect_errors';
-- 2. 查看主机连接缓存(MySQL 8.0+,需 PROCESS 权限)
SELECT * FROM performance_schema.host_cache WHERE HOST = '被拉黑的IP';
-- 重点关注:SUM_CONNECT_ERRORS(累计失败连接次数)、BLOCKED(是否被拉黑,YES/NO)
-- 3. 低版本 MySQL(5.7-)查看失败连接次数(需解析状态变量)
SHOW GLOBAL STATUS LIKE 'Aborted_connects'; -- 全局累计失败连接数
步骤 2:验证连接失败的真实原因
从被拉黑的主机执行连接测试,定位失败根源:
# 手动测试连接,查看具体失败原因
mysql -u 用户名 -p -h MySQL服务器IP -P 3306
# 常见失败提示:
# - Access denied for user 'xxx'@'xxx' (using password: YES) → 密码错误
# - Access denied for user 'xxx'@'xxx' (using password: NO) → 未传密码
# - Can't connect to MySQL server on 'xxx' (110) → 网络超时
步骤 3:排查程序 / 连接池配置
检查应用程序的数据库连接配置:
- 用户名 / 密码是否正确;
- 连接串中的
host是否为 MySQL 服务器正确 IP; - 连接池是否开启 “测试连接”(如
testOnBorrow=true),避免无效连接尝试; - 是否有死循环代码导致批量创建无效连接。
步骤 4:检查是否存在恶意攻击
# 查看 MySQL 端口(3306)的连接日志(Linux)
grep -i "3306" /var/log/auth.log
# 或用 netstat 查看当前连接来源
netstat -an | grep 3306 | grep ESTABLISHED
若某 IP 短时间内有大量 SYN_RECV 状态的连接,大概率是暴力破解攻击。
四、针对性解决方案
方案 1:临时解锁被拉黑的主机(紧急恢复)
这是报错提示中明确的解决方案,快速解除主机拉黑状态:
方式 1:使用 mysqladmin flush-hosts(推荐)
在 MySQL 服务器端执行(需 root 权限):
# 直接执行 flush-hosts,清空主机连接缓存,解除拉黑
mysqladmin -u root -p flush-hosts
# 输入 root 密码后,被拉黑主机即可重新连接
方式 2:通过 SQL 语句解锁(替代方案)
登录 MySQL 客户端执行:
-- 清空主机连接缓存,等效于 mysqladmin flush-hosts
FLUSH HOSTS;
方案 2:修复连接失败的根本原因(避免再次拉黑)
场景 2.1:密码 / 权限错误
-- 1. 重置用户密码(确保密码正确)
ALTER USER '用户名'@'被拉黑的IP' IDENTIFIED BY '新密码';
-- 若用户无该 IP 的访问权限,授权(如允许从任意 IP 连接)
GRANT ALL PRIVILEGES ON *.* TO '用户名'@'%' IDENTIFIED BY '密码';
FLUSH PRIVILEGES; -- 刷新权限
场景 2.2:网络波动 / 超时
- 排查客户端与服务器之间的网络(ping/traceroute 测试丢包);
- 增大 MySQL 连接超时配置:
-- 临时调整(重启失效) SET GLOBAL connect_timeout = 30; -- 连接建立超时,默认 10 秒 SET GLOBAL net_read_timeout = 60; -- 永久调整(修改 my.cnf/my.ini) [mysqld] connect_timeout = 30 net_read_timeout = 60
场景 2.3:程序 / 连接池配置错误
以 Java Druid 连接池为例,修正配置:
# 错误配置(密码错误/host 错误)
spring.datasource.password=wrong123
spring.datasource.url=jdbc:mysql://wrong-ip:3306/test
# 正确配置
spring.datasource.password=correct123
spring.datasource.url=jdbc:mysql://正确IP:3306/test?useUnicode=true&characterEncoding=utf8mb4
spring.datasource.testOnBorrow=true # 借连接时测试,避免无效连接
spring.datasource.validationQuery=SELECT 1
场景 2.4:恶意连接攻击
- 临时封禁攻击 IP(通过防火墙 / 安全组):
# Linux iptables 封禁 IP iptables -A INPUT -s 攻击IP -p tcp --dport 3306 -j DROP - 改 MySQL 默认端口(3306)为非标准端口(如 3307);
- 开启 MySQL 防火墙(如
bind-address限制允许连接的 IP):[mysqld] bind-address = 允许的IP1,允许的IP2 # 仅允许指定 IP 连接
方案 3:调整 max_connect_errors 阈值(长期优化)
若业务场景允许少量失败连接,可增大阈值或禁用该限制:
方式 1:临时调整(重启失效)
-- 增大阈值(如设为 1000)
SET GLOBAL max_connect_errors = 1000;
-- 禁用限制(设为 0,不推荐生产环境)
SET GLOBAL max_connect_errors = 0;
方式 2:永久调整(修改配置文件)
编辑 my.cnf(Linux)/ my.ini(Windows):
[mysqld]
# 增大失败连接阈值
max_connect_errors = 1000
# 可选:禁用主机缓存(MySQL 8.0+)
host_cache_size = 0
修改后重启 MySQL 服务生效:
bash
# Linux
systemctl restart mysqld
# Windows
net stop mysql && net start mysql
五、典型错误案例与修复
案例 1:密码错误导致主机拉黑
# 客户端连接报错:
Host '192.168.1.100' is blocked because of many connection errors; unblock with 'mysqladmin flush-hosts'
# 排查:手动连接提示密码错误
mysql -u app_user -p -h 192.168.1.200
Enter password: ******
ERROR 1045 (28000): Access denied for user 'app_user'@'192.168.1.100' (using password: YES)
# 修复步骤:
1. 解锁主机:mysqladmin -u root -p flush-hosts
2. 重置密码:ALTER USER 'app_user'@'192.168.1.100' IDENTIFIED BY 'correct_pass123';
3. 验证连接:mysql -u app_user -pcorrect_pass123 -h 192.168.1.200 # 连接成功
案例 2:网络超时导致批量失败连接
# 报错:Host '10.0.0.50' is blocked because of many connection errors
# 排查:ping 测试丢包率 30%,连接超时频繁
ping 192.168.1.200 -c 100 # 丢包严重
# 修复步骤:
1. 解锁主机:FLUSH HOSTS;
2. 排查网络故障(修复交换机/路由器);
3. 增大连接超时配置:SET GLOBAL connect_timeout = 30;
4. 应用端开启连接重试机制,降低超时概率。
案例 3:参数过小导致误拉黑
# 排查:max_connect_errors 被设为 10
SHOW VARIABLES LIKE 'max_connect_errors'; # 返回 10
# 修复步骤:
1. 解锁主机:mysqladmin flush-hosts -u root -p
2. 永久增大阈值:
vi /etc/my.cnf
[mysqld]
max_connect_errors = 1000
3. 重启 MySQL:systemctl restart mysqld
六、预防措施
- 规范用户权限配置:
- 为用户指定精准的访问主机(如
user@192.168.1.%),避免%通配符; - 定期清理无用用户,降低密码泄露风险。
- 为用户指定精准的访问主机(如
- 优化连接参数:
- 合理设置
max_connect_errors(生产环境建议 1000+); - 应用端连接池开启 “连接测试”(如
testOnBorrow=true),避免无效连接尝试。
- 合理设置
- 监控失败连接:
- 监控
Aborted_connects状态变量,异常升高时及时告警; - MySQL 8.0+ 监控
performance_schema.host_cache表,提前发现即将被拉黑的主机。
- 监控
- 加强网络安全:
- 禁止 MySQL 端口(3306)暴露在公网,仅允许内网访问;
- 开启防火墙 / 安全组,限制仅业务 IP 能访问 MySQL。
- 程序端防护:
- 连接失败时增加重试间隔(避免短时间批量重试);
- 密码错误时及时告警,避免程序死循环重试。
总结
该报错的核心解决思路是:先临时解锁主机恢复业务,再定位失败连接的根本原因(密码 / 网络 / 配置),最后调整参数 / 优化配置避免再次触发。90% 的场景是密码 / 权限错误或网络波动导致,只需修复连接问题并解锁主机即可解决;长期需通过合理配置 max_connect_errors 和加强监控,避免误拉黑或恶意攻击导致的问题。


被折叠的 条评论
为什么被折叠?



