是的,REVOKE执行后权限在服务端立即生效,但已存在的会话不会自动刷新权限,需重连或SET ROLE NONE同步;撤销数据库全部权限须分层处理,且ALL PRIVILEGES不包含GRANT OPTION。

REVOKE 执行后权限是否立即生效
是的,REVOKE 语句执行成功后,权限变更在服务端立即生效。但当前已建立的连接(session)不会自动刷新权限视图——用户仍能继续执行之前有权限的操作,直到断开重连或显式重置角色状态。
常见现象:执行 REVOKE SELECT ON app.* FROM 'dev'@'%'; 后,dev 用户还能查 app 库里的表。这不是撤销失败,而是旧会话缓存未更新。
- MySQL 8.0 中,无需执行
FLUSH PRIVILEGES(该命令仅在直接修改mysql系统表后才需要) - 最简单可靠的同步方式是让客户端重新连接
- 若用户启用了角色(
SET ROLE),可执行SET ROLE NONE;临时丢弃当前激活角色的权限
撤销用户所有数据库级权限的正确写法
想清空用户对某个库的全部操作权,不能只写 REVOKE ALL PRIVILEGES ON mydb.* —— 这会漏掉列级、存储过程、触发器等细粒度权限。
必须分层处理:
- 先撤销对象级权限:
REVOKE ALL PRIVILEGES, GRANT OPTION ON mydb.* FROM 'user'@'host'; - 再检查是否有列级权限:
SELECT * FROM mysql.columns_priv WHERE User='user' AND Host='host' AND Db='mydb';,如有则用REVOKE ... ON mydb.tbl(col1,col2) FROM ...逐条撤 - 若有函数/过程权限,需额外执行:
REVOKE EXECUTE ON FUNCTION mydb.fn_name FROM 'user'@'host';
注意:ALL PRIVILEGES 不包含 GRANT OPTION,后者必须显式写出,否则用户仍可转授。
为什么 REVOKE ALL FROM 'role_name' 会报错
因为 MySQL 根本不支持这种语法。REVOKE ALL FROM 'role_name' 直接触发 ERROR 1064 (42000):语法错误。
角色不是“权限集合体”而是“权限容器”,撤销动作只能作用于两个方向:
- 从用户身上解绑角色:
REVOKE 'reader_role' FROM 'alice'@'localhost'; - 彻底删除角色定义(含其所有内置权限):
DROP ROLE 'reader_role';
试图对角色本身执行 REVOKE,就像对一个文件夹执行 rm -rf 权限 —— 操作对象错了。真正要清理的是“谁用了它”或“它本身要不要留”。
部分撤销(PARTIAL REVOKES)启用后的影响
开启 partial_revokes=ON 后,用户即使拥有全局 SELECT,也能被单独禁止访问某库(如 sys 或 mysql)。但这也带来约束:
- 一旦用户存在部分撤销规则,就不能再用
REVOKE ALL PRIVILEGES ON *.* FROM ...清空全局权限,否则报ERROR 3790 (HY000) - 部分撤销只适用于特定全局权限(
SELECT、INSERT、GRANT OPTION等),不支持表级或列级限制 -
INFORMATION_SCHEMA禁止加部分撤销,MySQL 显式拒绝
最易忽略的一点:部分撤销是“叠加式限制”,它不改变原始授权,只是新增例外;因此 SHOW GRANTS 输出里会出现 REVOKE SELECT ON `sys`.* FROM ... 这样的行,别当成错误。


















