ERROR 1045本质是'mysql.user'表中缺失'root'@'localhost'记录或plugin不兼容,需执行SELECT host,user,authentication_string,plugin FROM mysql.user WHERE user='root'确认存在性及插件类型。
ERROR 1045 的本质不是“密码错了”,而是 MySQL 在 mysql.user 表里根本没找到匹配的 'root'@'localhost' 这条记录。很多安装方式(尤其是 Docker 镜像、一键脚本、MySQL 8.0+ 默认安装)压根不创建它,只留 'root'@'127.0.0.1' 或 'root'@'%'。
如果你还能用其他账号(比如有 sudo 权限的系统用户)进 MySQL,立刻执行:
SELECT host, user, authentication_string, plugin FROM mysql.user WHERE user = 'root';
若结果为空,或只有 host 是 '%' 或 '127.0.0.1',那 'root'@'localhost' 就不存在——socket 连接(即不加 -h 或用 -h localhost)会直接失败。
mysql -u root -p 登录失败,但 mysql -u root -h 127.0.0.1 -p 成功 → 典型缺失 localhost 记录mysql -u root -h localhost -p --protocol=tcp 能进 → 说明 socket 连接强制走 host='localhost' 匹配,而该行缺失MySQL 8.0+ 默认用 caching_sha2_password 插件,但老客户端(如旧版 Navicat、PHP mysqli、某些 Python 驱动)不支持它,就会报 1045 而不是明确提示插件不兼容。
查当前 root 用户用的插件:
SELECT host, user, plugin FROM mysql.user WHERE user = 'root';
如果 plugin 是 caching_sha2_password,且你用的是旧工具,必须改回 mysql_native_password:
ALTER USER 'root'@'localhost' IDENTIFIED WITH mysql_native_password BY 'your_password';
FLUSH PRIVILEGES;
'root'@'127.0.0.1' 却忘了 'root'@'localhost',问题依旧localhost 在 MySQL 里不等于 127.0.0.1:前者走 Unix socket(Linux/macOS)或 named pipe(Windows),后者走 TCP/IP。两者在 mysql.user 表中是完全独立的记录。
执行这条命令看排序优先级:
SELECT host, user FROM mysql.user ORDER BY host DESC, user;
你会发现 '%' 排最前,'localhost' 排最后——但这只是字符串排序,不影响匹配逻辑。MySQL 实际按「最精确匹配」选行:'localhost' 比 '%' 精确,所以只要存在 'root'@'localhost',它就一定被优先选中。
'root'@'localhost' 后,即使 'root'@'%' 存在,mysql -u root -p 仍会报 1045(因为 socket 强制要求 host=‘localhost’)skip-name-resolve 开启时,localhost 可能被解析成 127.0.0.1,导致意外匹配到另一条记录这是 MySQL 8.0+ 生产环境高频坑:密码含 @、%、# 等 Shell 特殊符号,mysqldump -u root -pYour@Pass%Word 会被 Shell 提前解析,传给 mysqldump 的实际密码已损坏。
验证方法:
mysql -u root -p 输入相同密码能进 → 密码本身正确mysqldump 报错信息里显示 (using password: YES) 但失败 → 很可能被 Shell 截断或替换解决方式只有两个:
mysqldump -u root -p'Your@Pass%Word' database_name
~/.my.cnf),避免密码暴露在命令行别在配置文件里写明文密码后还 chmod 755——权限不对也会触发 1045。