flush tables权限只能在.上撤销,必须用revoke flush tables on . from 'dev'@'%';主机名须完全匹配,多host需逐条执行;撤销后必须flush privileges并重连验证,否则长连接仍可执行。

FLUSH TABLES 权限只能在 *.* 上撤销
MySQL 不允许对数据库或表级对象授予或撤销 FLUSH TABLES,它属于全局管理权限(类似 SUPER、RELOAD),作用域固定为 *.*。写成 REVOKE FLUSH TABLES ON mydb.* FROM 'dev'@'%' 会直接报错:ERROR 1221 (HY000): Incorrect usage of DBACL and GLOBAL PRIVILEGES。
- 必须用
REVOKE FLUSH TABLES ON *.* FROM 'dev'@'%' - 主机名必须完全匹配——
'dev'@'192.168.1.%'和'dev'@'%'是两个不同用户,不能混用 - 若用户有多个 host 记录(如
'dev'@'localhost'和'dev'@'10.%'),需逐条执行对应语句
撤销后必须显式刷新,否则长连接仍可执行 FLUSH
FLUSH TABLES 是高危操作,影响全库缓存和元数据锁。MySQL 8.0+ 虽在 REVOKE 后自动更新部分权限缓存,但该权限的生效依赖于全局权限表重载,旧连接仍能调用成功,直到断开重连或手动刷新。
- 执行
FLUSH PRIVILEGES是必要步骤,不是“可选优化” - 不刷新时,应用连接池(如 Druid、HikariCP)里的活跃连接仍可执行
FLUSH TABLES,造成误操作风险 - 验证是否生效:新开一个
mysql -u dev -p连接,再运行FLUSH TABLES,应报错ERROR 1227 (42501): Access denied
别漏掉 GRANT OPTION 和角色继承路径
仅撤 FLUSH TABLES ON *.* 不够。如果该用户曾被授予 GRANT OPTION,他可能已把 FLUSH TABLES 转授给他人;如果权限来自角色(如 backup_admin),直接撤权限无效。
- 查是否带转授权:
SELECT Grant_priv FROM mysql.user WHERE User='dev' AND Host='%';,若为Y,必须补一句:REVOKE GRANT OPTION ON *.* FROM 'dev'@'%' - 查角色继承:
SELECT * FROM mysql.role_edges WHERE TO_USER='dev' AND TO_HOST='%';,若有结果,需先REVOKE role_name FROM 'dev'@'%' - 角色撤销后,仍需对角色本身执行
REVOKE FLUSH TABLES ON *.* FROM role_name,否则下次赋角色还会带回来
SHOW GRANTS 看不到就等于没权限?不一定
SHOW GRANTS FOR 'dev'@'%' 输出里没出现 FLUSH TABLES,不代表它真没了。原因有两个:
- 权限可能来自
mysql.user表的Reload_priv字段(FLUSH TABLES和RELOAD共享该字段),而SHOW GRANTS只展示显式GRANT记录,不反映字段直改 - 若之前是用
UPDATE mysql.user SET reload_priv='Y' ...手动改的,REVOKE无法覆盖,必须同步UPDATE mysql.user SET reload_priv='N' WHERE User='dev' AND Host='%'并FLUSH PRIVILEGES
最稳妥的验证方式是:查 SELECT Reload_priv FROM mysql.user WHERE User='dev' AND Host='%';,确认返回 N,且新连接执行 FLUSH TABLES 报错。











