mysql权限突然失效主因是'user'@'host'组合不匹配,需用select user(), current_user()确认实际匹配账户,检查mysql.user表中host字段是否与客户端真实ip或解析结果完全一致,避免依赖dns主机名授权。

MySQL权限报错不是随机的,而是因为 'user'@'host' 组合不匹配——同一用户名从不同主机连接,会被视为完全不同的账户,权限互不影响。
为什么用主机名连接时权限突然失效?
Linux 服务器默认不解析 Windows 主机名(如 DESKTOP-ABC123),MySQL 在认证阶段拿到的是客户端真实 IP 或未解析的主机名,和 mysql.user 表中记录的 Host 值对不上。
- 你在
GRANT ... TO 'app'@'DESKTOP-ABC123'授了权,但客户端实际连上来时 MySQL 看到的是'app'@'192.168.1.100'(或'app'@'localhost') -
SELECT User, Host FROM mysql.user显示的Host字段必须**字面完全一致**才匹配,不支持模糊或 DNS 反查自动转换 - Windows 的
hosts文件只影响本机解析,不影响 MySQL 服务端如何识别客户端来源
怎么确认当前连接被识别成哪个 'user'@'host'?
在已成功登录的会话里执行:
SELECT USER(), CURRENT_USER();
USER() 返回你「声称」的身份(含客户端传来的主机名),CURRENT_USER() 才是 MySQL 实际匹配并用于权限检查的账户。两者不一致,就是主机名没对上。
- 如果
USER()是'app'@'DESKTOP-ABC123',但CURRENT_USER()是'app'@'%',说明 MySQL 没找到精确匹配,退而使用通配符规则 - 如果
CURRENT_USER()是'app'@'localhost',哪怕你用 IP 连,也说明 MySQL 认为你是从本地 socket 连入(常见于 Linux 上用127.0.0.1和localhost的区别)
GRANT 时该用 IP、% 还是具体主机名?
优先级:**IP 地址 > 具体主机名 > %**,但生产环境应避免无脑用 %。
- 明确知道客户端固定 IP(如应用服务器):用
'app'@'10.0.2.5'—— 最安全,权限最小化 - 客户端 IP 动态但可控(如内网 DHCP 段):用子网掩码形式,如
'app'@'10.0.2.%'(注意:MySQL 不支持 CIDR,%只能匹配单段) - 测试或开发环境需快速放行:用
'app'@'%',但务必配合防火墙限制可访问源 IP 范围 - 绝对不要用
'app'@'hostname.local'之类依赖 DNS 解析的写法——DNS 故障或延迟会导致权限瞬间失效
刷新权限后还是不生效?重点检查这三处
FLUSH PRIVILEGES 不是万能的,很多问题出在缓存或配置层面:
- MySQL 8.0+ 用户权限变更后,
FLUSH PRIVILEGES已非必需(GRANT自动持久化),但旧版本仍需;若不确定版本,执行它没坏处 - 客户端驱动可能复用连接池,旧连接仍带着旧权限上下文,重启应用或连接池更可靠
- 某些中间件(如 ProxySQL、MaxScale)会缓存用户权限映射,需单独刷新其元数据
真正容易被忽略的是:MySQL 启动时加载的 my.cnf 中若设置了 skip-name-resolve,它会跳过反向 DNS 查询,所有远程连接统一记为 IP 地址——此时你在 mysql.user 里写的主机名权限全无效,只能靠 IP 或 % 匹配。











