dba不是mysql内置角色,需通过权限组合识别:真正具备管理能力的用户通常拥有super、grant option、create user、reload、shutdown等至少三项全局权限,且须结合mysql.user表查询验证,避免仅凭super_priv='y'误判。

DBA不是MySQL内置角色,得靠权限组合判断
MySQL没有叫“DBA”的预设角色或字段,所谓DBA权限其实是多个高危权限的集合。真正有管理能力的用户,通常具备 SUPER、GRANT OPTION、CREATE USER、RELOAD、SHUTDOWN 等至少三项全局权限。不能只看 Super_priv = 'Y' 就断定是DBA——有些运维脚本会误开这个权限但没给其他配套权限,实际管不了库。
查 mysql.user 表识别高权限用户
直接查系统表最可靠,SHOW GRANTS 无法批量筛选,且不反映已过期或未刷新的权限:
SELECT User, Host, Super_priv, Grant_priv, Create_user_priv, Reload_priv, Shutdown_priv, Process_priv FROM mysql.user WHERE Super_priv = 'Y' OR Grant_priv = 'Y' OR Create_user_priv = 'Y' OR Reload_priv = 'Y' OR Shutdown_priv = 'Y';
-
Super_priv是关键指标,但单独存在意义有限;搭配Grant_priv才能真正转授权限 -
Create_user_priv比INSERT INTO mysql.user更安全,应优先检查此项 -
Process_priv能看到别人SQL,审计时有用,但不算DBA核心权限
注意 host 匹配和权限继承陷阱
同一个用户名在不同 Host 下权限可能完全不同,比如 'admin'@'localhost' 和 'admin'@'%' 是两个独立账号:
- 先用
SELECT User, Host FROM mysql.user WHERE User = 'admin';确认完整账号名 - MySQL 8.0+ 若用了角色(
mysql.role_edges),mysql.user表不体现角色继承的权限,得额外查SELECT * FROM mysql.role_edges WHERE TO_HOST = 'admin'@'localhost'; -
FLUSH PRIVILEGES不影响已连接会话,新权限要重连才生效,别被缓存误导
别漏掉数据库级和表级“伪DBA”账号
有些账号虽无全局 SUPER,但在关键库(如 mysql)上有 ALL PRIVILEGES,也能删用户、改权限表:
SELECT User, Host, Db, Select_priv, Insert_priv, Update_priv, Delete_priv, Create_priv, Drop_priv FROM mysql.db WHERE Db = 'mysql' AND (Insert_priv = 'Y' OR Update_priv = 'Y' OR Drop_priv = 'Y');
这类账号实际危害不亚于全局DBA,尤其当 mysql.db 表里 Db 字段是通配符(如 test%)时,容易被忽略。











