RDS for MySQL 的基于角色的权限模型
从 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
。 使用
mysqlpump
客户端实用程序。此示例包括除mysql
系统数据库中的表之外的所有表。它还包括用于重现迁移数据库中的所有 MySQL 用户的CREATE USER
和GRANT
语句。mysqlpump --exclude-databases=mysql --users
为了简化对许多用户或应用程序的权限管理,您可以使用 CREATE ROLE
语句来创建具有一组权限的角色。然后,您可以使用 GRANT
和 SET ROLE
语句以及 current_role
函数将角色分配给用户或应用程序、切换当前角色以及检查哪些角色有效。有关 MySQL 8.0 中基于角色的权限系统的更多信息,请参阅 MySQL 参考手册中的使用角色
重要
我们强烈建议不要直接在应用程序中使用主用户。请遵守使用数据库用户的最佳实践,按照您的应用程序所需的最少权限创建用户。
从版本 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 activemysql>
SELECT CURRENT_ROLE();+--------------------------------------------------+ | CURRENT_ROLE() | +--------------------------------------------------+ | `CUSTOM_ROLE`@`%`,`rds_superuser_role`@`%` | +--------------------------------------------------+