MySQL 8.0+真锁定仅靠FAILED_LOGIN_ATTEMPTS与PASSWORD_LOCK_TIME实现,需用户使用caching_sha2_password或mysql_native_password插件、创建/修改时显式指定策略,且PASSWORD_LOCK_TIME=0为永久锁定;connection_control插件仅为加延迟,不改account_locked字段,须双插件加载并配置非零延迟才生效。

MySQL 8.0+ 真锁定:用 FAILED_LOGIN_ATTEMPTS 和 PASSWORD_LOCK_TIME
这是唯一能真正把账号状态设为 account_locked = 'Y' 的方式,不是加延迟,是硬性拒绝后续登录。但必须满足几个硬条件:
- 用户认证插件必须是
caching_sha2_password或mysql_native_password(sha256_password不支持) - 创建或修改用户时显式指定策略,例如:
CREATE USER 'u'@'%' IDENTIFIED BY 'p' FAILED_LOGIN_ATTEMPTS 3 PASSWORD_LOCK_TIME 1;
表示输错 3 次锁 1 小时 -
PASSWORD_LOCK_TIME 0是永久锁定,不会自动恢复;锁定期满也不会自动解锁——必须有一次**成功登录**才会重置计数并清除锁定状态 - 失败计数只对同一用户+主机组合独立维护,
'u'@'192.168.1.10'和'u'@'192.168.1.11'互不影响
connection_control 插件:本质是加延迟,不是锁定账号
它不改 account_locked 字段,也不拦截连接,只是让第 N 次失败后的响应变慢。常见误配导致“设了没反应”:
- 必须同时加载两个插件:
connection_control.so(或.dll)和connection_control_failed_login_attempts.so,缺一不可 -
connection_control_failed_connections_threshold = 3只表示“从第 4 次失败开始启用延迟逻辑”,但若connection_control_min_connection_delay = 0(默认值),延迟就是 0 毫秒 → 完全无感 - 单位是毫秒,不是秒:
60000是 1 分钟,60是 60 毫秒,客户端根本察觉不到 - 所有失败都报
ERROR 1045 (28000),无法靠错误码区分是密码错还是被插件卡住;确认是否生效得查:SHOW STATUS LIKE 'Connection_control_delayed_connections';
非零才说明真在起作用
为什么 max_connect_errors 不是你想要的“账号锁定”
这个变量早于 MySQL 5.7,作用对象是**客户端 IP 地址**,不是用户账号。它触发的是“禁止该 IP 连接”,而不是“锁定某用户”。典型表现:
- 输错密码 10 次(
max_connect_errors = 10),之后来自该 IP 的任何用户(包括 root)都会被拒绝,报错Host 'x.x.x.x' is blocked - 它不记录失败原因,SSL 错误、网络中断、用户名不存在,全算作一次“connect error”
- 清空计数靠
FLUSH HOSTS,不是靠时间或成功登录;重启 mysqld 也会重置 - 它和
FAILED_LOGIN_ATTEMPTS、connection_control三者逻辑完全独立,混用容易互相掩盖问题
怎么验证当前生效的是哪种机制?
别信客户端表现,直接查服务端状态:
- 看账号是否真被锁:
SELECT user, host, account_locked, failed_login_attempts FROM mysql.user WHERE user = 'u';
若account_locked = 'Y',说明FAILED_LOGIN_ATTEMPTS在起作用 - 看插件是否加载成功:
SELECT PLUGIN_NAME, PLUGIN_STATUS FROM INFORMATION_SCHEMA.PLUGINS WHERE PLUGIN_NAME IN ('connection_control', 'connection_control_failed_login_attempts');两行都必须是ACTIVE - 看延迟是否触发:
SHOW VARIABLES LIKE 'connection_control%'; SHOW STATUS LIKE 'Connection_control%';
关键是Connection_control_delayed_connections是否递增
最易被忽略的一点:所有配置项(尤其是插件路径、阈值、延迟值)必须在 my.cnf 的 [mysqld] 段里写死,然后完整重启 mysqld;运行时 SET GLOBAL 对插件参数可能无效,INSTALL PLUGIN 在 secure_file_priv 启用时大概率失败。











