mysql 8.0.1+才支持角色,5.7及以前不支持;创建、授权、分配三步须分离;角色需显式激活(会话级或设默认角色);不支持嵌套,备份需额外处理。

MySQL 8.0+ 才支持角色,低版本直接用用户权限
MySQL 的角色(ROLE)是 8.0.1 版本才正式引入的特性,5.7 及更早版本没有 CREATE ROLE、GRANT ... TO role_name 这类语法。如果你执行 CREATE ROLE 'dev'; 报错 ERROR 1064 (42000) 或提示语法错误,先确认版本:SELECT VERSION();。别折腾配置文件或插件——不是配置问题,是压根不支持。
创建角色、授权、再分配给用户三步必须分开
角色本身不登录、不连接数据库,它只是权限容器。常见错误是试图给角色设密码或直接用角色名连接。正确流程只有三步,且不能合并:
CREATE ROLE 'app_reader';-
GRANT SELECT ON mydb.* TO 'app_reader';(注意:这里TO后是角色名,不是用户) -
GRANT 'app_reader' TO 'app_user'@'192.168.%';(把角色授予具体用户)
缺第三步,用户登录后权限不会生效;第二步漏了 ON 子句或写成 GRANT SELECT ON *.*(没指定库),会导致权限范围过大或报错;如果用户已存在,还需执行 SET DEFAULT ROLE 'app_reader' TO 'app_user'@'192.168.%';,否则新角色默认不激活。
激活角色需显式设置,默认不启用
即使你把角色授给了用户,该用户登录后也不会自动拥有角色权限。必须手动激活:
- 会话级激活:
SET ROLE 'app_reader';(当前连接生效,断开即失效) - 设为默认角色:
SET DEFAULT ROLE 'app_reader' TO 'app_user'@'192.168.%';(下次登录自动激活)
检查当前会话有效角色:SELECT CURRENT_ROLE();;查用户所有被授予的角色:SELECT * FROM mysql.role_edges WHERE TO_HOST = '192.168.%';。别依赖 SHOW GRANTS; —— 它默认只显示用户直连权限,不展开角色继承,得加 FOR 'user'@'host' 才能看到完整视图。
角色不能嵌套,且无法跨实例复用
MySQL 不支持角色继承角色(比如 GRANT 'admin_role' TO 'dev_role'; 是非法语法)。每个角色的权限必须单独授予。另外,角色元数据存在 mysql.role_edges 和 mysql.role_graph_edges 表中,但这些表不能直接 INSERT/UPDATE,必须用 GRANT/DROP ROLE 操作。备份恢复时注意:mysqldump --all-databases 默认不导出角色信息,需额外加上 --skip-triggers --skip-routines 并确保目标实例也是 8.0+,否则还原后角色丢失、权限断裂。











