多租户管理与资源隔离
本文介绍了GaussDB(for MySQL)提供的多租户数据隔离以及资源隔离的相关语法和使用说明。
功能简介
GaussDB(for MySQL)提供的多租户管理功能,让数据库能够为其多个租户服务,提高数据库资源利用率。租户间实现数据隔离,不同租户能访问自己的数据。支持租户级资源隔离和用户级资源隔离,资源隔离能够避免浪费和性能扰邻。支持资源动态调整,能够及时应对不同租户或用户的业务高峰和波谷。
多租户管理功能的原理图如下:
常用概念
如表1所示为租户级和用户级的相关术语。
所属层级 |
相关术语 |
---|---|
租户级 |
租户(Tenant):租户的层级结构在数据库实例之下,在数据库与用户之上。租户是为了数据隔离、资源隔离提出的概念,实际访问数据库还是需要以用户的身份去访问。
资源配置(resource_config):为实现租户级资源隔离所提出的概念,一个resource_config描述了对应租户下能够使用的资源。当前仅支持通过设置min_cpu和max_cpu实现对CPU资源上下限进行配置,内置以下资源配置:
租户按照数据隔离的维度将租户分为系统租户和普通租户。 系统租户(sys_tenant):系统租户是为了适配原有模式下用户的使用,原有数据库实例中的用户默认属于系统租户,也可以称为系统用户。当通过系统租户下的用户连接数据库时,若该用户拥有对应的数据库实例访问权限,即可访问所有租户下的数据库实例。 普通租户(user_tenant):普通租户需要在系统租户下进行创建,普通租户下的数据库实例与用户完全隔离,无法互相访问,并且普通租户无法访问系统租户下的数据库实例。 租户可使用的资源由租户级资源配置(当前仅支持CPU资源)确定,按照资源隔离的维度又可以将租户分为独占型租户和共享型租户。 独占型租户:租户关联的资源配置中的min_cpu>0,需要保证在任何时刻该租户的CPU核数不小于min_cpu。 共享型租户:关联到特定的资源配置shared_tenants_config的租户,此资源配置的min_cpu=0。系统优先保证独占租户的资源请求,然后将剩余资源配给共享租户。同时,系统保留一部分CPU资源(由参数mt_shared_cpu_reserved进行配置)给共享租户,保证共享租户在CPU争抢时不会出现无法获取到资源的情况。独占型租户和共享型租户可以通过修改关联的资源配置进行相互转换。 |
用户级 |
用户的层级结构在数据库实例和租户之下,同一个租户可以拥有多个用户。多租户功能没有修改用户间的数据隔离,只增加了用户级的资源管理机制。
图2 用户级资源配置关系图
资源消费组(consumer_group) 多个用户可以归属到同一个资源消费组,这些用户共享资源消费组所关联的资源。 资源计划指令(plan_directive) 资源计划指令描述了一个资源消费组具体的资源配置情况,一个资源计划指令唯一对应一个资源消费组;一个资源消费组可以关联多个资源计划指令,其中至多只允许启用一个资源计划指令,为实现此功能,引入下述的资源计划的概念。 资源计划(plan) 用于控制资源计划指令的启用或禁用。一个资源计划关联一个或多个资源计划指令。启用或禁用资源计划可使对应的资源计划指令生效或失效,同一个租户内至多只能启用一个资源计划。 |
使用须知
- 多租户管理与资源隔离功能支持租户级数据隔离、租户级CPU资源隔离、用户级CPU资源隔离。
- 多租户管理与资源隔离功能需要GaussDB(for MySQL)实例内核版本为2.0.57.240900及以上。
- 开启多租户管理与资源隔离前必须开启thread pool功能。
- 开启多租户管理与资源隔离功能前,要求实例中的数据库名称、用户名称、表空间名称不能包含@字符。
- Serverless不支持多租户管理与资源隔离功能。
- 租户跨实例迁移:
- Binlog:
目前Binlog没有实现租户隔离,如果允许普通租户拉取Binlog会破坏租户间数据隔离,因此当前禁止普通租户下的用户拉取Binlog。
- 数据库代理:
因HTAP标准版和轻量版不支持带@字符的数据库,普通租户下的数据库迁移到该类HTAP引擎时会更改目标端库名,但数据库代理的自动行存/列存引流功能要求源端和目标端的库名一致,因此普通租户创建的数据库将无法使用数据库代理的自动行存/列存引流功能。
- 备份恢复:
- 兼容性:
- 先开启后关闭多租开关,创建数据库、用户和表空间时,名称中不能包含@字符。
- 普通租户下,数据库名称最大长度由64降低为50,用户名称最大长度由32降低为20。
- 系统库mysql、sys暂不开放给普通租户。
- 普通租户下,系统库performance_schema里的表使用用户名或库名做条件查询时,需要使用模糊搜索。
- 系统租户的root用户可以kill其他用户的session;普通租户的用户,只能kill当前用户的session。
- 多租实例不支持全文索引。
开启多租户模式
- 登录管理控制台。
- 单击管理控制台左上角的,选择区域和项目。
- 在页面左上角单击,选择 。
- 在实例管理页面,单击目标实例名称,进入实例概览页面。
- 在实例信息区域,单击多租户隔离右侧,在弹框中单击“确认”,开启多租户隔离功能。
开启多租户隔离前要求存量的数据库名称、用户名称以及表空间名称不能包含@字符,否则会开启失败。
资源管理
资源配置(resource_config)和租户是一对多的关系,当某一租户绑定此资源配置时便可限制此租户下用户使用的CPU资源。
- 创建资源配置
CREATE resource_config config_name MAX_CPU [=] {max_cpu_value} [MIN_CPU [=] {min_cpu_value}];
- 更新资源配置
ALTER resource_config config_name MAX_CPU [=] {max_cpu_value} [MIN_CPU [=] {min_cpu_value}];
- 删除资源配置
DROP resource_config config_name;
- 查看资源配置
SELECT * FROM information_schema.DBA_RSRC_TENANT_RESOURCE_CONFIGS;
- 仅在高权限root用户下可使用。
- 参数说明:
- config_name: 资源配置名称。最大长度为64,仅支持包含大写字母、小写字母、数字或下划线。
- MAX_CPU:绑定该资源配置的租户能够使用的最大CPU资源,单位为核数,最小值为0.1,最大值为实例规格中的CPU核数,可查看变量mt_flavor_cpu获取。粒度0.1。
- MIN_CPU:在CPU资源争抢时,承诺分配给绑定该资源配置的租户的CPU资源,单位为核数,为可选项。默认等于MAX_CPU,最小值为0.1,最大值不超过MAX_CPU。粒度为0.1。(注意:shared_tenants_config为系统内置的资源配置,其MIN_CPU为0)。承诺分配给租户的CPU资源遵循按需分配策略,不会预留,例如:承诺给租户分配1U,但如果租户业务空闲,只会使用0.3U,则剩余的0.7U会按需分配给其他租户。
- 更新resource_config时,如果该resource_config已经绑定租户,且更新后MIN_CPU值大于原有的MIN_CPU值,则需要校验修改后的值是否满足资源约束,否则不做资源约束校验。
- 删除resource_config时,若租户正在使用该资源配置,则无法进行删除操作。
- CPU争抢时,租户间资源分配会尽量按照租户的MIN_CPU分配资源,但存在一定的误差,误差通常在1U以内。
- 各租户下的实例的读写性能峰值并非和分配到的CPU资源呈线性关系。例如16U的实例分配给2个租户的MAX_CPU均为8U,那么两个租户同时满载跑业务的总共的TPS将达不到8U实例的2倍。即租户下的实例性能可能比同等规格的非多租实例的性能稍低。
租户管理
创建租户时,需要绑定已经创建的资源配置(resource_config),以此限制该租户下用户使用的CPU资源。
- 创建租户
CREATE TENANT tenant_name RESOURCE_CONFIG config_name [COMMENT [=] 'comment_string'];
- 更改租户
ALTER TENANT tenant_name RESOURCE_CONFIG config_name [COMMENT [=] 'comment_string'];
- 删除租户
DROP TENANT tenant_name;
- 查看租户
SELECT * FROM information_schema.DBA_RSRC_TENANT;
- 仅在高权限root用户下可使用。
- 创建租户
- tenant_name长度不超过10个字符,仅支持包含小写字母、数字或下划线_。
- 创建租户会进行资源约束检查,需要保证所有租户的资源配置中MIN_CPU之和满足资源约束。
- 如果租户绑定shared_tenants_config,则租户成为共享租户,否则是独占租户。当发生资源争抢时,优先满足独占租户的MIN_CPU承诺资源需求,剩余的资源再由共享租户和独占租户争抢。
- 更改租户resource_config
- 如果新绑定的resource_config的MIN_CPU值大于等于原有resource_config的MIN_CPU值时,会进行资源约束检查,需要保证所有租户的资源配置中MIN_CPU之和满足资源约束。
- 如果独占租户新绑定到shared_tenants_config,则成为共享租户,将同时删除租户下的用户级资源隔离相关的配置。
- 删除租户
- 需要保证租户下的DB和用户已经被删除,否则,无法删除租户。
- 删除租户的同时将删除租户关联的用户级资源隔离相关的配置。
用户管理
开启多租模式后,用户分为系统租户下的用户和普通租户下的用户。存量的用户均属于系统租户,新创的用户根据接口语义属于系统租户或者普通租户。
- 在系统租户下管理用户
创建系统租户下的用户:
CREATE user [IF NOT EXISTS] user_name@host;
创建普通租户下的用户:
CREATE user [IF NOT EXISTS] 'user_name@tenant_name'@host;
重命名用户
重命名系统租户下的用户:
RENAME USER user_from@host1 TO user_to@host2;
重命名普通租户下的用户:
RENAME USER 'user_from@tenant_name'@host1 TO 'user_to@tenant_name'@host2;
删除用户
删除系统租户下的用户:
DROP USER [IF EXISTS] user_name@host;
删除普通租户下的用户:
DROP USER [IF EXISTS] 'user_name@tenant_name'@host;
授权用户
为用户'user_1@tenant_1'@'%'授予租户tenant_1下的priv_type权限:
GRANT priv_type ON *.* to 'user_1@tenant_1'@'%' with grant option;
查看权限:
SHOW grants for 'user_1@tenant_1'@'%';
- 在普通租户下管理用户
创建当前租户下的用户:
CREATE user [IF NOT EXISTS] user_name@host;
重命名用户
RENAME USER user_from@host1 TO user_to@host2;
删除用户
DROP USER [IF EXISTS] user_name@host;
授权用户
为用户user1授予当前租户下的priv_type权限:
GRANT priv_type ON *.* to 'user_1'@'%' with grant option;
查看权限:
SHOW grants for 'user_1';
- 以系统租户身份创建或删除普通租户下的用户时,需要以user_name@tenant_name的方式对用户进行操作。
- 普通租户下的用户名称的长度被限制为不超过20个字符。
- 租户内不可以创建部分特殊用户:mysql.sys, mysql.session, mysql.infoschema以及参数rds_reserved_users中保留的用户。
- 在系统租户下,对普通租户下的用户重命名时,需要保证user_from和user_to中的tenant_name相同,如不相同,则接口返错。
- 多租户隔离特性关闭时,无法重命名普通租户下的用户。
数据库管理
数据库分为系统租户下的数据库和普通租户下的数据库。系统租户可以访问所有数据库,普通租户只能访问属于自己的数据库。
- 在系统租户下管理数据库
创建系统租户的数据库:
CREATE DATABASE [IF NOT EXISTS] `db_name`;
创建普通租户的数据库:
CREATE DATABASE [IF NOT EXISTS] `db_name@tanant_name`;
删除数据库
删除系统租户的数据库:
DROP DATABASE [IF EXISTS] `db_name`;
删除普通租户的数据库:
DROP DATABASE [IF EXISTS] `db_name@tanant_name`;
- 在普通租户下管理数据库
CREATE DATABASE [IF NOT EXISTS] 'db_name';
删除当前租户的数据库:
DROP DATABASE [IF EXISTS] 'db_name';
- 在系统租户下需要以db_name@tenant_name的方式对普通租户下的数据库进行操作。
- 系统库SYS、MYSQL暂不允许普通租户访问。
- 租户内不可以创建部分特殊DB:INFORMATION_SCHEMA, PERFORMANCE_SCHEMA, MYSQL, SYS, __recyclebin__。
- 存量数据库分配租户
为保证兼容性,升级或者迁移到多租实例后,存量的数据库默认属于系统租户,可以通过如下语法将存量的数据库分配给租户。此外,对于已经开启多租特性后,系统租户创建的且未分配给普通租户的数据库,也可通过如下语法分配数据库给对应租户。
数据库分配
将数据库分配给租户名为tenant_name的普通租户
ALTER DATABASE db_name TENANT = `tenant_name`;
将数据库回收到系统租户下
ALTER DATABASE db_name TENANT = ``;
查看映射关系
SELECT * FROM information_schema.DBA_RSRC_TENANT_DB;
- 仅在高权限root用户下可使用。
- 如果数据库是开启多租后创建的,以db_name@tenant_name格式命名的数据库不允许分配调用此接口,接口会返错。
- 如果tenant不存在,且不为空,接口返错。
- 通过租户下的用户连接数据库
在普通租户下,指定用户时,需要以user_name@tenant_name的形式;指定数据库时,支持db_name和db_name@tenant_name两种形式。
mysql --host=**** -u user1@tenant_1 -D db1 -p pwssword; mysql --host=**** -u user1@tenant_1 -D db1@tenant_1 -p pwssword;
连接成功后,该用户将受到对应租户下的资源限制。
用户级资源配置
租户下的用户默认共享当前租户的资源,若要进行用户级资源限制,请使用本节提供的用户级资源配置接口。
共享租户无法进行用户级资源配置。
- 资源消费组(consumer_group)管理
多个用户可以归属到同一个资源消费组(consumer_group),这些用户共享资源消费组所关联的资源,通过租户下的用户连接数据库,进行资源消费组管理。
创建消费组
dbms_resource_manager.create_consumer_group ( consumer_group CHAR(128), comment CHAR(2000));
- consumer_group:资源消费组名称,仅支持包含大写字母、小写字母、数字或下划线。
- comment:资源消费组说明,可为''。
添加用户到资源消费组/从资源消费组中移除用户
dbms_resource_manager.set_consumer_group_mapping ( attribute CHAR(128), value varbinary(128), consumer_group CHAR(128));
- attribute:要添加或修改的映射属性,当前版本仅支持USER。
- value:要添加或修改的映射属性,当前版本仅支持用户名。
- consumer_group:资源消费组名称,当参数不为空时将用户添加到资源消费组,当参数为空('')时,将用户从所在的资源消费组中移除。
删除消费组
dbms_resource_manager.delete_consumer_group ( consumer_group CHAR(128));
- consumer_group:资源消费组名称。
- 删除consumer_group的时候会同步删除该资源消费组对应的plan_directive以及consumer_group_mapping。
- 如果特性开关打开,删除用户时,会自动将用户从已关联的资源消费组中移除。当特性关闭时,删除用户时不会自动从已关联的资源消费组中移除,但不会有任何影响,当后续重新打开特性时,如果发现关联到资源消费组的用户已经被删除,会自动将这些用户从已关联的资源消费组中移除。
- 如果特性开关打开,重命名用户时,不影响用户与资源消费组的关联关系。如果特性开关关闭后,删除用户,再创建同名用户,后续打开特性,该用户依然属于原有的资源消费组。
查看资源消费组
视图DBA_RSRC_CONSUMER_GROUPS记录了资源消费组信息。如果以系统租户下的用户身份下查看,则可以查询到所有租户的资源消费组信息,如果在普通租户下查看,只能看到当前租户下的资源消费组信息。
select * from information_schema.DBA_RSRC_CONSUMER_GROUPS;
查看资源消费组和用户的关联关系
视图DBA_RSRC_GROUP_MAPPINGS记录了用户和资源消费组的关联关系。如果以系统租户下的用户身份下查看,则可以查询到所有租户的用户和资源消费组的关联关系,如果在普通租户下查看,只能看到当前租户下的用户和资源消费组的关联关系。
select * from information_schema.DBA_RSRC_GROUP_MAPPINGS;
资源计划(plan)管理
资源计划(plan)用于控制资源计划指令(plan_directive)的启用或禁用。一个资源计划关联一个或多个资源计划指令。启用或禁用资源计划可使对应的资源计划指令生效或失效,同一个租户内至多只能启用一个资源计划。
- 创建资源计划
dbms_resource_manager.create_plan ( plan_name VARCHAR(128), comment VARCHAR(2000));
- plan_name:资源计划名称,仅支持包含大写字母、小写字母、数字或下划线。
- comment:资源计划描述信息,可为''。
- 若删除当前启用的资源计划,则会将当前启用的资源计划设置为空,同时删除对应的资源计划指令(plan_directive)。
- plan默认可配置的最大数量为128,由参数mt_resource_plan_num控制。
- 启用或禁用资源计划
dbms_resource_manager.set_resource_manager_plan( plan_name VARCHAR(128));
- plan_name:资源计划名称。如果为空(''),则禁用资源计划。
- 删除资源计划
dbms_resource_manager.delete_plan ( plan_name VARCHAR(128));
- plan_name:资源计划名称。
- 删除当前正在启用的资源计划,则会将当前启用的资源计划设置为空,同时删除所关联的资源计划指令(plan_directive)。
- 查看资源计划
视图DBA_RSRC_PLANS记录资源计划的详细信息。如果在系统租户下查看,则可以查询到所有租户的资源计划,如果在普通租户下查看,只能看到当前租户下的资源计划。
SELECT * FROM information_schema.DBA_RSRC_PLANS;
资源计划指令(plan_directive)管理
资源计划指令描述了一个资源消费组具体的资源配置情况,一个资源计划指令唯一对应一个资源消费组;一个资源消费组可以关联多个资源计划指令,其中至多只允许启用一个资源计划指令,启用资源计划指令由上述启用资源计划实现。
- 创建资源计划指令
dbms_resource_manager.create_plan_directive ( plan CHAR(128), group_or_subplan CHAR(128), comment VARCHAR(2000), mgmt_p1 bigint(20), utilization_limit bigint(20));
- plan:资源计划(plan)的名称。
- group_or_subplan:资源消费组(consumer_group)的名称。
- comment:资源计划指令的描述信息,可为''。
- mgmt_p1:在CPU资源争抢的情况下,承诺分配给本资源消费组的CPU资源占所属租户总CPU资源的比例,取值范围[0, 100],表示使用所属租户100%的CPU。同一租户且同一个资源计划(plan)所关联的所有资源计划指令(plan_directive)的mgmt_p1总和不超过100。当租户内的各个资源消费组发生CPU争抢,优先保证承诺分配各个资源消费组CPU资源,剩余的CPU资源由各个资源消费组争抢。承诺分配给资源消费组的CPU资源也遵循按需分配策略,不会预留,例如:承诺给当前资源消费组20%的CPU资源,但当前资源消费组业务量较少,只需要5%的CPU资源,则剩余的15%的CPU资源会按需分配给其他资源消费组。
- utilization_limit:资源消费组可用的CPU资源的上限占所属租户总CPU资源的比例,取值范围为 [1, 100]。表示最大可使用租户全部CPU资源,如果取值为70则表示最大可使用租户70%的CPU资源。
- 同一资源消费组下的用户共享当前启用的资源计划指令配置的资源。例如:同一租户下的用户user1和user2都添加到资源消费组consumer_group1中,consumer_group1当前启用的资源计划指令的UTILIZATION_LIMIT为70,mgmt_p1为10,则user1和user2可使用的CPU资源总和最大为当前租户70%,CPU争抢时,保证user1和user2可获得的CPU资源总和为当前租户10%。
- 更新资源计划指令
dbms_resource_manager.update_plan_directive ( plan CHAR(128), group_or_subplan CHAR(128), new_comment VARCHAR(2000), new_mgmt_p1 bigint(20), new_utilization_limit bigint(20));
- plan:资源计划(plan)的名称。
- group_or_subplan:资源消费组(consumer_group)的名称。
- comment:资源计划指令的描述信息,可为''。
- mgmt_p1:在CPU资源争抢的情况下,承诺分配给本资源消费组的CPU资源占所属租户总CPU资源的比例,取值范围[0, 100],表示使用所属租户100%的CPU。同一租户且同一个资源计划(plan)所关联的所有资源计划指令(plan_directive)的mgmt_p1总和不超过100。当租户内的各个资源消费组发生CPU争抢,优先保证承诺分配各个资源消费组CPU资源,剩余的CPU资源由各个资源消费组争抢。承诺分配给资源消费组的CPU资源也遵循按需分配策略,不会预留,例如:承诺给当前资源消费组20%的CPU资源,但当前资源消费组业务量较少,只需要5%的CPU资源,则剩余的15%的CPU资源会按需分配给其他资源消费组。
- utilization_limit:资源消费组可用的CPU资源的上限占所属租户总CPU资源的比例,取值范围为 [1, 100]。表示最大可使用租户全部CPU资源,如果取值为70则表示最大可使用租户 70%的CPU资源。
- 同一资源消费组下的用户共享当前启用的资源计划指令配置的资源。例如:同一租户下的用户user1和user2都添加到资源消费组consumer_group1中,consumer_group1当前启用的资源计划指令的UTILIZATION_LIMIT为70,mgmt_p1为10,则user1和user2可使用的CPU资源总和最大为当前租户70%,CPU争抢时,保证user1和user2可获得的CPU资源总和为当前租户10%。
- 删除资源计划指令
dbms_resource_manager.delete_plan_directive ( plan CHAR(128), group_or_subplan VARCHAR(128));
- plan:资源计划(plan)的名称。
- group_or_subplan:资源消费组(consumer_group)的名称。
- 删除正在启用的plan_directive, 将导致对应用户的资源配置失效。
- 查看资源计划指令
DBA_RSRC_PLAN_DIRECTIVES记录资源计划指令的详细信息。如果在系统租户下查看,则可以查询到所有租户的资源计划指令,如果在普通租户下查看,只能看到当前租户下的资源计划指令。
SELECT * FROM information_schema.DBA_RSRC_PLAN_DIRECTIVES;
清空用户级配置
dbms_resource_manager.clear_all_configs();
CPU使用率统计
- 用户级CPU使用率
新增information_schema.cpu_summary_by_user视图,用于显示各个资源消费组的CPU使用信息,在系统租户下会显示所有租户的所有资源消费组的CPU使用信息,在普通租户下,只会显示当前租户的所有资源消费组的CPU使用信息,具体使用如下:
SELECT * FROM information_schema.cpu_summary_by_user;
- 查询结果中的列名说明:
CONSUMER_GROUP:资源消费组名称。
CPU_USAGE:资源消费组的CPU使用率,为使用的CPU占所在实例总CPU的比例。例如4U的实例中, 资源消费组实际用了2U, 那么CPU_USAGE为50%。
CPU_USAGE_RELATIVE:资源消费组的CPU相对使用率,为使用的CPU占所在租户配置的MAX_CPU的比例。例如,当前租户的max_cpu为4U, 而资源消费组实际用了2U, 那么CPU_USAGE_RELATIVE为50%。
INCLUDED_USERS:属于此资源消费组中的用户名。
- 独占租户会创建一个默认的资源消费组default_group,租户下所有未绑定具体资源消费组的用户都会归属到default_group,default_group默认可使用租户的所有CPU资源,当租户内CPU争抢时,优先保证承诺分配给其他资源消费组的CPU资源,剩余的CPU资源分配给default_group。
- 查询结果中的列名说明:
- 租户级CPU使用率
新增information_schema.cpu_summary_by_tenant视图,用于显示各租户的CPU使用信息,在系统租户下会显示所有租户的CPU使用信息,在普通租户下,只会显示当前租户的CPU使用信息,具体使用如下:
SELECT * FROM information_schema.cpu_summary_by_tenant;
- 查询结果中的列名说明:
TENANT_TYPE:租户类型,exclusive表示独占租户,shared表示共享租户。
CPU_USAGE:租户的CPU使用率,为使用的CPU占所在实例总CPU的比例。例如4U的实例中, 租户实际用了2U, 那么CPU_USAGE为50%。
CPU_USAGE_RELATIVE:租户CPU相对使用率,为租户实际使用的CPU占配置的MAX_CPU的占比。例如,当前租户的max_cpu为4U, 而租户实际用了2U, 那么CPU_USAGE为50%。
- 在满足所有独占租户MIN_CPU所配置的CPU资源后,所有的共享租户共享剩余的CPU资源,所以视图中所有的共享租户的CPU使用率一样,为所有共享租户的CPU使用率的总和。
- 查询结果中的列名说明: