mysql账号被锁时输对密码仍报“account is locked”,因认证流程最前端即检查account_locked='y'并直接拒绝,不校验密码;必须用高权限账号执行alter user ... account unlock(常需同步重置密码),且host必须严格匹配,flush privileges无效。

必须用高权限账号(如 root)执行 ALTER USER ... ACCOUNT UNLOCK,仅输对密码或运行 FLUSH PRIVILEGES 完全无效。
为什么连对密码也报 “Account is locked”
MySQL 8.0 在认证流程最前端就检查 account_locked 字段,值为 'Y' 时直接拒绝登录,根本不会比对密码。错误信息通常是:Access denied for user 'xxx'@'localhost'. Account is locked.。这不是网络、服务或密码问题,而是账户状态被硬性锁定。
- 常见诱因包括:连续输错密码超限(
failed_login_attempts触发)、手动执行ALTER USER ... ACCOUNT LOCK、或老客户端连接 8.0+ 服务时触发隐式锁定 -
account_locked = 'Y'和password_expired = 'Y'可能同时存在;只解一个,登录仍会失败 - 不能通过
UPDATE mysql.user修改,MySQL 不允许直接写系统表来绕过状态机
临时解锁的正确 SQL 写法
必须一步到位,同时处理锁定状态和可能的过期状态。主机名(host)必须严格匹配,否则报错 ERROR 1396 (HY000)。
- 先确认状态:
SELECT user, host, account_locked, password_expired FROM mysql.user WHERE user = 'xxx'; - 若两个字段都是
'Y',执行:ALTER USER 'xxx'@'localhost' IDENTIFIED BY 'newpass' ACCOUNT UNLOCK; - 如果只是想保留原密码(且你知道它),可用空密码重置再设回(不推荐):
ALTER USER 'xxx'@'localhost' IDENTIFIED BY '' ACCOUNT UNLOCK;,但需后续再改密 - 注意:
FLUSH PRIVILEGES对此无任何作用——它只刷新权限缓存,不改变运行时账户状态
连 root 都被锁死怎么办
当没有其他高权限账号可用时,--init-file 是最安全可控的临时解锁方式,它不跳过权限校验,只在启动瞬间执行一条 SQL。
- 停服务:
sudo systemctl stop mysql(Linux)或net stop mysql80(Windows) - 写初始化文件,如
/tmp/unlock-root.sql,内容仅一行:ALTER USER 'root'@'localhost' ACCOUNT UNLOCK;(如有'root'@'%'也加一行) - 临时启动:
sudo mysqld --user=mysql --init-file=/tmp/unlock-root.sql &(Linux);Windows 下需指定--datadir和--console - 验证成功后,杀掉该进程:
sudo kill $(pgrep mysqld),再正常启动服务
解锁后仍连不上?检查认证插件兼容性
MySQL 8.0 默认用 caching_sha2_password 插件,但 Navicat 旧版、PHP 7.4 mysqli、某些 shell 脚本不支持它。即使账户已解锁,也会静默报错 Access denied,不提示锁定。
- 进库后立刻查:
SELECT User, Host, plugin FROM mysql.user WHERE User = 'xxx'; - 若需兼容,改回传统插件:
ALTER USER 'xxx'@'localhost' IDENTIFIED WITH mysql_native_password BY 'newpass'; - 别漏掉
'xxx'@'%'(如果存在),否则远程连接仍失败 - 改完插件后,务必确认
account_locked = 'N'和password_expired = 'N'都已生效——这是最容易忽略的环节











