MySQL 8.0+才支持角色管理,需用CREATE ROLE;5.7仅能模拟,执行该语句会报错。角色授予权限后须显式赋予用户并激活(SET ROLE或SET DEFAULT ROLE),否则无效;REVOKE操作对象是角色名还是用户名决定影响范围;慎用WITH GRANT OPTION以防权限失控。

MySQL 8.0+ 角色管理必须用 CREATE ROLE,5.7 及以前不支持角色
MySQL 原生角色功能从 8.0.1 版本才正式引入,5.7 只能靠用户级权限模拟,硬套角色概念会出错。如果你执行 CREATE ROLE 'app_reader' 报错 ERROR 1064 (42000),大概率是版本太低。先确认版本:SELECT VERSION();。5.7 用户权限需直接赋给具体账户,比如 GRANT SELECT ON mydb.* TO 'u1'@'%';。
给角色授予权限后,必须显式把角色赋予用户才能生效
角色本身不自动绑定到任何用户,即使你执行了 GRANT SELECT, INSERT ON app_db.* TO 'app_writer'@'%';,这个角色也处于“闲置”状态。必须再走一步:GRANT 'app_writer'@'%' TO 'dev_user'@'localhost';,然后让该用户激活角色:SET ROLE 'app_writer'@'%';(会话级)或设为默认:SET DEFAULT ROLE 'app_writer'@'%' TO 'dev_user'@'localhost';。漏掉这步,用户登录后查 SHOW GRANTS; 看不到任何权限。
REVOKE 某个权限时,注意它只影响当前授予对象,不级联撤销角色内权限
假设你给角色 app_reader 授予了 SELECT,又把这个角色给了 3 个用户。之后执行 REVOKE SELECT ON app_db.* FROM 'app_reader'@'%';,角色权限被移除,所有通过该角色获得 SELECT 的用户都会立刻失去该权限。但如果你误写成 REVOKE SELECT ON app_db.* FROM 'user1'@'%';,那只影响 user1 的直授权限,对角色和其它用户完全无感。关键区别在于 FROM 后面跟的是角色名还是用户名。
生产环境慎用 WITH GRANT OPTION,尤其在角色上
给角色加 WITH GRANT OPTION(如 GRANT UPDATE ON sales.* TO 'mgr_role' WITH GRANT OPTION;)等于授权该角色的持有者可以再转授 UPDATE 权限——包括转授给新用户、甚至新建角色。权限链越拉越长,审计和回收难度指数上升。更危险的是,如果某个用户同时拥有多个带 GRANT OPTION 的角色,他可能组合出意料外的高危权限。线上库建议所有角色权限都不带 GRANT OPTION,提权操作统一走 DBA 审批流程。
角色不是魔法开关,它只是权限的容器;容器空着没用,装进去不发钥匙也没用,发了钥匙不告诉用户怎么用还是白搭。最常被忽略的其实是 SET DEFAULT ROLE 这一步——很多团队配置完角色就以为结束了,结果开发连 SELECT 都报 Access denied,查半天才发现用户根本没激活角色。


















