MySQL 8.0中CREATE ROLE报ERROR 3719是因activate_all_roles_on_login默认关闭且缺ROLE_ADMIN权限,须由root执行SET GLOBAL activate_all_roles_on_login = ON、GRANT ROLE_ADMIN、FLUSH PRIVILEGES,并为用户显式SET DEFAULT ROLE才能生效。

CREATE ROLE 报错 ERROR 3719 或权限不足,先检查 activate_all_roles_on_login 是否启用
这不是语法问题,而是 MySQL 8.0 默认关闭角色功能。即使版本 ≥ 8.0.1,CREATE ROLE 也会报 ERROR 3719 (HY000) 或静默失败。必须由 root 或高权限用户执行:
SET GLOBAL activate_all_roles_on_login = ON;GRANT ROLE_ADMIN ON *.* TO 'admin_user'@'%';FLUSH PRIVILEGES;
注意:activate_all_roles_on_login 是动态变量,重启后失效,必须写入 my.cnf 的 [mysqld] 段下才持久化。
GRANT 角色给用户后权限仍不生效,缺了 SET DEFAULT ROLE 这一步
GRANT 'app_reader'@'%' TO 'user1'@'localhost' 只是把角色“挂载”到用户身上,在 mysql.role_edges 表中插入记录,不会自动激活。用户登录后 CURRENT_ROLE() 返回 NONE,所有权限都不可见。
- 管理员需显式执行:
SET DEFAULT ROLE 'app_reader'@'%' TO 'user1'@'localhost'; - 若用户有多个角色且需全部激活(慎用):
SET DEFAULT ROLE ALL TO 'user1'@'localhost'; - 主机名必须严格匹配:角色是
'app_reader'@'%',就不能对'user1'@'localhost'执行该语句,否则报错
SET DEFAULT ROLE 需要 SYSTEM_VARIABLES_ADMIN 或 ROLE_ADMIN 权限,普通用户无法自行执行。
SHOW GRANTS 看不到角色权限,不是配置失败,是设计如此
SHOW GRANTS FOR 'user1'@'localhost' 默认只显示直授权限(如 USAGE),完全不展开角色继承链——这是 MySQL 的明确设计行为,不是配置错误。
- 查角色本身权限:
SHOW GRANTS FOR 'app_reader'@'%'; - 查用户通过某角色获得的权限:
SHOW GRANTS FOR 'user1'@'localhost' USING 'app_reader'@'%'; - 验证当前会话是否真正激活:
SELECT CURRENT_ROLE();,返回非NONE值才算成功
审计时如果只扫 SHOW GRANTS 输出,可能把拥有 DBA 权限的账号误判为“仅能连接”,风险极高。
连接池场景下默认角色不生效,必须配置初始化 SQL
HikariCP、Druid 等主流连接池默认不执行任何会话级设置,即使你已设好 DEFAULT ROLE,新获取的连接仍处于未激活状态,CURRENT_ROLE() 为 NONE。
- 在 JDBC URL 中加参数:
sessionVariables=default_role=app_reader@% - 或配置
connection-init-sql="SET DEFAULT ROLE 'app_reader'@'%'" - 别依赖客户端自动识别——MySQL 不会把
DEFAULT ROLE推送到每个连接上下文,必须靠初始化语句触发
最容易被忽略的是:权限变更(比如新增表授权)对已有连接完全无效,必须重连或手动 SET ROLE;而连接池往往复用长连接,导致“改了权限却没效果”的现象反复出现。


















