mysql 8.0角色权限管理必须完成创建→授权→绑定→激活四步闭环,缺一即报error 1045;需先启用角色支持、授role_admin、持久化配置、显式set default role,且查权限时须用using子句。

MySQL 8.0 的角色权限管理不是“建完角色就自动生效”,必须走完创建 → 授权 → 绑定 → 激活四步闭环;跳过任意一步,用户登录后执行 SELECT 就会报 ERROR 1045 (28000): Access denied。
CREATE ROLE 前必须启用角色支持,否则直接报错
直接执行 CREATE ROLE 'app_reader' 很可能触发 ERROR 3719 (HY000): 'role_admin'@'%' is not set as a role。这不是语法错误,而是 MySQL 8.0 默认禁用角色功能。
- 由
root或高权限用户执行:SET GLOBAL activate_all_roles_on_login = ON - 授予管理员操作角色的权限:
GRANT ROLE_ADMIN ON *.* TO 'admin_user'@'%' - 写入配置文件防重启失效:
[mysqld]下添加activate_all_roles_on_login=ON
GRANT 权限给角色 ≠ GRANT 角色给用户,两步不能合并
常见误操作是以为 GRANT SELECT ON app.* TO 'api_user'@'%' 后再 GRANT 'reader_role' TO 'api_user'@'%' 就完成了——其实前者授的是直连权限,后者才是角色绑定,二者完全独立。
- 角色名必须带主机名(推荐统一用
@'%'):CREATE ROLE 'reader_role'@'%' - 给角色授具体权限(注意:不支持列级授权):
GRANT SELECT ON app.* TO 'reader_role'@'%' - 再把角色绑给用户:
GRANT 'reader_role'@'%' TO 'api_user'@'%' -
SHOW GRANTS FOR 'api_user'@'%'仍只显示绑定语句,不会展开角色内权限——这是正常现象
SET DEFAULT ROLE 是权限真正生效的临门一脚
没执行 SET DEFAULT ROLE,用户登录后 CURRENT_ROLE() 返回 NONE,所有角色权限不可见、不可用。
- 激活单个角色:
SET DEFAULT ROLE 'reader_role'@'%' TO 'api_user'@'%' - 激活多个角色:
SET DEFAULT ROLE 'reader_role', 'writer_role' TO 'api_user'@'%' - 该语句需由具备
APPLICATION_PASSWORD_ADMIN或SYSTEM_VARIABLES_ADMIN权限的管理员执行,普通用户无法自设 - 若用
SET PERSIST activate_all_roles_on_login = ON全局开启,新连接会默认激活所有已授予角色(但强制角色仍需单独配置mandatory_roles)
验证角色是否生效不能只看 SHOW GRANTS
SHOW GRANTS FOR 'api_user'@'%' 默认不显示角色继承的权限,容易误判配置失败。
- 查角色本身有哪些权限:
SHOW GRANTS FOR 'reader_role'@'%' - 查用户通过某角色获得的实际权限:
SHOW GRANTS FOR 'api_user'@'%' USING 'reader_role'(USING后必须是已绑定且有效的角色名) - 确认当前会话是否激活:
SELECT CURRENT_ROLE(),返回NULL就说明根本没激活 - 检查角色绑定关系:
SELECT * FROM mysql.role_edges WHERE to_user = 'api_user' AND to_host = '%'
最容易被忽略的是:角色名的主机部分必须精确匹配;GRANT 'role'@'%' TO 'user'@'localhost' 和 SET DEFAULT ROLE 'role'@'%' TO 'user'@'localhost' 会因 host 不一致而静默失败——这种错不会报错,但权限就是不生效。











