access denied for user 'root'@'localhost' 或 '%' 主因是权限匹配失败而非密码错误,需先查 mysql.user 表确认 root 账号是否存在及 host 匹配是否准确,再按需跳过验证创建账号或补授库级权限。

报错 Access denied for user 'root'@'localhost' 或 'root'@'%',绝大多数情况跟密码无关,而是权限匹配失败——MySQL 没找到符合「用户名 + 来源主机 + 数据库」三元组的授权记录。
查不到 root@'localhost' 这个账号就别试密码了
执行 SELECT User, Host FROM mysql.user WHERE User = 'root';,如果结果里根本没有 root 行,说明这个账号压根没被创建过。MySQL 初始化时可能只建了 root@'127.0.0.1' 或根本没建 root 账号(尤其 Docker 镜像、一键安装包常见)。这时候输再多次密码也没用。
解决办法是:先用 mysqld_safe --skip-grant-tables 启动跳过权限验证,然后手动插入或创建:
CREATE USER 'root'@'localhost' IDENTIFIED BY 'your_password';<br>GRANT ALL PRIVILEGES ON *.* TO 'root'@'localhost' WITH GRANT OPTION;<br>FLUSH PRIVILEGES;
- 不要直接改
mysql.user表,容易破坏认证插件字段(尤其是 MySQL 8.0+ 的authentication_string) - 如果只看到
root@'127.0.0.1',但你用localhost连,注意:MySQL 会优先尝试 Unix socket,不走 TCP,所以localhost和127.0.0.1在权限匹配上是两个 host
root@'%' 存在但连不上新库,是库级权限没给
你执行 CREATE DATABASE myapp; 成功了,但立刻 USE myapp; 就报 Access denied for user 'root'@'%' to database 'myapp'?这不是连接问题,是 MySQL 8.0+ 默认不自动授库级权限。即使 root@'%' 有全局 ALL PRIVILEGES,也得显式执行一次 GRANT 才能在 information_schema 查询中通过校验(GUI 工具如 DBeaver 切库时就会触发)。
使用tbot机器ID身份文件配合tsh CLI,通过Teleport访问控制SSH登录托管主机或执行远程命令。
运行这条即可:
GRANT USAGE ON `myapp`.* TO 'root'@'%';<br>FLUSH PRIVILEGES;
-
USAGE是最小权限,只允许“连接到该库”,够 GUI 工具初始化用;需要读写再加SELECT, INSERT... - 别漏掉反引号,库名含特殊字符或数字开头时必须包裹
- MySQL 5.7 不强制要求这步,但 8.0+ 及 MariaDB 10.5+ 默认启用更细粒度检查
连的是 root@'%' 却提示 localhost,说明 host 匹配错了
客户端显示连接的是 root@'localhost',但你实际是从远程 IP 连的,或者用了 127.0.0.1 —— 这说明 MySQL 服务端的 bind-address 配置或客户端解析出了偏差。重点检查:
-
my.cnf里的bind-address = 127.0.0.1(只监听本地),改成0.0.0.0或具体内网 IP 才能接受远程连接 - 客户端连的时候写的是
localhost,但 MySQL 认为这是 socket 连接,不会查root@'%',只会查root@'localhost';想走 TCP 就必须显式写127.0.0.1 -
SELECT USER(), CURRENT_USER();对比两个值:前者是客户端声明的用户,后者是 MySQL 实际匹配到的账号,不一致就说明 host 匹配失败
真正卡住人的地方,往往不是密码输错,而是 root@'localhost' 和 root@'%' 被当成两个独立账号处理,且 MySQL 8.0+ 对新库默认不继承任何权限。动手前先 SELECT User, Host FROM mysql.user 看清现状,比反复重置密码快得多。










