最直接方法是查询mysql.user表的super_priv列:select user, host from mysql.user where super_priv = 'y';mysql 8.0+还需检查角色继承路径,因用户可能通过角色间接获得super权限。

查 mysql.user 表的 Super_priv 列最直接
MySQL 8.0 之前,权限信息全在 mysql.user 表里,Super_priv 是个 ENUM 列,值为 'Y' 或 'N'。直接查它就行,不用绕路。
- 必须用
SELECT ... FROM mysql.user,其他视图(比如information_schema.role_table_grants)不包含 SUPER 权限 - 需要
SELECT权限才能读mysql.user,普通用户默认没这权限,得用 root 或有SELECT ON mysql.*的账号执行 - 注意大小写:
Super_priv是大写 S、P,不是super_priv或SUPER_PRIV
SELECT User, Host FROM mysql.user WHERE Super_priv = 'Y';
MySQL 8.0+ 要额外检查角色(Role)继承路径
8.0 引入了角色机制,用户可能没直连 Super_priv='Y',但被赋予了带 SUPER 权限的角色——这种情况下查 mysql.user 会漏掉。
- 先查角色本身有没有 SUPER:
SELECT Role FROM mysql.role_edges JOIN mysql.role_column_privs USING (From_host, From_user) WHERE Column_priv = 'Super_priv';(不推荐,表结构复杂) - 更可靠的做法是用内置函数
IS_ROLE_GRANTED()配合SHOW GRANTS模拟:对每个用户运行SHOW GRANTS FOR 'u'@'h';,看输出里是否含GRANT SUPER ON *.* - 如果脚本批量检查,优先用
SELECT ... FROM mysql.role_edges r JOIN mysql.user u ON r.To_user = u.User关联,再过滤角色的权限定义(需 joinmysql.role_column_privs或查mysql.procs_priv等,实际很碎)
SHOW GRANTS 是最准但最慢的验证方式
它反映的是当前生效权限,不受缓存或未刷新权限影响,适合最终确认。但它不能批量查,每次只能指定一个用户。
- 执行
SHOW GRANTS FOR 'root'@'localhost';,如果结果里出现GRANT SUPER ON *.* TO ...,就实锤有权限 - 注意:
SHOW GRANTS不显示通过角色间接获得的权限(8.0.16+ 才支持SHOW GRANTS FOR ROLE),所以得先查用户被授予了哪些角色 - 别信
SELECT CURRENT_USER();的结果——它返回连接时认证的用户,不是你SHOW GRANTS FOR的目标用户
常见误判点:mysql.session 和 mysql.infoschema 这类系统账户
它们在 mysql.user 表里 Super_priv='Y',但这是 MySQL 内部保留用途,不是 DBA 可用的“真实” SUPER 用户。
- 这些账户通常
plugin='mysql_native_password'但密码为空或无效,无法登录,只是服务端内部调用用的 - 查出结果后建议加过滤:
WHERE Super_priv = 'Y' AND authentication_string != '' AND account_locked = 'N'(MySQL 5.7+) - MySQL 8.0 默认禁用
old_passwords,但如果你看到plugin='sha256_password'+Super_priv='Y',基本可判定是人为配置的高权账号,不是系统账户
SUPER 权限极敏感,且 MySQL 不提供“谁最近用了它”的审计日志(除非开了 general_log 或企业版 audit log),查到之后别只盯着列表,得立刻确认这些账号是否仍在业务必要范围内。











