只有直接修改系统权限表时才必须执行FLUSH PRIVILEGES,它强制重载磁盘权限到内存缓存,不刷新则新权限不生效;GRANT/REVOKE操作在MySQL≥8.0.16中无需刷新。
FLUSH PRIVILEGES
只有在**绕过 GRANT/REVOKE 语句、直接修改系统权限表**时,才「必须」执行 FLUSH PRIVILEGES。比如你用 UPDATE mysql.user 改了密码,或手动 INSERT INTO mysql.db 加了库级权限——MySQL 不会自动感知这些变更,内存里的权限缓存仍沿用旧数据,不刷新就永远不生效。
UPDATE mysql.user SET authentication_string = PASSWORD('xxx') WHERE User='u1'; 后不执行 FLUSH PRIVILEGES → 新密码无效GRANT SELECT ON db.* TO 'u1'@'%'; → 权限立即生效,无需额外命令GRANT,也建议加 FLUSH PRIVILEGES,否则可能遇到权限延迟或不一致FLUSH PRIVILEGES 到底做了什么它不是“更新权限”,而是「强制重载」:清空内存中已缓存的全部权限数据(包括 mysql.user、mysql.db、mysql.tables_priv 等 6 张核心表),再从磁盘完整读一遍,重建缓存。整个过程是原子性的全量覆盖,没有增量合并逻辑。
SHOW GRANTS 显示旧结果FLUSH PRIVILEGES;
SHOW GRANTS FOR 'u1'@'%';
重启确实也能让权限生

FLUSH PRIVILEGES 是轻量热操作,毫秒级完成,适合生产环境紧急修复。
mysql 库损坏,FLUSH 会失败并报错(如 ERROR 1036: Table 'user' is read only)GRANT/REVOKE,避免手动改表最常踩的坑不是“忘刷新”,而是“刷了却没效果”,原因往往藏在细节里:
'u1'@'localhost' 和 'u1'@'127.0.0.1' 是两个不同用户,改错 Host 就白刷'u1'@'%' 授了 SELECT 在 db1.*,但程序连的是 db2 → 刷也没用authentication_string 字段内容格式变了,用老版 PASSWORD() 函数更新会导致认证失败,此时刷了也登不进FLUSH PRIVILEGES 不解决网络层拦截:防火墙、skip-networking、bind-address 限制等,和权限刷新完全无关MySQL 权限生效本质是「磁盘定义 → 内存缓存 → 连接时校验」三步链路,FLUSH PRIVILEGES 只管中间那一步。真要排查权限异常,先确认改的是哪个表、哪个用户、哪个 host、哪个 MySQL 版本,再决定要不要刷、怎么刷、刷完怎么验。