mysql 8.0.19+账户自动锁定需同时满足三条件:使用caching_sha2_password或sha256_password插件、显式设置failed_login_attempts与password_lock_time、启用validate_password插件;缺一不可,否则锁定不生效。

MySQL 8.0.19+ 原生账户锁定策略**必须同时满足三个条件才生效**:用户用 caching_sha2_password(或 sha256_password)插件、显式设置 FAILED_LOGIN_ATTEMPTS 和 PASSWORD_LOCK_TIME、且 validate_password 插件已启用。缺一不可,否则执行成功但完全不锁。
确认用户认证插件类型
很多用户设了参数却没锁住,根本原因是插件不匹配。mysql_native_password 用户即使写了两个参数,account_locked 字段也永远是 N。
- 查当前插件:
SELECT User, Host, plugin FROM mysql.user WHERE User = 'your_user'; - 只认
caching_sha2_password或sha256_password;mysql_native_password和auth_socket不触发自动锁定 - 旧版本升级来的用户大概率仍是
mysql_native_password,不能只改策略,得连插件一起换
成对设置 FAILED_LOGIN_ATTEMPTS 和 PASSWORD_LOCK_TIME
这两个参数是绑定关系,单独设置任意一个,MySQL 都会静默忽略——不会报错,也不会锁,account_locked 永远不变。
- 新建用户时必须写全:
CREATE USER 'app'@'%' IDENTIFIED WITH caching_sha2_password BY 'pwd' FAILED_LOGIN_ATTEMPTS 3 PASSWORD_LOCK_TIME 0.04167;(锁 1 小时) - 已有用户要改:
ALTER USER 'app'@'%' IDENTIFIED WITH caching_sha2_password BY 'newpwd' FAILED_LOGIN_ATTEMPTS 3 PASSWORD_LOCK_TIME 0.00694;(锁 10 分钟) -
PASSWORD_LOCK_TIME单位是「天」:5 分钟 ≈0.00347,0 表示永久锁定(需管理员手动ALTER USER ... ACCOUNT UNLOCK) - 锁定期满后不会自动解锁:必须有一次成功登录,才会重置失败计数并清除锁定状态
必须启用 validate_password 插件
这个插件不是用来校验密码强度的,而是为失败计数机制提供底层钩子。没它,FAILED_LOGIN_ATTEMPTS 根本不启动,错误日志里也看不到 Too many failed login attempts 记录。
- 检查是否启用:
SELECT PLUGIN_NAME, PLUGIN_STATUS FROM INFORMATION_SCHEMA.PLUGINS WHERE PLUGIN_NAME = 'validate_password';,状态必须是ACTIVE - 启用方式二选一:配置文件加
plugin_load_add = validate_password.so后重启;或运行INSTALL PLUGIN validate_password SONAME 'validate_password.so'; - 启用后会顺带激活密码强度策略(如
validate_password.length),可能影响已有建用户脚本,需提前评估
ACCOUNT LOCK 和自动锁定别混用
ALTER USER ... ACCOUNT LOCK 是人工开关式禁用,和 FAILED_LOGIN_ATTEMPTS 是两套互斥机制。一起设会导致自动锁定失效——失败计数器压根不累加,account_locked 字段也不变,但账号实际已被人工锁死。
-
ACCOUNT LOCK立即生效、不依赖插件、不影响已有连接,适用于离职停用等场景 -
account_locked字段只反映自动锁定状态,ACCOUNT LOCK不改它,所以不能靠查这个字段判断是否被人工锁住 - 验证是否真锁:用新连接尝试登录,输任意密码都应返回
Access denied for user ... (using password: YES) - 生产环境建议分策略:应用账号走自动锁定,运维账号用
ACCOUNT LOCK人工管控
最容易被忽略的是 validate_password 插件的状态和 PASSWORD_LOCK_TIME 的单位——前者不启用,整个机制形同虚设;后者写错(比如当成秒或分钟),锁时长会偏差几百倍。设完务必用真实客户端连一次失败再连一次成功,观察错误提示和 account_locked 变化,才算真正落地。











