mysql 8.0 中角色需显式授权、绑定用户并激活才能生效:先 grant 权限给角色,再 grant 角色给用户,最后 set default role 激活,否则权限不生效。

MySQL 8.0 中用 CREATE ROLE 创建角色后,GRANT 只能授予权限给角色本身,不能直接让角色“自动生效”——必须再走一步:把角色授予用户,并显式激活。
CREATE ROLE 后权限是空的,必须用 GRANT 显式填充
角色创建后不带任何权限,哪怕名字叫 admin_role 或 dba_role,它也只是一个空容器。你得用 GRANT 把具体权限塞进去:
-
GRANT SELECT, INSERT ON myapp.* TO 'app_writer';—— 这是对角色授权,不是对用户 -
GRANT ALL PRIVILEGES ON sales.* TO 'analyst_role';—— 注意:角色不支持列级权限,GRANT SELECT(col1)在角色上会报错 -
GRANT CREATE, DROP ON *.* TO 'devops_role';—— 系统级权限可以授给角色,但不能加WITH GRANT OPTION(否则报错) - 角色名含特殊字符(如
-、.)或为保留字时,必须用反引号包裹:GRANT SELECT ON logs.* TO `ci-pipeline`;
GRANT 到角色 ≠ 用户能用,必须再 GRANT 角色给用户
很多人卡在这步:执行了 GRANT SELECT ON mydb.* TO 'reader';,又执行了 GRANT 'reader' TO 'api_user'@'%';,但用户一连上去还是 Access denied。原因就一个:没激活。
-
GRANT 'reader' TO 'api_user'@'%';只是建立绑定关系,不启用权限 - 必须执行
SET DEFAULT ROLE 'reader' TO 'api_user'@'%';,让用户每次连接自动激活 - 若跳过这步,应用就得在每次连接后立刻执行
SET ROLE 'reader';,否则SHOW GRANTS;看不到任何权限 - 一个用户可被授予多个角色,
SET DEFAULT ROLE ALL TO 'dev'@'localhost';能全激活,但违反最小权限原则,慎用
SHOW GRANTS 看不到角色权限?必须加 USING 子句
执行 SHOW GRANTS FOR 'api_user'@'%';,输出可能只有空行或极简内容,但这不代表权限没生效——这是 MySQL 的默认行为:它只显示直接授予用户的权限,不展开角色继承的权限。
- 要查角色带来的真实权限,必须指定角色名:
SHOW GRANTS FOR 'api_user'@'%' USING 'reader'; - 想确认用户被授予了哪些角色,查系统表:
SELECT * FROM mysql.role_edges WHERE to_user = 'api_user' AND to_host = '%'; - 查看当前会话生效的角色:
SELECT CURRENT_ROLE();,返回NULL就说明角色根本没激活 - 误以为权限没配好,其实是忘了
USING或SET DEFAULT ROLE,这是最常被跳过的验证环节
真正容易出问题的地方不在语法,而在流程完整性:创建角色 → 给角色 GRANT → GRANT 角色给用户 → SET DEFAULT ROLE → 验证时用 USING。漏掉任意一环,权限就断在半路。特别是生产环境批量初始化时,脚本里如果没包含 SET DEFAULT ROLE 这句,所有用户都会静默失效。











