create role报错error 1064或3719,是因版本低于8.0.1、activate_all_roles_on_login未启用on、缺少role_admin权限、角色名误用反引号或与用户名冲突;grant后需set default role激活,否则current_role()返回none。

CREATE ROLE 报错 ERROR 1064 或 ERROR 3719 怎么办
这不是语法写错了,是版本或配置没到位。先执行 SELECT VERSION(); —— 输出必须是 8.0.1 或更高;5.7.x 或 8.0.0 直接不支持角色功能。
确认变量已开启:SELECT @@activate_all_roles_on_login; 必须返回 ON,否则即使建成功也会在后续 GRANT 时报 ERROR 3719。
检查当前用户权限:SHOW GRANTS; 里必须包含 GRANT ROLE_ADMIN ON *.*,否则连 GRANT 'role_x' TO 'user' 都会被拒绝。
角色名别用反引号:CREATE ROLE `app_reader` 是错的,应写成 CREATE ROLE 'app_reader' 或 CREATE ROLE app_reader;角色名还区分大小写,'Analyst' 和 'analyst' 是两个角色。
角色名不能和已有用户名冲突:比如已存在 'admin'@'%' 用户,再执行 CREATE ROLE 'admin' 就会失败。
GRANT 了角色,用户登录后还是报 ERROR 1142 怎么排查
这是最常误判的问题:GRANT 只建立“绑定”,不等于“激活”。用户登录后默认角色处于未激活状态,CURRENT_ROLE() 返回 NONE 就是铁证。
必须显式执行:SET DEFAULT ROLE 'app_reader' TO 'user1'@'%';
若使用连接池(如 HikariCP),需额外配置:
– sessionVariables=default_role=app_reader
– 或 connection-init-sql="SET DEFAULT ROLE 'app_reader'"
注意:SET DEFAULT ROLE ALL TO 虽方便,但违反最小权限原则,生产环境慎用。
权限变更后,已存在的连接不会自动刷新——要么重连,要么在当前会话手动执行 SET ROLE 'app_reader'。
SHOW GRANTS 看不到角色权限,是不是授权失败了
不是失败,是设计如此。SHOW GRANTS FOR 'user'@'%' 只显示直接授予用户的权限(比如 USAGE),完全不展开角色继承的权限。
查角色本身权限:SHOW GRANTS FOR 'app_reader';
查某用户通过某角色获得的权限:SHOW GRANTS FOR 'user1'@'%' USING 'app_reader';
验证当前会话是否生效:SELECT CURRENT_ROLE();,返回非 NONE 才算真正激活。
审计时如果只扫 SHOW GRANTS 输出,可能把拥有 DBA 权限的账号当成“仅能连接”,风险极大。
如何用角色实现部门/岗位级的权限叠加
MySQL 不支持字段式权限分级(比如 role_level >= 3),也不支持嵌套继承(如 A→B→A 会报 ER_ROLE_GRANTED_TO_ITSELF),但支持角色叠加。
一个用户可被授予多个角色:GRANT 'marketing_base', 'marketing_manager', 'marketing_admin' TO 'zhangsan'@'10.0.2.%';
跨部门共享权限必须新建独立角色,例如财务要读市场报表:
– CREATE ROLE 'report_readonly';
– GRANT SELECT ON marketing.campaign_summary TO 'report_readonly';
– GRANT 'report_readonly' TO 'caiwu_user'@'%', 'market_user'@'%';
别用 GRANT SELECT ON *.* 开全局口子——哪怕只为临时查一张表,也必须精确到 db.table。
真正容易被忽略的是权限缓存机制:哪怕你刚 GRANT SELECT ON new_table TO 'app_reader',已连着的会话仍查不到新表——必须重连,或在当前会话手动 SET ROLE 'app_reader'。











