FLUSH PRIVILEGES 到底干了什么?
它不是“让权限生效”的万能开关,而是强制 MySQL 从磁盘重新读取
mysql.user、
mysql.db、
mysql.tables_priv等权限表,并完全覆盖内存中缓存的 ACL(访问控制列表)——相当于把权限缓存“重装一遍”。这个过程不重启服务,但只影响后续新建的连接;已存在的连接仍按旧权限运行,必须重新登录才感知变更。
什么时候必须执行 FLUSH PRIVILEGES?
仅在你绕过标准语法、直接用 DML 操作系统表时才需要。比如:
UPDATE mysql.user SET authentication_string = PASSWORD('newpass') WHERE User = 'test'; → 必须跟 FLUSH PRIVILEGES;
INSERT INTO mysql.db ...或
DELETE FROM mysql.proxies_priv→ 同样必须刷新 用文本编辑器或工具直接改了
mysql库的 .ibd 文件(极不推荐)→ 也得靠它通知 MySQL 重载
反之,用
CREATE USER、
GRANT、
REVOKE、
ALTER USER等语句修改权限或密码时,MySQL 自动同步磁盘+内存,执行
FLUSH PRIVILEGES不但多余,还可能掩盖语法错误。
为什么有时候刷了也不生效?常见踩坑点
很多人一遇到权限不生效就下意识
FLUSH PRIVILEGES,结果白忙活甚至引发事故: host 匹配失败:比如
GRANT ... TO 'u'@'localhost',但客户端用
127.0.0.1连——这是两个不同 host,和刷不刷无关 权限表改错了:手误清空
authentication_string或写错
Host字段,一刷就立刻锁死 root 登录 主从不一致:在从库上直接改
mysql表再
FLUSH,导致主从权限分裂,复制可能报错 没检查当前会话视角:用
SHOW GRANTS;看的是当前连接的权限快照,不是全局最新状态;应配合
CURRENT_USER()确认实际匹配的用户身份
更安全、更现代的替代方案
直接操作
mysql系统表是最后手段。MySQL 5.7.6+ 起,优先走语义明确、原子安全的标准路径: 建用户:
CREATE USER 'u'@'h' IDENTIFIED BY 'p';赋权:
GRANT SELECT ON db.* TO 'u'@'h';改密:
ALTER USER 'u'@'h' IDENTIFIED BY 'newp';(比
SET PASSWORD更推荐) 回收:
REVOKE INSERT ON db.t FROM 'u'@'h';,而不是
DELETE FROM mysql.user
真正需要
FLUSH PRIVILEGES的场景,越来越少;而一旦要用,就得先确保磁盘上的数据本身是对的——它只是个“重载信号”,不是纠错工具。
