error 1045 是 mysql 认证失败错误,核心原因为密码错误或用户 'xxx'@'yyy' 未被授权从该主机连接;需同时匹配用户名与主机名,localhost 与 127.0.0.1 视为不同账号。

MySQL报错 ERROR 1045 (28000): Access denied for user 'xxx'@'yyy' 是什么情况
这是 MySQL 最典型的认证失败错误,核心原因只有两个:密码不对,或者用户账号根本不被允许从当前主机连接。不是配置文件没生效,也不是服务没启动,而是 MySQL 服务器在登录握手阶段就拒绝了这次连接请求。
重点看错误信息里的 'xxx'@'yyy' —— 这不是用户名和 IP 的简单拼接,而是 MySQL 内部定义的「用户身份元组」:user 和 host 必须同时匹配,缺一不可。比如 'admin'@'localhost' 和 'admin'@'127.0.0.1' 在 MySQL 看来是两个完全不同的账号。
为什么用 localhost 连不上,但换成 127.0.0.1 就可以
这是因为 MySQL 对 localhost 有特殊处理:它会强制走 Unix socket 文件(而非 TCP/IP),而 socket 认证只认 'user'@'localhost' 这类 host 为 localhost 的记录;127.0.0.1 则走 TCP,匹配的是 'user'@'127.0.0.1' 或 'user'@'%'。
- 检查当前登录方式:
mysql -u root -p默认用localhost;加-h 127.0.0.1才走 TCP - 确认账号是否存在对应 host:
SELECT User, Host FROM mysql.user WHERE User = 'xxx'; -
'%'通配符不匹配localhost(这是历史设计,不是 bug) - 如果只建了
'xxx'@'%',又想用mysql -u xxx -p直连,得额外加一条'xxx'@'localhost'
重置密码时执行 ALTER USER ... IDENTIFIED BY 没用
常见于跳过权限验证启动(mysqld --skip-grant-tables)后,直接运行 ALTER USER 却发现下次仍登不上。根本原因是:在跳过权限表模式下,MySQL 不加载 mysql.user 表,所有 DML 都不写入磁盘,重启后还原。
正确做法是先用 --skip-grant-tables 启动,然后:
- 连上后立刻执行
FLUSH PRIVILEGES;(强制重载权限表) - 再用
UPDATE mysql.user SET authentication_string = PASSWORD('newpass') WHERE User = 'root' AND Host = 'localhost';(MySQL 5.7+ 用authentication_string字段,不是Password) - 最后必须执行
FLUSH PRIVILEGES;,否则修改不生效 - 退出并正常重启 mysqld(别带
--skip-grant-tables)
新用户创建后还是连不上,检查这三处硬限制
即使 CREATE USER 'a'@'%' IDENTIFIED BY 'p'; 成功,也不代表能连。MySQL 会在多个层级做拦截:
- 网络层:防火墙是否放行 3306 端口(特别是云服务器安全组)
- MySQL 配置层:
bind-address是否设为127.0.0.1(导致只监听本地);应改为0.0.0.0或具体外网 IP - 账号权限层:
GRANT之后没执行FLUSH PRIVILEGES;,或只给了SELECT没给USAGE(后者是连接基础权限)
最稳妥的验证方式:在数据库服务器本机执行 mysql -h 127.0.0.1 -u xxx -p,排除网络和 host 解析干扰。如果本机都连不上,问题一定出在账号定义或密码本身。











