MySQL 8.0+预定义角色不存于任何系统表,而是硬编码在服务端的虚拟角色;唯一权威来源是官方文档“Predefined Roles”章节。

MySQL 8.0+ 中预定义角色存放在哪个系统表里
MySQL 8.0 引入了角色(ROLE)机制,但它的预定义角色(如 BACKUP_ADMIN、CLONE_ADMIN、CONNECTION_ADMIN 等)并不像普通用户那样显式存储在 mysql.user 表中。它们是硬编码在服务端的“虚拟角色”,没有对应行记录,因此直接查 mysql.role_edges 或 mysql.user 查不到。
真正能列出所有可用预定义角色的方式,是查询权限系统表 information_schema.role_table_grants —— 但它只返回已被授予的角色;更可靠的做法是查 mysql.global_grants 表(MySQL 8.0.16+),不过该表仅包含全局权限项,不直接列角色名。
实际可行路径只有一条:依赖 MySQL 文档明确列出的、服务启动时自动注册的内置角色列表,并通过 SHOW ROLES(MySQL 8.0.24+)或尝试 SELECT * FROM mysql.role_edges WHERE TO_HOST = '' 辅助验证。
使用 SHOW ROLES 查看当前已存在(含预定义)的角色
SHOW ROLES 是 MySQL 8.0.24 起引入的命令,它会列出所有**已被创建或已激活的**角色,包括你手动 CREATE ROLE 的,也包括部分预定义角色——但前提是这些预定义角色已被至少一次显式授予过某个用户(例如执行过 GRANT BACKUP_ADMIN TO 'u'@'%'),否则不会出现在结果中。
所以运行:
SHOW ROLES;
可能返回空或只有少量角色,不代表预定义角色不存在,只是尚未被“实例化”。
面向 CRM 系统的 MySQL 8 数据库模式设计。当用户需要为客户关系管理(CRM)系统设计、评审、优化或生成数据库模式时,应使用此项技能。
常见误区:
- 误以为
SHOW ROLES能列出全部内置角色(它不能,只列已存在的) - 试图用
SELECT * FROM mysql.user WHERE account_locked = 'Y'找预定义角色(预定义角色不占mysql.user行) - 在低于 8.0.24 的版本执行
SHOW ROLES报错Unknown command
最稳妥的方法:查官方文档 + 查询 global_grants 权限项
MySQL 官方文档明确列出了所有预定义角色及其权限(见 “Predefined Roles” 章节),这是唯一权威来源。你无法通过 SQL 100% 自动枚举出全部,因为它们不落地为数据行。
但你可以间接确认某角色是否被支持:
- 尝试授予一个已知预定义角色,比如:
GRANT BACKUP_ADMIN TO 'dummy'@'localhost';
如果不报错ERROR 3530 (HY000): Access denied for user ... to database 'mysql'或Unknown role,说明该角色存在且有效 - 检查
mysql.global_grants表中是否有对应权限记录(MySQL 8.0.16+):SELECT * FROM mysql.global_grants WHERE grantee LIKE '%BACKUP_ADMIN%';
注意:该表字段grantee存的是'role_name'@''格式,不是纯角色名 - 运行
SELECT DISTINCT privilege FROM information_schema.role_table_grants;可看到部分预定义角色所带的权限关键词(如BACKUP_ADMIN对应BACKUP_ADMIN权限),但不能反推角色名
为什么不能像查用户一样查预定义角色
预定义角色不是数据库对象,而是权限集合的快捷别名。MySQL 启动时将它们注册进内存权限系统,不写入磁盘表。这种设计带来两个后果:
- 没有
CREATE ROLE IF NOT EXISTS backup_admin;这类语句生效(会报错,因角色已存在) -
DROP ROLE BACKUP_ADMIN;会失败,提示ERROR 3539 (HY000): Cannot drop system role 'BACKUP_ADMIN' - 它们不能被重命名、不能被设置密码、也不能被
RENAME USER操作影响
换句话说:你只能用,不能管——这是最容易忽略的边界。一旦依赖自动化脚本枚举“所有角色”,必须硬编码这份列表,或调用 MySQL 版本号 + 文档映射表来做兼容判断。










