GRANT后执行FLUSH PRIVILEGES是多余的,因标准语句(如GRANT、ALTER USER)自5.7.6起已自动同步磁盘与内存权限缓存,8.0.16+更彻底消除延迟;仅当直接DML修改mysql系统表时才需该命令。

GRANT之后执行FLUSH PRIVILEGES是多余的
绝大多数情况下,GRANT、REVOKE、CREATE USER、ALTER USER 这类标准语句执行完就立刻生效,不需要也不应该加 FLUSH PRIVILEGES。MySQL 5.7.6 起已自动同步磁盘与内存 ACL 缓存;8.0.16+ 更彻底消除了延迟可能。
常见错误现象:加了 FLUSH PRIVILEGES 后“看起来生效了”,其实是 GRANT 本身生效的——FLUSH 只是碰巧没报错,纯属冗余。更危险的是:如果 GRANT 因语法错误、用户不存在或权限不足而失败,FLUSH PRIVILEGES 仍会成功返回,掩盖真实问题。
-
GRANT SELECT ON db.* TO 'u'@'%';→ 权限立即写入磁盘 + 刷新内存,新连接即用 - 执行
FLUSH PRIVILEGES前后调用SHOW GRANTS FOR 'u'@'%';结果一致,说明它没做任何事 - 若发现不生效,优先检查是否重连、
CURRENT_USER()匹配的 host 是否正确,而不是补刷命令
什么时候真需要FLUSH PRIVILEGES?
只有一种情况:你绕过所有授权语法,直接用 DML 修改了 mysql 系统表。这时 MySQL 完全不知情,内存缓存仍是旧的,不刷就永远不生效。
典型场景包括:
UPDATE mysql.user SET authentication_string = '$A$...' WHERE User='u1';INSERT INTO mysql.db (Host, Db, User, Select_priv) VALUES ('%', 'testdb', 'u1', 'Y');- 用
mysqldump导入修改过的mysql.user表,或脚本批量更新mysql.tables_priv
这些操作只改磁盘,不触发内存重建。此时 FLUSH PRIVILEGES 是唯一补救手段——但它不是“让权限生效”,而是强制重载信号:清空内存 ACL,再从磁盘完整读取全部权限表重建。
执行了FLUSH PRIVILEGES还是连不上?常见陷阱
成功执行 FLUSH PRIVILEGES 并不等于权限已应用。它只影响新建立的连接,已有连接的权限快照在登录瞬间就固化了,不会动态更新。
容易被忽略的点:
- 当前连接仍用旧权限,必须退出后重新登录:
QUIT;再mysql -u u1 -p -
'u'@'localhost'和'u'@'127.0.0.1'是两个独立账号,改了一个,另一个不受影响 - MySQL 8.0 默认用
caching_sha2_password插件,老客户端(如旧版 JDBC)可能静默降级失败,表现为“能连但权限不对” - 执行
FLUSH PRIVILEGES需要RELOAD权限,普通用户会直接报错ERROR 1227 (42501): Access denied
验证改密或授权是否真正生效的正确姿势
别依赖命令是否返回成功,要看实际效果:
- 用
CURRENT_USER()确认当前会话匹配的是哪条user@host记录(注意空格、大小写、host 通配符) - 新开终端,用新密码尝试登录:
mysql -u u1 -p -h 127.0.0.1,而不是复用旧连接 - 对已授权限的对象执行实际操作,比如
SELECT * FROM db.t;,看是否报ERROR 1142或其他权限错误 - 检查
mysql.user表结构是否完整,特别是 8.0 升级后未运行mysqld --upgrade=FORCE可能导致authentication_string字段缺失
真正难排查的从来不是命令敲得对不对,而是你以为权限已加载,其实连接还挂着旧上下文,或者压根连错了实例、账号匹配错了 host。


















