MySQL 8.0.19+需启用validate_password插件并配置failed_login_attempts与password_lock_time参数,且用户须使用mysql_native_password或caching_sha2_password认证;创建用户时需显式声明FAILED_LOGIN_ATTEMPTS和PASSWORD_LOCK_TIME,解锁用ALTER USER … ACCOUNT UNLOCK。

MySQL 8.0+ 的 failed_login_attempts 和 password_lock_time 怎么配
MySQL 8.0.19 起原生支持登录失败锁定,但必须启用 validate_password 插件(即使不校验密码强度),且只对使用 mysql_native_password 或 caching_sha2_password 认证插件的用户生效。
配置需分两步:
- 全局开启插件:
INSTALL PLUGIN validate_password SONAME 'validate_password.so';
- 设置策略参数(在
my.cnf中或运行时 SET):SET PERSIST failed_login_attempts = 3;
SET PERSIST password_lock_time = 86400;(单位:秒;设为 0 表示永久锁定,需手动解锁)
- 注意:
SET PERSIST写入mysqld-auto.cnf,重启仍生效;用SET GLOBAL则仅当前会话有效
创建带锁定策略的用户时,CREATE USER 的 FAILED_LOGIN_ATTEMPTS 语法怎么写
策略不能全局统一应用到所有用户,必须显式在 CREATE USER 或 ALTER USER 里声明。未声明的用户沿用全局默认值(若未设则为 0,即不限制)。
示例(创建一个最多输错 5 次、锁 1 小时的用户):
CREATE USER 'app_user'@'%' IDENTIFIED BY 'p@ssw0rd'
FAILED_LOGIN_ATTEMPTS 5 PASSWORD_LOCK_TIME 3600;
关键点:
-
FAILED_LOGIN_ATTEMPTS和PASSWORD_LOCK_TIME必须同时出现,不能只写一个 - 若设
PASSWORD_LOCK_TIME UNBOUNDED,表示锁定后永不自动解锁,只能由管理员执行ALTER USER ... ACCOUNT UNLOCK - 该策略仅作用于该用户,与其他用户的锁定状态完全隔离
用户被锁定了,怎么查和解
锁定状态不记录在 mysql.user 表中,而是存在内存中(performance_schema 的 account_status 表),且只在启用相关监控时才可见。
更可靠的方式是查 INFORMATION_SCHEMA.USER_ATTRIBUTES(MySQL 8.0.22+):
SELECT User, Host, ATTRIBUTE->>'$.password_lock_time' AS lock_time,
ATTRIBUTE->>'$.failed_login_attempts' AS max_tries
FROM INFORMATION_SCHEMA.USER_ATTRIBUTES
WHERE User = 'app_user';
解锁操作很简单:
ALTER USER 'app_user'@'%' ACCOUNT UNLOCK;
常见误区:
-
DROP USER+CREATE USER不会重置锁定计数,因为账户元数据未清空(尤其mysql.user行还存在) - 错误日志里出现
User 'xxx'@'yyy' has been locked due to X failed login attempts才是真正触发锁定,不是每次输错都记日志 - 连接池复用连接时,可能因旧连接失效导致误判为“连续失败”,实际锁定是按用户+主机维度统计的
为什么设置了但没生效?几个典型失效场景
最常踩的坑不是配置错,而是环境不满足前提条件:
- MySQL 版本低于 8.0.19 —— 此功能不存在,
SET PERSIST failed_login_attempts会报错Unknown system variable - 用户认证插件不是
mysql_native_password或caching_sha2_password(比如用了auth_socket或自定义插件),锁定逻辑直接跳过 - 客户端连接时用了
--protocol=TCP但服务端绑定了skip-networking,导致认证流程绕过账户系统 - 使用了代理(如 ProxySQL、MaxScale),实际认证发生在代理层,MySQL 本身根本收不到登录请求
验证是否生效最直接的方法:用错误密码反复连接,观察第 N+1 次是否返回 ERROR 3956 (HY000): Account is locked —— 这个错误码才是锁定生效的确凿证据。
