grant/revoke后权限自动生效,无需flush privileges或重启;问题多因旧连接未重连、'u'@'localhost'与'u'@'127.0.0.1'账号不匹配、caching_sha2_password插件兼容性差,或表级/库级/全局权限生效时机不同所致。

GRANT/REVOKE 之后绝大多数情况根本不用重启服务,也不需要 FLUSH PRIVILEGES —— 权限已自动生效,问题往往出在连接、匹配或粒度上。
为什么刚执行 GRANT 却连不上或查不了?
权限不是“写完就全局可用”,它受连接生命周期和作用域限制:
- 已存在的连接不会动态更新权限:哪怕你刚给
'app'@'%'加了SELECT ON sales.*,该连接后续仍按旧权限运行,必须QUIT后重连 -
'u'@'localhost'和'u'@'127.0.0.1'是两个独立账号:前者走 Unix socket,后者走 TCP/IP;授权漏掉任一 Host,就会报Access denied - MySQL 8.0+ 默认插件是
caching_sha2_password,老客户端(如 MySQLdb、旧版 Navicat)可能静默降级失败——看似连上了,实则权限校验被跳过
哪些权限变更对当前连接“热生效”?
生效时机取决于权限粒度,不是统一刷新:
- 表级权限(如
GRANT SELECT ON db.t1 TO 'u'@'h'):下一条SELECT就生效 - 库级权限(如
GRANT SELECT ON db.* TO 'u'@'h'):下次执行USE db后才生效(注意:部分版本实测为即时生效,但不能依赖) - 全局权限(如
GRANT SUPER ON *.* TO 'u'@'h'):只对新连接生效,当前连接即使执行KILL或SET GLOBAL也会报错
什么时候真要执行 FLUSH PRIVILEGES?
仅当绕过 SQL 授权语法、直接操作系统表时才必须用:
- 你写了
UPDATE mysql.user SET Select_priv='Y' WHERE User='u'→ 必须跟FLUSH PRIVILEGES,否则无效果 - 你没
RELOAD权限却执行它 → 报错ERROR 1227 (42000): Access denied; you need (at least one of) the RELOAD privilege(s) - 你在只读实例(
--read-only)或 Group Replication 的非 primary 节点上执行 → 直接报错,不支持
配置修改不重启怎么生效?
配置项分两类:动态可调的用 SET GLOBAL,静态的必须改 my.cnf 并重启:
- 支持动态的常见参数:
max_connections、innodb_buffer_pool_size、wait_timeout,执行SET GLOBAL max_connections = 2048立即生效 - 不支持动态的参数(如
datadir、server_id):改了my.cnf也无效,必须重启;误以为FLUSH PRIVILEGES能 reload 配置是常见误解 - MySQL 8.0.22+ 支持
SET PERSIST持久化动态设置到mysqld-auto.cnf,避免重启后丢失,但不改变“是否需重启”的本质逻辑
最易被忽略的是权限粒度与连接状态的耦合:你改的是 *.* 还是 db.*,决定了要不要重连;你连的是 localhost 还是 127.0.0.1,决定了授没授对人;而 FLUSH PRIVILEGES 在标准流程里,基本就是个“无害但多余”的动作。











