只有在绕过GRANT/REVOKE、直接修改mysql系统表后才需执行FLUSH PRIVILEGES;正常用GRANT或CREATE USER授权时自动生效,无需且不建议手动刷新。
什么时候必须执行 FLUSH PRIVILEGES
只有在**绕过 grant/revoke 语句、直接修改系统表(如 mysql.user、mysql.db)后**,才需要手动执行 flush privileges。mysql 正常用 grant 或 create user 授权时,权限会自动加载,不需要也不建议额外刷一次。
- 常见误操作场景:用
UPDATE直接改mysql.user表的authentication_string字段重置密码 - 或者用
INSERT INTO mysql.user手动加用户(不推荐) - 用
mysqldump导入权限表、或从其他实例复制mysql库数据后
FLUSH PRIVILEGES 的实际效果和限制
它只是让 mysqld 进程重新读取内存中的权限缓存,并不校验 SQL 语法、不验证账号是否存在、也不触发任何日志或审计动作。它不会解决权限不生效的根本问题——比如你改错了表名、字段名,或者没 FLUSH 到正确的实例(主从架构下只在目标节点执行)。
- 执行后不报错 ≠ 权限已生效;建议立刻用新账号连接测试,而不是依赖返回的
Query OK - 对运行中的连接无效:已建立的会话仍沿用旧权限,新连接才用新规则
- 8.0+ 版本中,
mysql.user表结构变化大,直接写表风险更高,FLUSH PRIVILEGES无法修复字段缺失或类型不匹配
替代方案:优先用 GRANT 而不是刷表
绝大多数授权需求,GRANT 就够了,且更安全、可审计、兼容性好。比如要给用户增删库级权限:
GRANT SELECT, INSERT ON `app_db`.* TO 'api_user'@'10.20.%';
如果权限变更涉及角色、动态列、密码策略等 8.0+ 新特性,GRANT 会自动处理底层存储逻辑,而手改表 + FLUSH 很可能漏掉关联字段(如 password_last_changed、account_locked)。
-
GRANT失败时会明确报错,比如ERROR 1410 (42000): You are not allowed to create a user with GRANT - 想批量授权?用脚本生成
GRANT语句,别拼INSERT语句往mysql库里塞 - 备份恢复权限?用
mysqldump --no-data --databases mysql导出结构,再配合GRANT语句迁移
执行前必须确认的三件事
很多人卡在“明明刷了却不生效”,往往是因为这三点没核对清楚:
- 当前连接的是目标实例:
SELECT @@hostname, @@port;,尤其在 Docker、RDS、主从混用环境下容易连错 - 执行用户有
RELOAD权限:SHOW GRANTS FOR CURRENT_USER;,否则会报ERROR 1227 (42000): Access denied; you need (at least one of) the RELOAD privilege(s) - 没有漏掉
FLUSH后的验证步骤:新开一个终端,用刚授权的账号尝试连接并执行SELECT USER(), CURRENT_USER();,看是否匹配预期 host 和权限上下文
真正难的从来不是执行那条命令,而是判断「该不该刷」以及「刷完到底改对了没有」——这两点没法靠文档覆盖,得靠连接实测和权限上下文比对。

















