mysql 8.0中flush privileges已非必需,因grant/alter user等操作自8.0.16起自动同步磁盘与内存权限;仅在直接update mysql.user等系统表时才需执行,且不影响已存在连接,新权限须重连生效。

MySQL 8.0 根本没有权限缓存机制——FLUSH PRIVILEGES 在绝大多数场景下已不必要,且无法刷新“权限缓存”,因为压根不存在这个缓存层。
MySQL 8.0 已移除 query cache,权限也不再走缓存路径
5.7 中的 query_cache 是独立模块,影响 SQL 查询结果缓存;但它和权限系统完全无关。真正被误传为“权限缓存”的,其实是 MySQL 内部对用户权限元数据的内存驻留行为:5.7 和 8.0 都会将 mysql.user、mysql.db 等权限表加载进内存并缓存,但实现方式与触发逻辑完全不同。
- 5.7:权限数据加载后长期驻留内存,仅在执行
FLUSH PRIVILEGES或重启时重载,期间即使你直接UPDATE mysql.user,也不会自动生效 - 8.0:权限元数据由新数据字典统一管理,
CREATE USER、GRANT、DROP USER等 DDL 操作**立即持久化并实时生效**,无需额外刷新 - 8.0 中
FLUSH PRIVILEGES仅在极少数异常场景下有用(如手动修改了系统表、或从旧版本迁移后权限表未正确转换),正常授权流程中调用它既无效果,还可能掩盖操作错误
为什么执行 GRANT 后仍连不上?大概率是认证插件或 host 匹配问题
常见现象:在 8.0 执行了 CREATE USER 'u1'@'%' IDENTIFIED BY 'pwd'; GRANT SELECT ON test.* TO 'u1'@'%';,但客户端连接时报 Access denied。这不是权限没刷新,而是以下任一原因:
- 用户创建时用了
'u1'@'localhost',但连接时用的是127.0.0.1(MySQL 视为不同 host) - 客户端不支持
caching_sha2_password插件(如老版 MySQL Workbench、某些 JDBC 驱动),需显式降级:ALTER USER 'u1'@'%' IDENTIFIED WITH mysql_native_password BY 'pwd'; - 未执行
FLUSH PRIVILEGES—— 这个动作在 8.0 下其实无效,但很多人误以为“没刷所以不生效”,实际应检查SELECT user,host,plugin FROM mysql.user WHERE user='u1';
如何验证权限是否真实生效?别依赖 FLUSH,用 SELECT 检查
最可靠的方式是绕过“是否刷新”这个伪命题,直接查权限状态:
- 确认用户存在且 plugin 正确:
SELECT user,host,plugin,authentication_string FROM mysql.user WHERE user='u1'; - 确认权限已分配:
SHOW GRANTS FOR 'u1'@'%';(注意必须带引号和 host,SHOW GRANTS FOR u1会报错) - 模拟连接行为测试:
mysql -uu1 -h127.0.0.1 -p,避免用localhost(Unix socket 路径优先,可能命中另一条 user 记录) - 若仍失败,开 general log:
SET GLOBAL general_log = ON;,看连接时 MySQL 实际匹配的是哪个user@host组合
真正容易被忽略的点是:MySQL 8.0 的权限判断发生在连接建立前的认证阶段,而这个阶段只读取数据字典快照,不依赖任何运行时缓存。所谓“刷新”,本质是确保 DDL 操作成功执行——而不是调用某个魔法命令。











