mysql 8.0+才支持角色,5.7及以前版本执行create role必报error 1064;必须严格分三步:创建角色、授予权限给角色、将角色授予用户并set default role激活,缺一不可。

MySQL 8.0+ 才支持角色,5.7 及以前版本直接报错
执行 CREATE ROLE 'dev_role' 报 ERROR 1064 (42000)?不是配置没开,是版本不支持。先确认:SELECT VERSION();。结果低于 8.0.1 就别折腾角色了——删掉配置、重启服务都没用。低版本只能靠用户级授权硬扛,或者升级 MySQL。
角色三步必须分开:创建 → 授权 → 分配,不能合并
常见错误是把三步写成一条语句,或漏掉关键子句。正确顺序和要点如下:
-
CREATE ROLE 'app_reader';—— 角色名加单引号,不设密码,不登录 -
GRANT SELECT ON myapp.* TO 'app_reader';—— 注意TO后是角色名,且ON必须指定库(如myapp.*),不能写成*.*或漏掉 -
GRANT 'app_reader' TO 'web_user'@'192.168.1.%';—— 这步只是“授予”,不等于“生效”;如果用户已存在,还需额外执行SET DEFAULT ROLE 'app_reader' TO 'web_user'@'192.168.1.%';
漏第三步,用户登录后 SHOW GRANTS; 看不到角色权限;漏 SET DEFAULT ROLE,每次登录都得手动 SET ROLE,容易被忽略。
角色默认不激活,CURRENT_ROLE() 返回 NULL 是正常现象
即使角色已分配,新会话里 SELECT CURRENT_ROLE(); 返回 NULL,不代表失败,只是未激活。激活方式有两种:
- 会话级临时激活:
SET ROLE 'app_reader';(当前连接生效) - 设为默认角色:
SET DEFAULT ROLE 'app_reader' TO 'web_user'@'192.168.1.%';(下次登录自动生效) - 一次性激活所有已授角色:
SET ROLE ALL;
查用户所有已授角色用:SELECT * FROM mysql.role_edges WHERE TO_USER = 'web_user' AND TO_HOST = '192.168.1.%';;只看当前生效角色必须用 CURRENT_ROLE(),SHOW GRANTS 默认不展开角色,得加 FOR 'web_user'@'192.168.1.%' 才完整。
角色不能嵌套,备份时角色元数据不会自动导出
MySQL 不允许 GRANT 'admin_role' TO 'dev_role' 这类嵌套操作,每个角色的权限必须单独 GRANT。更隐蔽的问题是备份:
-
mysqldump --all-databases默认不导出角色定义和角色关系(mysql.role_edges表内容) - 还原到新实例后,用户还在,但角色丢失、权限断裂,应用连不上或报
Access denied - 必须显式加上
--skip-triggers --skip-routines并确保目标实例也是 8.0+,或单独导出角色 SQL:SELECT CONCAT('CREATE ROLE ''', role, ''';') FROM mysql.role_edges GROUP BY role;+ 权限语句
角色权限变更后,不需要 FLUSH PRIVILEGES(8.0 已自动刷新),但角色删除或重命名后,关联用户的默认角色设置可能残留,需手动清理 mysql.default_roles 表或重置 SET DEFAULT ROLE NONE TO ...。











