撤销super权限必须用revoke super on . from 'user'@'host';,因其是纯实例级权限;mysql 8.0.16+已废弃super,需改用system_variables_admin、connection_admin等动态权限替代,并主动kill旧连接及检查角色继承。

撤销 SUPER 权限必须写 ON *.*,否则报错 ERROR 1221
MySQL 把 SUPER 视为纯实例级权限,它不作用于任何库或表,只控制 KILL、SET GLOBAL、启动复制等操作。因此语法强制要求作用域只能是 *.*——写成 mydb.*、mysql.* 或漏掉 ON *.* 都会触发 ERROR 1221 (HY000): Incorrect usage of DB GRANT and GLOBAL PRIVILEGES。
常见错误写法:
-
REVOKE SUPER ON mydb.* FROM 'admin'@'%';❌ -
REVOKE SUPER FROM 'admin'@'%';❌(缺ON *.*) -
REVOKE SUPER ON * FROM 'admin'@'%';❌(缺第二个星号)
正确写法只有一种:REVOKE SUPER ON *.* FROM 'admin'@'%';✅
MySQL 8.0.16+ 中 SUPER 已废弃,得用细粒度权限替代
如果你的 MySQL 版本 ≥ 8.0.16(执行 SELECT VERSION(); 确认),直接 REVOKE SUPER ON *.* 会报错:ERROR 3715 (HY000): The SUPER privilege is obsolete。这不是配置问题,是 MySQL 主动移除了该权限语义。
此时必须改用对应动态权限逐个回收:
-
SYSTEM_VARIABLES_ADMIN→ 替代SET GLOBAL -
CONNECTION_ADMIN→ 替代KILL其他连接(常被忽略,但权限极高) -
SET_USER_ID→ 替代SET USER或模拟用户上下文 -
REPLICATION_APPLIER→ 替代从库线程控制
安全做法是合并撤销:REVOKE SYSTEM_VARIABLES_ADMIN, CONNECTION_ADMIN, SET_USER_ID ON *.* FROM 'admin'@'%';
撤销后旧连接仍有效,必须主动 KILL 或重连
REVOKE 只影响新建立的连接。已存在的活跃连接(包括应用长连接、DBA 客户端)仍持有原权限,可继续执行 KILL、SET GLOBAL max_connections = 1000 等操作。
必须手动干预:
- 查活跃会话:
SELECT ID, USER, HOST, COMMAND, TIME FROM INFORMATION_SCHEMA.PROCESSLIST WHERE USER = 'admin'; - 逐个终止:
KILL CONNECTION 1234;(不是KILL QUERY) - 若用连接池(如 HikariCP),需触发重建或重启应用
别指望 FLUSH PRIVILEGES —— 它对动态权限无效,且在 8.0+ 中也不必要。
别漏掉角色继承和代理关系带来的隐式权限
用户可能没被直接授过 SUPER,而是通过角色获得:GRANT SUPER ON *.* TO 'dba_role'; GRANT 'dba_role' TO 'admin'@'%';。此时只对用户执行 REVOKE 不起作用。
检查方式:
- 查角色绑定:
SELECT * FROM mysql.role_edges WHERE TO_USER = 'admin' AND TO_HOST = '%'; - 查角色内权限:
SHOW GRANTS FOR 'dba_role'; - 若有,先
REVOKE 'dba_role' FROM 'admin'@'%';,再考虑DROP ROLE 'dba_role';
另外注意代理用户(proxy user):查 mysql.proxies_priv 表,否则删用户后,代理登录可能静默失败。











