根本原因是连接未匹配授权账号或未重连,而非缓存未刷新;'u'@'localhost'与'u'@'127.0.0.1'是两个独立账号,权限检查只在连接建立时生效,旧连接需QUIT后重新登录才应用新权限。

FLUSH PRIVILEGES执行成功但权限没变,根本不是缓存问题
命令返回 Query OK 只说明内存权限结构被重载了,不代表你当前连接正在用刚授权的账号。MySQL 权限检查只发生在连接建立那一刻,已有连接的权限快照已固化,FLUSH PRIVILEGES 不会动态更新它。真正起作用的是退出后重连——比如在客户端执行 QUIT;,再用 mysql -u u -p -h 127.0.0.1 新建连接。
'u'@'localhost' 和 'u'@'127.0.0.1' 是两个完全不同的账号
这是最常踩的坑:MySQL 把它们当作独立账户处理,权限记录互不影响。
-
'u'@'localhost'默认走 Unix socket(除非显式禁用),而多数 GUI 工具(Navicat、DBeaver)或命令行填-h 127.0.0.1时走 TCP/IP,匹配的是'u'@'127.0.0.1' - IPv6 的
::1同样需要单独授权,%不覆盖它 - 验证实际匹配账号:执行
SELECT USER(), CURRENT_USER();——前者是你“声称的身份”,后者才是 MySQL 实际查到并应用权限的那行记录
直接 UPDATE mysql.user 后 FLUSH 仍失败,大概率是字段写错了
MySQL 8.0+ 对 authentication_string 和 plugin 字段强校验,手动写入极易出错:
- 填了明文密码或 MD5 哈希,但插件是
caching_sha2_password,必须用 SHA2('pwd',256) - 改了
authentication_string却漏掉plugin字段,导致认证插件与密码格式不匹配 - 误删或清空
password_last_changed,触发静默锁定(account_locked='Y'也可能被忽略) -
FLUSH PRIVILEGES不校验合法性,只负责加载;非法值加载后反而让账号彻底不可用
GRANT 后加 FLUSH PRIVILEGES 是冗余操作,还可能误导排查方向
从 MySQL 5.7.6 起,GRANT、REVOKE、ALTER USER 等语句都会自动同步磁盘与内存,加 FLUSH PRIVILEGES 不报错但纯属多余。如果你发现“加了才生效”,大概率是因为顺手重连了——真正生效的是重连,不是刷新。
- 高并发下频繁执行
FLUSH PRIVILEGES会触发全局锁,短暂阻塞新连接认证,有雪崩风险 - 云数据库(如阿里云 RDS)通常禁用该命令,直接报
ERROR 1227 (42501) - 脚本中写
mysql -e "GRANT ...; FLUSH PRIVILEGES;",建议删掉后半句


















