必须执行flush privileges仅当直接修改mysql系统库权限表(如update mysql.user)后;使用create user、grant等标准命令则自动同步,无需且不应执行该命令。

什么时候必须执行 FLUSH PRIVILEGES
只有在**直接修改了 mysql 系统库的权限表(如 user、db、tables_priv 等)后**,才需要手动执行 FLUSH PRIVILEGES。MySQL 服务启动时会将这些表加载进内存缓存,后续权限检查都走内存副本,不实时查表。
换句话说:用 CREATE USER、GRANT、DROP USER 这类 DDL 命令操作权限,MySQL 会自动同步内存缓存——此时 FLUSH PRIVILEGES 完全多余,甚至可能掩盖误操作。
- ✅ 正确场景:用
UPDATE mysql.user SET authentication_string = ... WHERE User = 'foo'改了密码字段 - ❌ 错误场景:刚执行完
GRANT select ON db.* TO 'u'@'%',又补一句FLUSH PRIVILEGES - ⚠️ 风险:如果
UPDATE语句漏掉WHERE或写错条件,FLUSH会让错误权限立刻生效
FLUSH PRIVILEGES 的实际行为和限制
它不是“重载配置”,而是强制 MySQL 丢弃当前内存中的权限缓存,并从磁盘上的 mysql 表重新读取全部数据。这个过程会阻塞所有新连接的权限验证,直到刷新完成(通常很快,但高并发下可感知)。
- 不会触发事务提交:即使你之前用
BEGIN; UPDATE mysql.user ...; COMMIT;,FLUSH仍是必需的(因为权限缓存不参与事务) - 不校验语法或逻辑:如果
user表里存在重复 Host/User 组合、空密码字段、非法 plugin 值,FLUSH仍会加载,但后续登录可能失败 - 对运行中连接无影响:已建立的连接保留原有权限,新连接才用新缓存
替代方案:优先用标准权限语句
95% 的权限管理需求,都应该避开直接改系统表。标准语句更安全、可审计、自动生效:
CREATE USER 'app'@'10.0.2.%' IDENTIFIED WITH caching_sha2_password BY 'pwd123'; GRANT SELECT, INSERT ON sales.* TO 'app'@'10.0.2.%'; ALTER USER 'app'@'10.0.2.%' REQUIRE ssl;
这些命令内部做了三件事:更新磁盘表 + 更新内存缓存 + 记录到二进制日志(如果开启)。不需要、也不应该加 FLUSH PRIVILEGES。
- 修改密码统一用
ALTER USER ... IDENTIFIED BY,别碰authentication_string - 删用户用
DROP USER,别只delete FROM mysql.user - 要批量授权?写脚本生成
GRANT语句,而不是拼INSERT INTO mysql.db
调试权限问题时,别盲目刷缓存
遇到“明明 GRANT 了却不生效”,先确认根本原因,而不是第一反应 FLUSH PRIVILEGES:
- 检查是否连错了实例:
SELECT @@hostname, @@port; - 确认用户匹配逻辑:
SELECT User, Host FROM mysql.user WHERE User = 'u';—— 注意'u'@'localhost'和'u'@'127.0.0.1'是不同账户 - 验证当前连接用的哪个账户:
SELECT USER(), CURRENT_USER();(前者是客户端声明的,后者是服务器认证后的) - 查看具体权限:
SHOW GRANTS for 'u'@'h';,不是看mysql.user表字段
直接改系统表+刷缓存,相当于绕过 MySQL 的权限抽象层,容易让状态变得不可预测。真正棘手的权限问题,往往出在 Host 匹配、SSL 要求、角色激活或代理用户配置上,而不是缓存没刷新。