MySQL 8.0角色需四步闭环:启用支持→创建角色→授权给角色→绑定并激活(SET DEFAULT ROLE),缺一不可;CURRENT_ROLE()返回NULL即未激活;CREATE ROLE报错需检查版本及activate_all_roles_on_login开关。

CURRENT_ROLE() 返回 NULL?说明角色权限根本没生效——MySQL 8.0 的角色不是建完就自动可用的“快捷方式”,必须走完四步闭环:启用支持 → 创建角色 → 授权给角色 → 绑定并激活角色给用户。漏掉任何一步,用户照样 Access denied。
CREATE ROLE 报错 ERROR 1064 或 ERROR 3719 怎么办
这不是语法写错了,而是环境压根没准备好:
-
ERROR 1064:运行SELECT VERSION();确认版本,低于8.0.1直接放弃角色,改用传统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 SELECT ON db.* TO 'role_name' 和 GRANT 'role_name' TO 'user' 是两回事
这两步不能合并、不能跳过、顺序不能反:
- 第一步是“填充角色”:
GRANT SELECT, INSERT ON app_db.* TO 'dev_role'@'%';—— 权限只存进角色,不作用于任何人 - 第二步是“绑定用户”:
GRANT 'dev_role'@'%' TO 'dev1'@'10.20.%';—— 只往mysql.role_edges插记录,SHOW GRANTS FOR 'dev1'仍只显示这行绑定语句,不会展开权限内容 - 角色名必须带主机名,
'dev_role'等价于'dev_role'@'%',但若用户是'dev1'@'localhost',而角色是'dev_role'@'%',后续SET DEFAULT ROLE会因 host 不匹配失败 - 角色不支持列级授权:
GRANT SELECT(id) ON t1 TO 'dev_role'直接报ERROR 1142
SET DEFAULT ROLE 是权限真正生效的临门一脚
用户登录后仍被拒?CURRENT_ROLE() 返回 NULL?问题几乎一定出在这步没做:
面向 CRM 系统的 MySQL 8 数据库模式设计。当用户需要为客户关系管理(CRM)系统设计、评审、优化或生成数据库模式时,应使用此项技能。
- 必须由具备
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'; -
SET DEFAULT ROLE ALL TO 'dev1'@'%'会激活所有已授予角色,但违背最小权限原则,慎用
验证权限是否真生效不能只看 SHOW GRANTS
SHOW GRANTS FOR 'dev1'@'%' 默认不展开角色权限,这是设计行为,不是配置失败:
- 查角色本身有哪些权限:
SHOW GRANTS FOR 'dev_role'@'%'; - 查用户通过某角色获得的权限:
SHOW GRANTS FOR 'dev1'@'%' USING 'dev_role'; - 确认当前会话是否激活:
SELECT CURRENT_ROLE();,返回非NULL值才算成功 - 权限变更不影响已有连接:刚
GRANT给角色的新权限,老连接必须手动执行SET ROLE 'dev_role'@'%';才能加载
最常被忽略的点是:以为 GRANT 'role' TO 'user' 就等于权限落地了。其实这只是挂了个钩子,没 SET DEFAULT ROLE,钩子永远不拉紧。










