MySQL 8.0角色权限生效必须完成创建→授权→绑定→激活四步闭环;漏掉SET DEFAULT ROLE或连接池未配置sessionVariables=default_role,应用连接即报ERROR 1142。

MySQL 8.0 的角色权限控制不是建完角色就自动生效,必须完成「创建→授权→绑定→激活」四步闭环;漏掉 SET DEFAULT ROLE 或没配连接池初始化语句,应用一连就报 ERROR 1142 (42000)。
CREATE ROLE 和 GRANT 权限给角色时的硬约束
角色名不能和现有用户名冲突,比如已有 'admin'@'%',再执行 CREATE ROLE 'admin' 会失败。角色本身不带密码、不可登录,只作权限容器使用。
-
GRANT SELECT ON finance.reports TO 'reporter'是合法的;但GRANT SELECT(col1) ON finance.reports TO 'reporter'会报错——角色不支持列级授权 - 所有
GRANT到角色的语句都不能加WITH GRANT OPTION,MySQL 明确禁止(报ERROR 3526) - 确认操作权限:执行者需有
CREATE ROLE和对应库表的GRANT OPTION,普通 DBA 账号默认没有CREATE ROLE权限
用户绑定角色后仍无权限?缺的是激活,不是授权
执行 GRANT 'reporter' TO 'app_user'@'10.20.30.%' 只在 mysql.role_edges 插入一条绑定记录,此时 CURRENT_ROLE() 返回 NULL,权限完全不可见。
- 生产环境必须补上:
SET DEFAULT ROLE 'reporter' TO 'app_user'@'10.20.30.%' - 若用
SET DEFAULT ROLE ALL TO ...,会把该用户所有已授角色全激活,易违反最小权限原则 -
SHOW GRANTS FOR 'app_user'@'10.20.30.%'永远不显示角色权限——查权限得用SHOW GRANTS FOR 'app_user'@'10.20.30.%' USING 'reporter'或登录后查CURRENT_ROLE()
连接池场景下角色失效的典型原因与修复
HikariCP、Druid 等连接池复用物理连接,旧连接未激活角色,新连接又未必走初始化流程,导致权限时有时无。
面向 CRM 系统的 MySQL 8 数据库模式设计。当用户需要为客户关系管理(CRM)系统设计、评审、优化或生成数据库模式时,应使用此项技能。
- Java JDBC 连接串加参数:
sessionVariables=default_role=reporter(推荐)或connection-init-sql=SET ROLE 'reporter' - 避免依赖
DEFAULT ROLE单点配置——连接池可能跳过用户默认角色加载逻辑 - 验证方式:从连接池取一个连接,立即执行
SELECT CURRENT_ROLE(),返回值必须是'reporter'才算到位
mandatory_roles 配置的隐性风险与验证盲区
设了 mandatory_roles 后,所有新连接(含 root)都会强制带上指定角色,且无法被 REVOKE 或 DROP ROLE 清除——这是最易被忽略的全局后门。
- 正确写法:
SET PERSIST mandatory_roles = '''reporter''@''%'''(注意三重单引号转义) -
SHOW GRANTS FOR 'app_user'@'10.20.30.%'完全不体现 mandatory role,只能靠CURRENT_ROLE()查到 - 清空唯一方式:
SET PERSIST mandatory_roles = '';重启 MySQL 不会清除它,SET GLOBAL也不持久
角色权限的“生效”始终是会话级行为,不存在跨连接继承;哪怕配置了 DEFAULT ROLE,连接池里复用的老连接依然不会自动重载,这点在灰度发布或连接长期存活的场景中极易踩坑。










