MySQL 8.0角色需四步闭环:启用支持→创建角色→授权给角色→SET DEFAULT ROLE激活;漏任一步均导致CURRENT_ROLE()返回NULL、权限不生效。

CURRENT_ROLE() 返回 NULL?说明角色权限根本没生效——MySQL 8.0 的角色不是建完就自动可用的“快捷方式”,必须走完四步闭环:启用支持 → 创建角色 → 授权给角色 → 绑定并激活(SET DEFAULT ROLE),漏掉任何一步,用户照样 Access denied。
CREATE ROLE 报错 ERROR 1064 或 ERROR 3719 怎么办
这不是语法写错了,而是环境压根没准备好:
-
ERROR 1064:运行SELECT VERSION();确认版本,低于8.0.1直接放弃角色,改用传统GRANT SELECT ON db.* TO 'u'@'%'; -
ERROR 3719(提示'role_admin'@'%'is not set as a role):说明全局开关未开,必须由root执行:SET GLOBAL activate_all_roles_on_login = ON;<br>GRANT ROLE_ADMIN ON *.* TO 'admin_user'@'%';<br>FLUSH PRIVILEGES;
该变量重启失效,生产环境务必在my.cnf的[mysqld]段下加:activate_all_roles_on_login=ON
GRANT SELECT ON db.* TO 'role_name' 和 GRANT 'role_name' TO 'user' 是两回事
这两步不能合并、不能跳过、顺序不能反:
- 第一步是“填充角色”:
GRANT SELECT, INSERT ON app_db.* TO 'dev_role'@'%';—— 权限只存进角色,不作用于任何人 - 第二步是“绑定用户”:
GRANT 'dev_role'@'%' TO 'dev1'@'10.20.%';—— 只往mysql.role_edges插记录,SHOW GRANTS FOR 'dev1'仍只显示这行绑定语句,不会展开权限内容 - 角色名必须带主机名,
'dev_role'等价于'dev_role'@'%',但若用户是'dev1'@'localhost',而角色是'dev_role'@'%',后续SET DEFAULT ROLE会因 host 不匹配失败 - 角色不支持列级授权:
GRANT SELECT(id) ON t1 TO 'dev_role'直接报ERROR 1142
批量分配角色必须脚本生成逐条语句,不能靠一条 SQL 完成
MySQL 不支持 GRANT 'dev_role' TO 'u1','u2','u3' 这类语法。必须逐条生成或脚本驱动,且每个用户 host 必须精确匹配:
安装、修复、更新或打包一个基于 Python 和 PyMySQL 实现的 Windows `mysql` 命令。适用于用户希望在 PowerShell/CMD 中输入 `mysql` 时重定向到 Python 实现、需要交互式输入 MySQL 连接信息、需要同步到当前用户本地 bin 目录,或需要将该能力封装成可公开复用的 Codex skill。
- 确认用户存在:
SELECT User, Host FROM mysql.user WHERE User LIKE 'dev_%' AND Host = '10.20.%'; - 生成批量语句(用
SELECT CONCAT()):SELECT CONCAT('GRANT dev_role TO ''', User,'''@''', Host,''';')<br>FROM mysql.user<br>WHERE User LIKE 'dev_%' AND Host = '10.20.%'; - 导出后执行:
mysql -u root -p - 用户含特殊字符(如
dev-team)必须用反引号:GRANT dev_role TO `dev-team`@'10.20.%';
SET DEFAULT ROLE 是权限真正生效的临门一脚
即使 GRANT 'dev_role' TO 'dev1'@'10.20.%' 执行成功,用户登录后仍被拒?CURRENT_ROLE() 返回 NULL?问题几乎一定出在这步没做:
- 必须由具备
SYSTEM_VARIABLES_ADMIN或APPLICATION_PASSWORD_ADMIN权限的管理员执行:SET DEFAULT ROLE 'dev_role'@'%' TO 'dev1'@'10.20.%'; - host 必须严格匹配:角色是
'dev_role'@'%',就不能对'dev1'@'localhost'执行该语句 - 批量操作可生成 SQL:
SELECT CONCAT('SET DEFAULT ROLE ''dev_role''@''%'' TO ''', username, '''@''%', ''';') FROM user_list WHERE dept = 'dev'; -
SET DEFAULT ROLE ALL TO 'dev1'@'%'会激活所有已授予角色,但违背最小权限原则,慎用
最容易被忽略的是:activate_all_roles_on_login 开关必须持久化进 my.cnf,否则重启 MySQL 后所有角色功能直接退化为不可用状态;另外,FLUSH PRIVILEGES 在角色权限变更后必须执行,否则新用户无法继承,已有连接也无法加载更新后的角色权限。










