MySQL 8.0 正式引入 Role (角色) 機制,將權限集合封裝為可復用對象,解決「大量用戶逐個 GRANT、權限變更需批量操作」的運維痛點。本文通過完整案例演示 Role 全生命週期管理:創建、授權、用戶綁定、默認激活、權限遞歸變更、系統表審計。
GRANT 權限 TO Role → GRANT Role TO User → SET DEFAULT ROLE 激活SET DEFAULT ROLE 自動激活;會話中可用 SET ROLE 臨時切換CREATE DATABASE `testdb` CHARACTER SET utf8mb4;
USE `testdb`;
CREATE TABLE `t1` (`a` INT PRIMARY KEY, `b` INT);
INSERT INTO `t1` VALUES (1,2);
CREATE ROLE `priv_t1`; -- 創建角色
GRANT SELECT ON `testdb`.`t1` TO `priv_t1`; -- 角色獲得 SELECT 權限
CREATE USER 'rw_user1'@'%' IDENTIFIED BY 'User@Pass2024';
GRANT `priv_t1` TO 'rw_user1'@'%'; -- 用戶獲得角色
-- 僅顯示角色授予關係
SHOW GRANTS FOR 'rw_user1'@'%';
+---------------------------------------+
| Grants for rw_user1@% |
+---------------------------------------+
| GRANT USAGE ON *.* TO `rw_user1`@`%` |
| GRANT `priv_t1`@`%` TO `rw_user1`@`%` |
+---------------------------------------+
-- 展開角色實際權限
SHOW GRANTS FOR 'rw_user1'@'%' USING `priv_t1`;
+-------------------------------------------------+
| Grants for rw_user1@% |
+-------------------------------------------------+
| GRANT USAGE ON *.* TO `rw_user1`@`%` |
| GRANT SELECT ON `testdb`.`t1` TO `rw_user1`@`%` |
| GRANT `priv_t1`@`%` TO `rw_user1`@`%` |
+-------------------------------------------------+
-- 設置默認角色,登錄後自動激活
SET DEFAULT ROLE ALL TO 'rw_user1'@'%';
-- 或指定角色
SET DEFAULT ROLE `priv_t1` TO 'rw_user1'@'%';
-- 會話中臨時激活/切換
SET ROLE `priv_t1`; -- 激活
SET ROLE NONE; -- 取消所有角色
SET ROLE DEFAULT; -- 恢復默認角色
注意:
SET DEFAULT ROLE需重新登錄生效;SET ROLE當前會話即時生效。
-- 重新登錄 rw_user1
mysql -u rw_user1 -p
mysql> SELECT * FROM `testdb`.`t1`; -- 成功
mysql> INSERT INTO `testdb`.`t1` VALUES (2,3); -- ERROR 1142 (INSERT 權限缺失)
-- DBA 為角色新增 INSERT 權限
GRANT INSERT ON `testdb`.`t1` TO `priv_t1`;
-- rw_user1 無需重連,下一條語句即生效
mysql> INSERT INTO `testdb`.`t1` VALUES (2,3); -- 成功
-- 回收權限同樣即時生效
REVOKE INSERT ON `testdb`.`t1` FROM `priv_t1`;
mysql> INSERT INTO `testdb`.`t1` VALUES (3,4); -- ERROR 1142
-- 默認角色記錄
SELECT * FROM mysql.default_roles;
+------+----------+-------------------+-------------------+
| HOST | USER | DEFAULT_ROLE_HOST | DEFAULT_ROLE_USER |
+------+----------+-------------------+-------------------+
| % | rw_user1 | % | priv_t1 |
+------+----------+-------------------+-------------------+
-- 角色-用戶關係圖
SELECT * FROM mysql.role_edges;
+-----------+-----------+---------+----------+-------------------+
| FROM_HOST | FROM_USER | TO_HOST | TO_USER | WITH_ADMIN_OPTION |
+-----------+-----------+---------+----------+-------------------+
| % | priv_t1 | % | rw_user1 | N |
+-----------+-----------+---------+----------+-------------------+
-- 當前會話激活角色
SELECT CURRENT_ROLE();
+----------------+
| CURRENT_ROLE() |
+----------------+
| `priv_t1`@`%` |
+----------------+
CREATE ROLE `read_only`;
GRANT SELECT ON `testdb`.* TO `read_only`;
GRANT `read_only` TO `priv_t1`; -- priv_t1 繼承 read_only 權限
GRANT `priv_t1` TO 'rw_user1'@'%' WITH ADMIN OPTION;
-- rw_user1 可將 priv_t1 授予其他用戶
-- 8.0.2+ 支援 mandatory_roles 系統變量
SET PERSIST mandatory_roles = '`priv_t1`@`%`';
-- 所有用戶登錄自動獲得該角色權限,無法 SET ROLE NONE 取消
ro_report、rw_order、dba_admin),避免大而全角色role_{biz}_{perm},如 role_order_rwmysql.role_edges、default_roles,對比基線配置lower_case_table_names)DROP ROLE 會級聯回收所有用戶該角色權限FLUSH PRIVILEGES 不會刷新角色緩存,權限變更即時生效MySQL 8.0 Role 機制將權限管理從「用戶維度」升級為「角色維度」,實現權限集合的復用、變更的原子傳播、審計的結構化。配合 mandatory_roles、WITH ADMIN OPTION、角色嵌套,可構建企業級 RBAC 體系。建議所有 8.0 實例全面遷移至 Role 模式,淘汰直接對用戶 GRANT 的傳統模式。