flush privileges强制从磁盘重载mysql.user等权限表到内存缓存,仅在直接dml修改系统表或特定alter user场景下必需;grant/revoke在5.7中仍需执行该命令,create user/drop user及同用户alter user则自动刷新。

MySQL 5.7 的权限缓存机制决定必须 FLUSH PRIVILEGES
MySQL 5.7 启动时会把 mysql.user 表加载进内存做权限缓存,后续所有连接验证都查这个内存副本,而不是实时读表。所以你用 UPDATE user 改了 authentication_string,只是改了磁盘上的数据,内存里的权限快照还是旧的——不执行 FLUSH PRIVILEGES,新密码永远不生效。
ALTER USER 为什么有时也得加 FLUSH PRIVILEGES?
ALTER USER 本身会自动触发权限重载,但有两个例外场景必须手动补上 FLUSH PRIVILEGES:
- 在
--skip-grant-tables模式下执行ALTER USER:此时权限系统被绕过,语句能执行成功,但不会触发内部刷新逻辑 - 修改的是非当前登录用户的 host 匹配项(比如你用
'root'@'localhost'登录,却去改'root'@'127.0.0.1'):部分版本中该操作不自动刷新对应 host 的缓存条目
哪些操作可以跳过 FLUSH PRIVILEGES?
只有以下两类操作是“真自动刷新”的,其余一律要加:
-
CREATE USER、DROP USER:用户元数据变更自带刷新 - 正常登录状态下执行的
ALTER USER ... IDENTIFIED BY(且目标用户 = 当前登录用户):MySQL 内部会同步更新内存缓存
但注意:GRANT 和 REVOKE 在 5.7 中仍需 FLUSH PRIVILEGES ——这点和直觉相反,很多人在这里踩坑。
FLUSH PRIVILEGES 不是万能的,它只刷权限,不刷认证插件逻辑
即使你正确执行了 FLUSH PRIVILEGES,如果密码字段填错格式,照样登录失败:
- 直接写
PASSWORD('xxx')→ 返回哈希值但不符合mysql_native_password插件要求的格式 - 手动拼接
authentication_string值 → 容易漏掉 salt 或长度校验,插件拒绝解析 - 没指定
@'localhost'导致匹配到'root'@'%'这条空密码记录 → 刷新后生效的仍是那条无效记录
真正安全的做法是:免密登录后,先 USE mysql,再用 ALTER USER 'root'@'localhost' IDENTIFIED BY 'xxx',最后补一句 FLUSH PRIVILEGES ——顺序不能乱,host 不能省。











