flush privileges 是修改 mysql 权限表后必须执行的轻量操作,用于重载内存权限;直接 dml 修改 mysql 库权限表需手动刷新,而 grant/revoke 或 alter user 等命令自动生效。

修改 MySQL 用户权限后 FLUSH PRIVILEGES 就够了,不用重启服务
MySQL 的权限系统是运行时加载的:服务启动时读一次权限表到内存,后续所有权限检查都走内存副本。所以改完 mysql.user、mysql.db 等表后,必须通知 mysqld 重新加载——但不是靠重启,而是执行 FLUSH PRIVILEGES。
常见错误现象:
– 用户刚用 UPDATE mysql.user SET authentication_string = ... 改了密码,却仍连不上
– 用 GRANT 添加了新权限,但应用报 Access denied
– 手动 INSERT 权限记录后,SHOW GRANTS FOR 'u'@'h' 不显示新项
- 只要权限表(
mysql.user、mysql.db、mysql.tables_priv等)被直接 DML 修改,就必须FLUSH PRIVILEGES - 用
GRANT/REVOKE命令修改,MySQL 自动刷新内存权限,无需手动FLUSH -
FLUSH PRIVILEGES是轻量操作,毫秒级,不影响连接或查询 - 如果权限改了但没生效,先确认是否漏了
FLUSH,而不是怀疑配置或网络
哪些权限变更必须 FLUSH PRIVILEGES?
不是所有修改都需要——关键看是否绕过了权限管理接口。直接写表就是“绕过”,GRANT 就是“走正门”。
- 手动
UPDATE/INSERT/DELETEmysql库下的权限表 → 必须FLUSH PRIVILEGES - 用
ALTER USER改密码或认证插件 → 自动生效,不需FLUSH - 用
CREATE USER或DROP USER→ 自动生效 - 修改
max_connections这类全局变量 → 需SET GLOBAL或改配置文件 + 重启,和权限无关
FLUSH PRIVILEGES 失败的典型原因
命令本身很简单,但失败往往暴露更底层的问题。
- 执行用户没有
RELOAD权限 → 报错ERROR 1227 (42000): Access denied; you need (at least one of) the RELOAD privilege(s) for this operation - 在只读实例(如从库)上执行 → 报错
ERROR 1290 (HY000): The MySQL server is running with the --read-only option so it cannot execute this statement - 权限表损坏或字符集不一致(比如
mysql.user表用了 utf8mb4,但客户端连接用 latin1)→ 可能导致FLUSH后权限加载异常,表现为部分用户权限丢失
权限生效延迟的隐藏因素:连接复用与缓存
即使 FLUSH PRIVILEGES 成功,你可能还会遇到“权限改了但旧连接没变”的情况——这不是 MySQL 没生效,而是连接本身的上下文没更新。
- 已建立的连接在登录那一刻就锁定了其权限快照,后续不会动态刷新
- 应用层连接池(如 HikariCP、PooledMySQLConnection)里的空闲连接,仍持有旧权限,直到被复用或关闭
- 解决方法只有两个:
KILL掉对应连接,或等它自然断开重连;不能指望“等几秒就自动同步” - 测试权限变更是否真正起效,务必用新连接验证,例如新开一个
mysql -u testuser -p终端
最常被忽略的一点:权限改的是“谁在什么 host 上能做什么”,但实际匹配时,MySQL 会按 user@host 字符串逐行查表,'user'@'127.0.0.1' 和 'user'@'localhost' 完全是两个账户——连 FLUSH 都救不了配错 host 的情况。











