首页/数据/数据库速查/连接报错 1045 Access denied 排错

连接报错 1045 Access denied 排错

认证或授权失败:账号不存在、来源主机不匹配、密码错误或账号被锁定。核心是先把「用户名@来源主机」这个完整身份对齐。

数据库速查数据更新于 2026-10-13

1045 是什么

ERROR 1045 (28000) Access denied 属于认证阶段的拒绝:TCP 已经连通、握手也完成了,服务端在核对账号身份时把这次登录挡了回来。MySQL 的账号身份由「用户名 + 来源主机」两部分组成,服务端从 mysql.user 里按 host 匹配出一条记录,再依次校验口令、认证插件、账号是否被锁以及失败次数。所以看到 1045 该先怀疑身份组合对不对,而不是服务器是否还活着。

基本信息

错误码ERROR 1045 (28000) Access denied
触发阶段连接已建立,认证校验中
完整身份用户名@来源主机,两部分都要对上
常见原因账号不存在、来源不匹配、口令错、插件不兼容、账号被锁
首要命令SELECT user,host,plugin,account_locked FROM mysql.user
适用版本MySQL 5.7 / 8.0,MariaDB 文案基本一致

典型使用场景

  • 新服务上线连不上库:应用来自 10.0.x 网段,却只建了 'app'@'localhost' 这条记录
  • 刚改过口令的应用仍报 1045:连接池里缓存着旧凭证,重连时被服务端拒绝
  • 5.7 升到 8.0 后旧客户端登录失败:默认认证插件变成 caching_sha2_password,老驱动不认识
  • 接入云数据库:控制台建了账号但没配来源网段,白名单之外的来源一律 1045
  • 账号因连续输错口令被临时锁定,处置前需要先 UNLOCK 解封
  • 区分认证失败与授权不足:1045 表示没通过登录,1044、1142 才是登录后权限不够

定位完整身份

定位完整身份
mysql -uapp -p -h 10.0.0.5 -P 3306   # 用应用真实来源复现,记下报错里的 user@host
mysql -uroot -p -e "SELECT user,host,plugin,account_locked FROM mysql.user WHERE user='app';"   # 看有几个同名账号
mysql -uroot -p -e "SHOW VARIABLES LIKE 'skip_name_resolve';"   # 开启后 host 必须写 IP,写域名对不上
mysql -uapp -p -h 10.0.0.5 -D appdb -e "SELECT CURRENT_USER(), USER();"   # 用成功登录的账号看实际命中身份

报错文案对照

报错片段含义处置方向
using password: NO客户端根本没带口令检查 -p 的交互输入、选项文件与连接池里的密码配置
using password: YES带了口令但校验失败按命中的那条账号记录改密,或纠正来源网段
Host ... is not allowed to connect没有任何 host 记录匹配来源按来源网段建账号,例如 'app'@'10.0.%'
Authentication plugin ... cannot be loaded客户端太老,不认识服务端插件升级驱动,或把该账号改为 mysql_native_password
Account is locked失败次数达到阈值被锁定用 UNLOCK USER 解封,并排查是谁在不停重试
Can't connect to local MySQL server与 1045 无关,属连接层问题按 2003 的思路先查服务状态与端口监听

修复与验证

修复与验证
CREATE USER 'app'@'10.0.%' IDENTIFIED BY 'Str0ng#Pass!';   # 按来源网段建账号,比 % 更可控
ALTER USER 'app'@'10.0.%' IDENTIFIED WITH mysql_native_password BY 'Str0ng#Pass!';   # 老客户端兼容,按需使用
UNLOCK USER 'app'@'10.0.%';   # 失败次数锁定后的解封手段
FLUSH PRIVILEGES;   # 只有直接改授权表才需要,CREATE/ALTER USER 会自动落盘
SELECT user,host,plugin,account_locked FROM mysql.user WHERE user='app';   # 改完立即核对结果
host 匹配不是简单字符串相等:更具体的取值(某个 IP、10.0.%)优先于 %,% 也不匹配空主机名;localhost 走本地 socket、127.0.0.1 走 TCP,这两条路的账号记录互相独立,改了一条不等于两条都改到。
云数据库的账号与白名单通常在控制台维护,mysql.user 只能读不能改,遇到 1045 先去核对控制台里的账号来源网段与访问白名单,再回来查服务端参数。
不要为了绕开 1045 就用 --skip-grant-tables 启动实例,那等于对整片内网开放无口令管理入口;确需重置口令时必须限制来源,处置完立刻恢复正常授权并重启。
建议固定排查顺序:先用应用账号从真实来源复现、拿到完整 user@host,再核对服务端存在哪几条同名记录,最后才动授权或口令。顺序颠倒容易出现改完仍报错、也说不清改了什么的情况。

易错点

  • 把认证失败当成服务故障去重启 mysqld:连接池会用同样的旧凭证重连并继续报错,只会放大抖动,先看清 user@host 再动手
  • 直接 UPDATE 或 DELETE mysql.user 却忘了 FLUSH PRIVILEGES:改动不生效,或者反过来把自己锁在门外,只能靠跳过授权表恢复
  • 只按用户名查账号、忽略 host 列:给 'app'@'%' 改了口令,本地应用仍命中 'app'@'localhost' 而继续失败
  • 用 ALTER USER ... IDENTIFIED WITH 换插件时漏写 BY '新口令':口令被清空,依赖该账号的应用会同时登录失败
  • 为兼容老客户端把全库账号批量降级成 mysql_native_password:长期运行在弱哈希上,应逐个确认客户端能力后再按需调整
  • 多个应用共用同一个账号且不区分来源:出问题时无法判断是谁在重试或撞锁,建议按应用拆分账号并各自限制来源网段

数据来源与参考

  • MySQL 8.0 Reference Manual: Access Denied Errors

相关工具

​‌‌​​‌​​​‌‌​‌‌‌‌​‌‌​​​‌‌​‌‌‌​​‌‌​​‌​‌‌‌​​‌‌‌​​​‌​‌‌​‌​​‌​‌‌‌​​​‌​‌‌​‌​​‌​‌‌​​​‌‌​‌‌‌​‌​​​‌‌​‌‌‌‌​​‌​‌‌‌​​‌‌​​​‌‌​‌‌​‌‌‌‌​‌‌​‌‌​‌