

# RDS for MySQL 的基于角色的权限模型
<a name="Appendix.MySQL.CommonDBATasks.privilege-model"></a>

从 RDS for MySQL 版本 8.0.36 开始，您无法直接修改 `mysql` 数据库中的表。特别是，您不能通过对 `grant` 表执行数据操作语言（DML）操作来创建数据库用户。相反，您可以使用 MySQL 账户管理语句（例如 `CREATE USER`、`GRANT`、和 `REVOKE`）向用户授予基于角色的权限。您也无法创建其他类型的对象，例如 `mysql` 数据库中的存储过程。您仍然可以查询 `mysql` 表。如果您使用二进制日志复制，则直接对源数据库实例上的 `mysql` 表进行的更改不会复制到目标集群中。

在某些情况下，您的应用程序可能会使用快捷方式通过插入到 `mysql` 表来创建用户或其他对象。如果是这样，请更改应用程序代码以使用相应的语句，例如 `CREATE USER`。

要在从外部 MySQL 数据库迁移期间导出数据库用户的元数据，请使用以下方法之一：
+ 将 MySQL Shell 的实例转储实用程序与筛选条件一起使用，来排除用户、角色和授权。以下示例显示了要使用的命令语法。确保 `outputUrl` 为空。

  ```
  mysqlsh user@host -- util.dumpInstance(outputUrl,{excludeSchemas:['mysql'],users: true})
  ```

  有关更多信息，请参阅《MySQL 参考手册》中的 [Instance Dump Utility, Schema Dump Utility, and Table Dump Utility](https://dev.mysql.com/doc/mysql-shell/8.0/en/mysql-shell-utilities-dump-instance-schema.html)。
+ 使用 `mysqlpump` 客户端实用程序。此示例包括除 `mysql` 系统数据库中的表之外的所有表。它还包括用于重现迁移数据库中的所有 MySQL 用户的 `CREATE USER` 和 `GRANT` 语句。

  ```
  mysqlpump --exclude-databases=mysql --users
  ```

  MySQL 8.4 中不再提供 `mysqlpump` 客户端实用工具。请改用`mysqldump`。

为了简化对许多用户或应用程序的权限管理，您可以使用 `CREATE ROLE` 语句来创建具有一组权限的角色。然后，您可以使用 `GRANT` 和 `SET ROLE` 语句以及 `current_role` 函数将角色分配给用户或应用程序、切换当前角色以及检查哪些角色有效。有关 MySQL 8.0 中基于角色的权限系统的更多信息，请参阅 MySQL 参考手册中的[使用角色](https://dev.mysql.com/doc/refman/8.0/en/roles.html)。

**重要**  
我们强烈建议不要直接在应用程序中使用主用户。请遵守使用数据库用户的最佳实践，按照您的应用程序所需的最少权限创建用户。

从版本 8.0.36 开始，RDS for MySQL 包括一个具有以下所有权限的特殊角色。该角色命名为 `rds_superuser_role`。每个数据库实例的主管理用户已经获得了此角色。`rds_superuser_role` 角色包括所有数据库对象的以下权限：
+  `ALTER` 
+  `APPLICATION_PASSWORD_ADMIN` 
+  `ALTER ROUTINE` 
+  `CREATE` 
+  `CREATE ROLE` 
+  `CREATE ROUTINE` 
+  `CREATE TEMPORARY TABLES` 
+  `CREATE USER` 
+  `CREATE VIEW` 
+  `DELETE` 
+  `DROP` 
+  `DROP ROLE` 
+  `EVENT` 
+  `EXECUTE` 
+  `INDEX` 
+  `INSERT` 
+  `LOCK TABLES` 
+  `PROCESS` 
+  `REFERENCES` 
+  `RELOAD` 
+  `REPLICATION CLIENT` 
+  `REPLICATION SLAVE` 
+  `ROLE_ADMIN` 
+  `SET_USER_ID` 
+  `SELECT` 
+  `SHOW DATABASES` 
+  `SHOW VIEW` 
+  `TRIGGER` 
+  `UPDATE` 
+  `XA_RECOVER_ADMIN`

 角色定义还包括 `WITH GRANT OPTION`，以便管理用户可以将该角色授予其他用户。特别是，管理员必须授予以 MySQL 集群作为目标执行二进制日志复制所需的任何权限。

**提示**  
 要查看权限的完整详细信息，请使用以下语句。  

```
SHOW GRANTS FOR rds_superuser_role@'%';
```

 当您使用 RDS for MySQL 版本 8.0.36 和更高版本中的角色授予访问权限时，还可以通过使用 `SET ROLE role_name` 或 `SET ROLE ALL` 语句来激活角色。下面的示例演示如何操作。将适当的角色名称替换为 `CUSTOM_ROLE`。

```
# Grant role to user
mysql> GRANT CUSTOM_ROLE TO 'user'@'domain-or-ip-address'

# Check the current roles for your user. In this case, the CUSTOM_ROLE role has not been activated.
# Only the rds_superuser_role is currently in effect.
mysql> SELECT CURRENT_ROLE();
+--------------------------+
| CURRENT_ROLE()           |
+--------------------------+
| `rds_superuser_role`@`%` |
+--------------------------+
1 row in set (0.00 sec)

# Activate all roles associated with this user using SET ROLE.
# You can activate specific roles or all roles.
# In this case, the user only has 2 roles, so we specify ALL.
mysql> SET ROLE ALL;
Query OK, 0 rows affected (0.00 sec)

# Verify role is now active
mysql> SELECT CURRENT_ROLE();
+--------------------------------------------------+
| CURRENT_ROLE()                                   |
+--------------------------------------------------+
| `CUSTOM_ROLE`@`%`,`rds_superuser_role`@`%` |
+--------------------------------------------------+
```