FLUSH PRIVILEGES 仅在直接修改 mysql.user 等系统表后必需,GRANT/REVOKE 会自动同步磁盘与内存,无需执行;权限对新连接生效,旧连接需重连才能应用。

FLUSH PRIVILEGES 不是解决授权后权限不生效的“万能开关”,绝大多数情况下它根本不需要执行——加了也白加,还可能掩盖真正的问题。
GRANT 后到底要不要执行 FLUSH PRIVILEGES
- MySQL 5.7 及以后版本(含 8.0+),只要用的是标准
GRANT或REVOKE语句,权限变更会自动写入系统表并重载内存缓存,无需手动FLUSH PRIVILEGES - 唯一必须执行的场景:你绕过授权语法,直接
UPDATE mysql.user、INSERT INTO mysql.db或用工具批量导入权限表数据 -
FLUSH PRIVILEGES加在GRANT后面语法合法,但属于冗余操作;如果加了它才“看起来生效”,说明你很可能没重连,或账号匹配错了
权限不生效,90% 是连接没断开或账号没匹配上
MySQL 权限检查只发生在连接建立那一刻,已有连接不会动态更新:
- 当前会话仍用旧权限,必须执行
QUIT;后重新登录(比如mysql -u u -p -h 127.0.0.1) -
'u'@'localhost'和'u'@'127.0.0.1'是两个完全不同的账号:前者走 Unix socket,后者走 TCP/IP;授权写错一个字符(比如多空格'u '@'localhost')就查不到 - 使用
SHOW GRANTS FOR 'u'@'h';只能看声明,要验证是否真生效,得实际跑一句SELECT * FROM db.t;看报错
不同粒度权限的生效时机完全不同
别指望“改完就能用”,生效逻辑取决于你授的是哪一级:
- 表级权限(如
GRANT SELECT ON db.t TO 'u'@'h';):下一次对该表发起查询即生效,当前连接内可立即验证 - 数据库级权限(如
GRANT SELECT ON db.* TO 'u'@'h';):执行USE db;后才生效,不用重连 - 全局权限(如
GRANT SELECT ON <em>.</em> TO 'u'@'h';):仅对新连接生效,当前连接无论怎么USE都无效
容易被忽略的底层干扰项
- 检查 MySQL 是否以
--skip-grant-tables启动:这种模式下所有权限校验被跳过,GRANT语句根本不会写入表,刷多少次FLUSH PRIVILEGES都没用 - MySQL 8.0+ 默认认证插件是
caching_sha2_password,老客户端(如旧版 MySQLdb、某些 JDBC 驱动)可能静默降级失败——表现为“连得上但权限不生效” - 升级到 8.0 后若没运行
mysqld --upgrade=FORCE,mysql.user表结构可能缺失authentication_string字段,导致GRANT实际没写进底层
最常卡住的地方不是命令没敲对,而是你以为权限已加载,其实连接还挂着旧上下文,或者压根连错了实例。


















