REVOKE SUPER必须作用于.,其他作用域报错;ALL PRIVILEGES不包含SUPER,需显式撤销;撤销不影响已有连接,需主动KILL或重启;角色授予的SUPER须从角色或用户侧剥离。

REVOKE SUPER必须用*.*作用域,其他写法直接报错
MySQL把SUPER归为全局权限,它不作用于库或表,只影响整个实例——比如KILL线程、SET GLOBAL、启动复制等。因此语法强制要求作用域只能是*.*,哪怕当初授予权限时写了myapp.*(实际会静默降级),撤的时候也必须回归正确形式:
-
REVOKE SUPER ON *.* FROM 'admin'@'%';✅ 正确 -
REVOKE SUPER ON myapp.* FROM 'admin'@'%';❌ 报错:ERROR 1221 (HY000): Incorrect usage of DB GRANT and GLOBAL PRIVILEGES -
REVOKE SUPER ON myapp.users FROM 'admin'@'%';❌ 同样报错,且不会部分生效
ALL PRIVILEGES不包含SUPER,必须显式列出
很多人误以为REVOKE ALL PRIVILEGES ON *.* FROM 'u'@'h';能顺带清掉SUPER,但这是错的。ALL PRIVILEGES只覆盖常规DML/DDL权限(SELECT、INSERT、CREATE等),而SUPER、GRANT OPTION、REPLICATION CLIENT属于独立管理类权限。
- 执行
REVOKE ALL PRIVILEGES ON *.* FROM 'admin'@'%';后,SUPER依然存在 - 要彻底清理,必须显式写出:
REVOKE ALL PRIVILEGES, SUPER, GRANT OPTION ON *.* FROM 'admin'@'%'; - 验证方式:运行
SHOW GRANTS FOR 'admin'@'%';,输出里不应再出现SUPER
撤销后旧连接仍保留SUPER,必须主动处理活跃会话
REVOKE只影响新建立的连接。如果用户当前有长连接(比如应用未重启的连接池、DBA正在用的客户端),那些连接持有的SUPER权限不会被实时剥夺——他们还能继续KILL线程、改max_connections等。
- 不能依赖“刚执行完
REVOKE就安全了” - 生产环境建议先查活跃会话:
SELECT ID, USER, HOST, COMMAND, TIME FROM INFORMATION_SCHEMA.PROCESSLIST WHERE USER = 'admin'; - 必要时主动断开:
KILL [connection_id];,或通知应用重启连接池 -
FLUSH PRIVILEGES;对SUPER撤销不是必需的(MySQL 8.0+ 自动刷新),但它不解决已存在连接的问题
别漏掉角色间接授予的SUPER
如果用户是通过角色获得SUPER(例如GRANT SUPER ON *.* TO 'myrole'; GRANT 'myrole' TO 'admin'@'%';),那么只对用户执行REVOKE无效。
- 要么从角色撤销:
REVOKE SUPER ON *.* FROM 'myrole'; - 要么剥离角色:
REVOKE 'myrole' FROM 'admin'@'%'; - 否则
SHOW GRANTS FOR 'admin'@'%';可能不显示SUPER,但实际仍具备该能力
真实操作中最容易忽略的是活跃连接残留和角色间接授权这两点——它们会让权限回收在表面上成功,实则形同虚设。


















