flush privileges并非必须执行,grant等标准语句在mysql 5.7+中自动同步磁盘与内存权限;仅在直接update mysql.user等系统表后才需执行,且旧连接须重连、账号host匹配、实例确认才能生效。

FLUSH PRIVILEGES 不是必须执行的——绝大多数情况下,加了反而暴露你没搞清权限生效逻辑。
GRANT 本身已同步磁盘与内存,无需手动刷新
MySQL 5.7 及以后(含 8.0+),所有标准权限语句(GRANT、REVOKE、CREATE USER)在执行成功后:
- 立即写入
mysql.user等系统表(磁盘持久化) - 同时更新内存中的权限结构(如
acl_users数组) - 新连接建立时直接读取最新内存快照,权限立刻可用
你看到的“不加 FLUSH PRIVILEGES 就不生效”,大概率是因为:
- 当前连接仍挂着旧权限上下文,没
QUIT重连 - 授权账号写错了 host(比如
'u'@'localhost'和'u'@'127.0.0.1'是两个账号) - 客户端连的是另一个 MySQL 实例(Docker、Homebrew、系统自带混用)
哪些情况才真需要 FLUSH PRIVILEGES?
它只在绕过 SQL 权限接口、直接操作系统表时才起作用:
- 用
UPDATE mysql.user SET Select_priv = 'Y'手动改权限字段 - 用
mysqldump导入权限表后没走GRANT流程 - 脚本批量
INSERT INTO mysql.db插入库级权限
注意:MySQL 8.0+ 中直接 UPDATE mysql.user 极易出错(authentication_string 格式、插件校验失败),FLUSH PRIVILEGES 也无法修复数据不一致。
权限不是“全局实时生效”,而是按粒度分层加载
即使你确认 GRANT 成功、也执行了 FLUSH PRIVILEGES,权限仍不会对所有操作立即起效:
- 全局权限(
ON <em>.</em>):仅对新连接生效,当前会话QUIT后重连才可用 - 数据库级权限(
ON db.*):当前连接需先执行USE db才触发检查 - 表级权限(
ON db.t):下一次访问该表(如SELECT * FROM t)即校验,无需重连或USE
别光看 SHOW GRANTS FOR 'u'@'h' 返回了什么——得真跑一句语句验证。
最常卡住的地方,从来不是命令敲得对不对,而是你以为权限已加载,其实连接还连着旧上下文,或者压根连错了实例。











