先用root执行ALTER USER 'xxx'@'host' IDENTIFIED BY 'newpass' ACCOUNT UNLOCK;若插件不兼容,需加IDENTIFIED WITH mysql_native_password;再查account_locked和password_expired是否均为'N'。

MySQL 8.0 报错 “Account is locked” 怎么办
不是密码错了,也不是服务没起来——是 account_locked 字段被设为 'Y',MySQL 直接拒绝认证流程。哪怕输对密码,也会卡在 Access denied for user 'root'@'localhost'. Account is locked.。这种情况常见于:手抖改了 mysql.user 表、连续输错密码超限、或用老客户端连新服务时触发的隐式锁定。
为什么不能直接 UPDATE mysql.user 然后 FLUSH PRIVILEGES
因为 MySQL 8.0 在 --skip-grant-tables 模式下禁用所有权限相关语句,执行 UPDATE mysql.user 或 FLUSH PRIVILEGES 会报错:ERROR 1290 (HY000): The MySQL server is running with the --skip-grant-tables option so it cannot execute this statement。必须先绕过该限制再操作。
用 --init-file 启动 mysqld 解锁 root(推荐生产环境)
相比修改配置文件加 skip-grant-tables,--init-file 更安全、更可控,且不依赖手动删配置项,避免重启后意外跳过权限校验。
- 创建初始化 SQL 文件,例如
/tmp/unlock-root.sql,内容为:
ALTER USER 'root'@'localhost' ACCOUNT UNLOCK; ALTER USER 'root'@'%' ACCOUNT UNLOCK;
- 停止 MySQL:
sudo systemctl stop mysql - 用 init-file 启动(注意路径可读、用户权限正确):
sudo mysqld --user=mysql --init-file=/tmp/unlock-root.sql & - 等待几秒,检查是否启动成功:
sudo ss -tlnp | grep :3306 - 正常连接验证:
mysql -u root -p,此时应能登录且不再提示锁定 - 停掉该临时实例,再用常规方式启动服务:
sudo kill $(pgrep mysqld)→sudo systemctl start mysql
解锁后必须检查 plugin 和密码策略
解锁只是恢复登录资格,不代表一定能用旧客户端连上。MySQL 8.0 默认用 caching_sha2_password,而很多工具(如 Navicat 旧版、PHP 7.4 mysqli、某些 shell 脚本)不支持它。
- 进库后立刻查插件:
SELECT User, Host, plugin FROM mysql.user WHERE User = 'root'; - 若需兼容,改回传统插件:
ALTER USER 'root'@'localhost' IDENTIFIED WITH mysql_native_password BY '你的新密码'; - 别漏掉
'root'@'%'(如果存在),否则远程仍连不上 - 确认
account_locked = 'N'和password_expired = 'N'都已生效
最易忽略的是:改完 plugin 后没重连测试,或者只修了 localhost 却忘了 %,结果换台机器又连不上——这种问题往往要倒回去查两遍日志才定位到。


















