mysql 8.0角色授权需四步:创建角色、赋权给角色、授予角色给用户、设默认角色,缺一不可;否则current_role()返回null且权限无效。

MySQL 8.0 的角色功能本身不支持“一键批量授权开发人员”,必须显式创建角色、赋权、绑定用户、设默认角色四步全走完,漏任何一步都会导致 CURRENT_ROLE() 返回 NULL,权限实际不可用。
CREATE ROLE 报错 ERROR 3719 或 ERROR 1064 怎么办
直接执行 CREATE ROLE 'dev_role' 就失败,大概率不是语法问题,而是环境没准备好:
- ERROR 1064:说明 MySQL 版本低于
8.0.1,角色功能压根不存在。运行SELECT VERSION();确认,5.7 或更老版本请放弃角色,改用传统GRANT。 - ERROR 3719(提示
'role_admin'@'%'is not set as a role):说明全局开关未启用。必须由root执行:SET GLOBAL activate_all_roles_on_login = ON;GRANT ROLE_ADMIN ON *.* TO 'admin_user'@'%';FLUSH PRIVILEGES; - 该变量重启失效,生产环境务必在
my.cnf的[mysqld]段下加:activate_all_roles_on_login=ON
GRANT 权限给角色 vs GRANT 角色给用户,两步不能合并
这是最常被跳过的断点:只做其中一步,权限就等于没给。
- 给角色赋权(填充权限包):
GRANT SELECT, INSERT, UPDATE, DELETE, CREATE, DROP ON app_db.* TO 'dev_role'@'%';
注意:角色名必须带主机名,'dev_role'等价于'dev_role'@'%',但后续绑定用户时 host 必须匹配。 - 把角色授予用户(建立绑定):
GRANT 'dev_role'@'%' TO 'dev1'@'10.20.%';
这步只是往mysql.role_edges表里插记录,SHOW GRANTS FOR 'dev1'@'10.20.%'只会显示GRANT 'dev_role'@'%' TO 'dev1'@'10.20.%',不会展开权限内容。 - 角色不支持列级授权:
GRANT SELECT(id) ON t1 TO 'dev_role'会报ERROR 1142;也不支持WITH GRANT OPTION,要用WITH ADMIN OPTION控制角色再分发权。
SET DEFAULT ROLE 是权限生效的临门一脚
用户登录后仍被拒?CURRENT_ROLE() 返回 NULL?问题几乎一定出在这步没做。
- 必须由有
SYSTEM_VARIABLES_ADMIN或APPLICATION_PASSWORD_ADMIN权限的管理员执行:SET DEFAULT ROLE 'dev_role'@'%' TO 'dev1'@'10.20.%'; - host 必须严格匹配:若角色是
'dev_role'@'%',就不能对'dev1'@'localhost'设默认角色。 - 批量操作可生成 SQL:
SELECT CONCAT('SET DEFAULT ROLE ''dev_role''@''%'' TO ''', username, '''@''%', ''';') FROM user_list WHERE dept = 'dev';
导出后执行,避免逐条手敲。 - 验证是否生效:
登录dev1后执行SELECT CURRENT_ROLE();—— 返回非NULL值才算成功;
查真实权限:SHOW GRANTS FOR 'dev1'@'10.20.%' USING 'dev_role';
真正容易被忽略的是:角色权限变更后必须 FLUSH PRIVILEGES,否则新用户无法继承;而 SET DEFAULT ROLE 之后,用户下次连接才生效,当前会话仍需手动 SET ROLE。这些细节不处理,批量授权就只是“看起来完成了”。











