MySQL 8.0+ 中 ACCOUNT LOCK 仅锁定账户登录能力,不改密码、不删用户,底层写入 mysql.user 表 account_locked 字段;手动锁与自动锁均可通过 ACCOUNT UNLOCK 解除。
MySQL 8.0+ 中用 ACCOUNT LOCK 锁定用户,不是改密码也不是删用户
锁定用户账户 ≠ 重置密码 ≠ 删除用户,它只是让该账号彻底无法建立新连接,哪怕密码完全正确也会被拒绝。这是 mysql 8.0 引入的原生账户状态控制机制,底层直接写入 mysql.user 表的 account_locked 字段,和密码哈希是否有效完全解耦。
- 执行
ALTER USER 'u1'@'localhost' ACCOUNT LOCK;后,下次任何客户端尝试连接都会收到错误:ERROR 3956 (HY000): Account u1@localhost is locked - 锁定后,
SELECT、SHOW GRANTS等本地管理操作仍可由管理员执行,但普通连接(包括 JDBC、MySQL CLI、PHP mysqli)一律失败 - 注意:如果用户同时拥有
SUPER或SYSTEM_USER权限,某些旧版客户端或配置下可能绕过锁定(极少见,但测试环境务必验证)
ACCOUNT UNLOCK 能解“手动锁”,也能解“自动锁”
MySQL 8.0.19+ 开始,ALTER USER ... ACCOUNT UNLOCK 不仅能解除 ACCOUNT LOCK 手动设置的锁定,还能一键清空因登录失败触发的临时锁定——比如你设了 FAILED_LOGIN_ATTEMPTS=3,用户输错三次后被自动锁 1 小时,此时执行 ACCOUNT UNLOCK 会立即释放,无需等超时。
- 手动锁的用户:查
SELECT user, host, account_locked FROM mysql.user WHERE user='u1';返回Y;解锁后变N - 自动锁的用户:即使
account_locked='Y',其锁定也带时间戳(记录在password_last_changed和内部计数器),ACCOUNT UNLOCK会重置计数器并清除锁定标记 - 别用
FLUSH PRIVILEGES试图“刷新锁定状态”——它对account_locked无效
创建用户时就锁定,避免“先建再锁”的窗口期
生产环境中,新用户(尤其是应用专用账号)不该存在“创建完成但尚未锁定”的短暂暴露期。直接在 CREATE USER 语句里加 ACCOUNT LOCK,一步到位。
- 正确写法:
CREATE USER 'app_rw'@'10.20.%' IDENTIFIED BY 's3cr3t!' ACCOUNT LOCK; - 错误写法:先
CREATE USER,再ALTER USER ... ACCOUNT LOCK—— 这中间几毫秒可能被扫描工具或误配脚本利用 - 注意:如果启用了
validate_password插件,即使ACCOUNT LOCK,也必须提供符合策略的密码,否则报错ERROR 1819 (HY000)
验证锁定状态别只看 SHOW CREATE USER,要查系统表
SHOW CREATE USER 'u1'@'localhost' 输出里带 ACCOUNT LOCK 是最直观的方式,但它不反映自动锁定状态(比如失败次数超限导致的临时锁)。真正可靠的判断依据是查询 mysql.user 表本身。
- 推荐命令:
SELECT user, host, account_locked, password_lifetime FROM mysql.user WHERE user = 'u1'; -
account_locked = 'Y'表示当前不可登录,无论原因(手动 or 自动) - 容易忽略的坑:MySQL 8.0 默认开启
caching_sha2_password认证插件,若客户端版本太老(如 MySQL 5.7 客户端连 8.0 服务端),可能报错Authentication plugin 'caching_sha2_password' cannot be loaded,这和账户锁定无关,但新手常误判为锁定了
ACCOUNT LOCK,又设 FAILED_LOGIN_ATTEMPTS=1,这时解锁行为可能受两者叠加影响。建议同一账号只用一种锁定逻辑,避免状态歧义。










