mysql 8.0 中 show grants for current_user() 不显示角色权限,因默认不激活角色且该命令不展开角色继承权限;必须通过 set default role 或 alter user 显式设置默认角色,并确保 grant 时 host 精确匹配,才能使角色权限在新连接中自动生效。

因为 MySQL 8.0 默认不激活任何角色——赋予角色(GRANT role_name TO 'user'@'host')只是把角色和用户在 mysql.role_edges 表里关联起来,但不会自动让该角色里的权限进入当前会话或后续连接。
为什么 SHOW GRANTS FOR CURRENT_USER() 看不到角色权限
MySQL 8.0 的 SHOW GRANTS 默认不展开角色继承的权限,只显示直接授予用户的权限。即使你执行了 GRANT reporter TO 'dev'@'10.20.30.%',只要没设置默认角色或手动激活,SHOW GRANTS FOR CURRENT_USER() 就不会列出 reporter 所含的 SELECT ON finance.* 等权限。
- 想确认角色是否真有权限:运行
SHOW GRANTS FOR 'reporter' - 想确认角色是否已授予该用户:查
SELECT * FROM mysql.role_edges WHERE TO_USER = 'dev' AND TO_HOST = '10.20.30.%' -
CURRENT_ROLE()返回NULL是最直接信号:说明当前会话没激活任何角色
必须显式设置默认角色才能自动生效
SET DEFAULT ROLE 是唯一能让角色权限在下次登录时自动加载的操作,但它有硬性前提:
- 角色必须已通过
GRANT role_name TO 'user'@'host'成功授予(host 必须完全匹配,'user'@'%'≠'user'@'localhost') - 不能对未授予权限的用户执行
SET DEFAULT ROLE ALL TO,否则报ERROR 3530 - 语句本身是持久化操作,不是临时会话级命令:执行后所有新连接都会自动激活该角色
- 若要激活多个角色:用
SET DEFAULT ROLE role1, role2 TO 'user'@'host'
当前会话临时激活 vs 登录后自动生效
两者完全独立,且不能互相替代:
-
SET ROLE 'reporter':仅对当前连接有效,断开即失效;不写入系统表,也不影响下次登录 -
ALTER USER 'dev'@'10.20.30.%' DEFAULT ROLE 'reporter':等价于SET DEFAULT ROLE,是推荐的显式写法,更清晰 - 如果同时设置了默认角色又执行了
SET ROLE,后者会覆盖前者,但仅限当前会话 - 别指望
activate_all_roles_on_login=ON能绕过SET DEFAULT ROLE——该变量仅控制“是否自动激活已设为默认的角色”,不代替设置动作
最容易被忽略的是 host 精确匹配和 mysql.role_edges 中记录的真实性。很多“赋了角色却没权限”的问题,根源不是语法错,而是 GRANT reporter TO 'dev'@'%' 和实际登录账号 'dev'@'10.20.30.5' 的 host 不一致,导致授权记录压根没被 MySQL 权限系统读到。











