应先用--skip-grant-tables跳过权限验证启动MySQL,再通过ALTER USER重置root密码并指定mysql_native_password插件,最后确保root@localhost与root@127.0.0.1均存在且密码一致。

直接跳过密码验证启动 MySQL 服务
当 root 用户完全无法登录,且你有服务器本地管理员权限时,唯一可行的起点是绕过权限系统重启 MySQL。这不是“重置密码”的捷径,而是强制进入可操作状态的前提。
关键在于用 --skip-grant-tables 启动 mysqld,它会跳过权限表加载,所有连接都获得最高权限(但仅限本地 socket 或 127.0.0.1)。
- 先停掉正在运行的 MySQL:执行
sudo systemctl stop mysql(Ubuntu/Debian)或sudo systemctl stop mysqld(CentOS/RHEL) - 手动启动并跳过权限检查:
sudo mysqld --skip-grant-tables --skip-networking &——--skip-networking很重要,防止远程未授权访问 - 此时直接执行
mysql -u root即可无密码进入,无需-p
更新 root 用户认证插件和密码(MySQL 5.7+ 必须做)
MySQL 5.7 及以后版本默认使用 caching_sha2_password 插件,而老配置或某些客户端不兼容;更常见的是,误删或改错 plugin 字段导致即使密码正确也报 Access denied。
进到 MySQL 后,不要急着改 password 字段(该字段在 5.7+ 已废弃),必须显式设置插件和密码:
对设计或页面进行 WCAG 2.1 AA 无障碍审计。触发关键词:“audit accessibility”、 “check a11y”、 “is this accessible?” 或在审查设计时使用。
FLUSH PRIVILEGES; ALTER USER 'root'@'localhost' IDENTIFIED WITH mysql_native_password BY '你的新密码';
- 必须用
ALTER USER ... IDENTIFIED WITH,不能用旧的UPDATE mysql.user SET authentication_string=... - 如果提示
ERROR 1396 (HY000): Operation ALTER USER failed,说明用户不存在,先执行CREATE USER 'root'@'localhost' IDENTIFIED WITH mysql_native_password BY '新密码'; - 改完立刻执行
FLUSH PRIVILEGES;,否则不生效
检查 host 匹配是否精确(localhost ≠ 127.0.0.1)
错误信息里写的是 'root'@'localhost',但你实际连接时可能用了 127.0.0.1 —— 在 MySQL 权限系统中,这是两个完全不同的账号,哪怕密码一样也不互通。
- 查当前生效的 root 账号:
SELECT User, Host FROM mysql.user WHERE User = 'root'; - 如果只看到
root@localhost,而你用mysql -h 127.0.0.1 -u root -p连,就会失败 - 补一个
root@127.0.0.1:CREATE USER 'root'@'127.0.0.1' IDENTIFIED WITH mysql_native_password BY '同上密码'; GRANT ALL PRIVILEGES ON *.* TO 'root'@'127.0.0.1' WITH GRANT OPTION; - 注意:macOS 上用
localhost默认走 socket,用127.0.0.1才走 TCP,行为差异极易被忽略
重启服务并验证连接方式
退出 MySQL,关掉带 --skip-grant-tables 的进程(sudo kill $(cat /var/run/mysqld/mysqld.pid) 或直接 killall mysqld),再正常启动服务。
- Ubuntu/Debian:
sudo systemctl start mysql - CentOS/RHEL:
sudo systemctl start mysqld - 验证方式要分场景:
– 用 socket(推荐):mysql -u root -p(不加-h)
– 用 TCP:mysql -h 127.0.0.1 -u root -p(必须确保root@127.0.0.1存在)
– 远程连接?先确认bind-address是否放开、防火墙是否放行 3306、用户Host是否设为%或具体 IP
最常被卡住的地方不是密码,而是你以为连的是 localhost,实际连了 127.0.0.1,而权限表里只有一边。务必用 SELECT USER(); 确认当前会话到底以哪个 User@Host 身份登录。

















