彻底解决 MySQL 报错 ERROR 1045 (28000): Access denied for user
详细排查并彻底解决 MySQL ERROR 1045 (28000): Access denied for user 访问被拒绝错误,包含密码重置、主机授权与权限刷新步骤。
在使用 MySQL 命令行、Navicat、DBeaver 或后端程序连接 MySQL 数据库时,最常遇到的权限报错就是 ERROR 1045 (28000):
ERROR 1045 (28000): Access denied for user 'root'@'localhost' (using password: YES)或者:
ERROR 1045 (28000): Access denied for user 'root'@'localhost' (using password: NO)本文将详细分析导致该错误的 4 种核心原因,并给出在 Windows 和 Linux/macOS 环境下的快速排查与终极修复方案。
错误原因深度剖析
ERROR 1045 本质是 MySQL 服务器在握手认证阶段拒绝了客户端的连接请求。错误提示中的关键信息包括:
user: 登录时使用的用户名。host: 客户端发起的 IP 或主机来源(例如localhost、127.0.0.1或局域网 IP)。using password:YES表示你输入了密码但密码不匹配;NO表示未提供密码。
常见诱因:
- 密码输入错误:包含密码包含特殊字符被 Shell 转义、大小写混淆或初始随机密码未正确更新。
- 主机限制(Host 不匹配):MySQL 用户是由
用户名@主机唯一定义的。例如root@localhost允许本机登录,但不允许来自远程 IP 或 Docker 宿主机的连接。 - 认证插件(Authentication Plugin)不兼容:MySQL 8.0 默认使用
caching_sha2_password插件,而旧版客户端仅支持mysql_native_password。 - 权限未刷新:通过直接修改
mysql.user表而非GRANT语句赋予权限,未执行FLUSH PRIVILEGES;。
解决方案一:通过安全模式跳过授权表重置密码
如果你完全忘记了 root 密码,可以通过跳过权限表(--skip-grant-tables)方式重置。
步骤 1:停止 MySQL 服务
在 Linux 系统执行:
sudo systemctl stop mysql
# 或 CentOS / Rocky Linux:
sudo systemctl stop mysqld
在 Windows 系统执行(以管理员权限打开 CMD):
net stop mysql
步骤 2:以安全模式启动 MySQL
在 Linux 终端执行:
sudo mysqld_safe --skip-grant-tables --skip-networking &
在 Windows 终端执行:
mysqld --console --skip-grant-tables --shared-memory
[!NOTE] 添加
--skip-networking参数可以禁止网络远程连接,确保在免密维护期间外部流量无法入侵。
步骤 3:免密登录并修改密码
新打开一个终端窗口,直接输入 mysql 登录:
mysql -u root
成功进入 MySQL 交互式控制台后,根据你的 MySQL 版本执行重置语句:
对于 MySQL 8.0 及以上版本:
FLUSH PRIVILEGES;
-- 将密码重置为您自己的强密码
ALTER USER 'root'@'localhost' IDENTIFIED WITH mysql_native_password BY 'YourNewPassword123!';
FLUSH PRIVILEGES;
[!TIP] 如果你的客户端驱动较新,推荐保留默认的
caching_sha2_password:ALTER USER 'root'@'localhost' IDENTIFIED BY 'YourNewPassword123!';
对于 MySQL 5.7 版本:
FLUSH PRIVILEGES;
ALTER USER 'root'@'localhost' IDENTIFIED BY 'YourNewPassword123!';
FLUSH PRIVILEGES;
步骤 4:重启 MySQL 恢复正常认证
退出 MySQL 客户端并杀掉安全模式进程:
exit;
在 Linux 上重启服务:
sudo pkill mysqld
sudo systemctl start mysql
在 Windows 上重启服务:
net start mysql
现在使用新密码登录即可正常进入:
mysql -u root -p
解决方案二:排查远程连接与 Host 授权
如果你可以在服务器本地通过 localhost 登录,但使用 Navicat、DBeaver 等客户端在另一台机器连接时提示 ERROR 1045,则是由于用户缺少远程主机连接权限。
步骤 1:检查现有用户的 Host 列表
登录到 MySQL 命令行,查询 mysql.user 表:
SELECT user, host, plugin FROM mysql.user;
输出示例:
+------------------+-----------+-----------------------+
| user | host | plugin |
+------------------+-----------+-----------------------+
| root | localhost | caching_sha2_password |
| mysql.infoschema | localhost | caching_sha2_password |
| mysql.session | localhost | caching_sha2_password |
+------------------+-----------+-----------------------+可以看到 root 仅允许从 localhost 登录。
步骤 2:修改 Host 允许任意主机或特定局域网
执行以下命令允许 root 从任意 IP 地址访问:
-- 方式 A: 修改已有 root 的 host 为 %
UPDATE mysql.user SET host = '%' WHERE user = 'root' AND host = 'localhost';
-- 方式 B: 或者新建一个专门供远程访问的专用管理员账号(更安全)
CREATE USER 'admin'@'%' IDENTIFIED BY 'YourStrongPassword123!';
GRANT ALL PRIVILEGES ON *.* TO 'admin'@'%' WITH GRANT OPTION;
-- 必须刷新权限生效
FLUSH PRIVILEGES;
解决方案三:解决客户端与 MySQL 8.0 认证插件不兼容
若连接时报错附带 Client does not support authentication protocol requested by server,说明连接工具(如老版本 Navicat、旧版 JDBC 驱动或 Node.js mysql 包)不支持 MySQL 8.0 的 caching_sha2_password 算法。
只需将该用户的认证插件切换为兼容模式 mysql_native_password:
ALTER USER 'root'@'%' IDENTIFIED WITH mysql_native_password BY 'YourNewPassword123!';
FLUSH PRIVILEGES;
总结与生产环境避坑指南
- 避免在生产环境中将
root的 host 设为%:建议针对应用创建独立账号(如app_user),并限制其只对业务数据库具备读写权限。 - 每次修改
mysql.user表必须执行FLUSH PRIVILEGES;:通过ALTER USER或GRANT语句修改会自动刷新,但直接执行UPDATE时必须手动刷新。 - 密码包含特殊字符的终端转义:在 Linux 终端执行
mysql -u root -p'P@ss!123'时,!会被 Bash 解释为历史扩展命令,导致密码错乱。建议直接使用mysql -u root -p,回车后在隐蔽提示下键入密码。