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。
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;(单位:秒;设为 0 表示永久锁定,需手动解锁)
SET PERSIST password_lock_time = 86400;
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_sche 的
maaccount_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 才是真正触发锁定,不是每次输错都记日志最常踩的坑不是配置错,而是环境不满足前提条件:
SET PERSIST failed_login_attempts 会报错 Unknown system variable
mysql_native_password 或 caching_sha2_password(比如用了 auth_socket 或自定义插件),锁定逻辑直接跳过--protocol=TCP 但服务端绑定了 skip-networking,导致认证流程绕过账户系统验证是否生效最直接的方法:用错误密码反复连接,观察第 N+1 次是否返回 ERROR 3956 (HY000): Account is locked —— 这个错误码才是锁定生效的确凿证据。