mysql中使用FLUSH PRIVILEGES更新权限表

2次阅读

必须执行flush privileges仅当直接修改mysql系统库权限表(如update mysql.user)后;使用create user、grant等标准命令则自动同步,无需且不应执行该命令。

mysql中使用FLUSH PRIVILEGES更新权限表

什么时候必须执行 FLUSH PRIVILEGES

只有在**直接修改了 mysql 系统库的权限表(如 userdbtables_priv 等)后**,才需要手动执行 FLUSH PRIVILEGES。MySQL 服务启动时会将这些表加载进内存缓存,后续权限检查都走内存副本,不实时查表。

换句话说:用 CREATE USERGRANTDROP USER 这类 DDL 命令操作权限,MySQL 会自动同步内存缓存——此时 FLUSH PRIVILEGES 完全多余,甚至可能掩盖误操作。

  • ✅ 正确场景:用 UPDATE mysql.user SET authentication_string = ... WHERE User = 'foo' 改了密码字段
  • ❌ 错误场景:刚执行完 GRANT select ON db.* TO 'u'@'%',又补一句 FLUSH PRIVILEGES
  • ⚠️ 风险:如果 UPDATE 语句漏掉 WHERE 或写错条件,FLUSH 会让错误权限立刻生效

FLUSH PRIVILEGES 的实际行为和限制

它不是“重载配置”,而是强制 MySQL 丢弃当前内存中的权限缓存,并从磁盘上的 mysql 表重新读取全部数据。这个过程会阻塞所有新连接的权限验证,直到刷新完成(通常很快,但高并发下可感知)。

  • 不会触发事务提交:即使你之前用 BEGIN; UPDATE mysql.user ...; COMMIT;FLUSH 仍是必需的(因为权限缓存不参与事务)
  • 不校验语法或逻辑:如果 user 表里存在重复 Host/User 组合、空密码字段、非法 plugin 值,FLUSH 仍会加载,但后续登录可能失败
  • 对运行中连接无影响:已建立的连接保留原有权限,新连接才用新缓存

替代方案:优先用标准权限语句

95% 的权限管理需求,都应该避开直接改系统表。标准语句更安全、可审计、自动生效:

CREATE USER 'app'@'10.0.2.%' IDENTIFIED WITH caching_sha2_password BY 'pwd123'; GRANT SELECT, INSERT ON sales.* TO 'app'@'10.0.2.%'; ALTER USER 'app'@'10.0.2.%' REQUIRE ssl;

这些命令内部做了三件事:更新磁盘表 + 更新内存缓存 + 记录到二进制日志(如果开启)。不需要、也不应该加 FLUSH PRIVILEGES

  • 修改密码统一用 ALTER USER ... IDENTIFIED BY,别碰 authentication_string
  • 删用户用 DROP USER,别只 delete FROM mysql.user
  • 要批量授权?写脚本生成 GRANT 语句,而不是拼 INSERT INTO mysql.db

调试权限问题时,别盲目刷缓存

遇到“明明 GRANT 了却不生效”,先确认根本原因,而不是第一反应 FLUSH PRIVILEGES

  • 检查是否连错了实例:SELECT @@hostname, @@port;
  • 确认用户匹配逻辑:SELECT User, Host FROM mysql.user WHERE User = 'u'; —— 注意 'u'@'localhost''u'@'127.0.0.1' 是不同账户
  • 验证当前连接用的哪个账户:SELECT USER(), CURRENT_USER();(前者是客户端声明的,后者是服务器认证后的)
  • 查看具体权限:SHOW GRANTS for 'u'@'h';,不是看 mysql.user 表字段

直接改系统表+刷缓存,相当于绕过 MySQL 的权限抽象层,容易让状态变得不可预测。真正棘手的权限问题,往往出在 Host 匹配、SSL 要求、角色激活或代理用户配置上,而不是缓存没刷新。

text=ZqhQzanResources