此前带你读源码第四篇《戳这里回顾OceanBase 源码解读四事务的一生》为大家介绍了事务的外部接口相关知识。本文将介绍社区版中创建、删除租户、资源隔离的相关代码。
OceanBase 数据库是支持多租户的这里租户的概念类似于传统数据库的数据库实例。租户下可以建立数据库在租户的数据库下可以建立表。
多租户特性可以降低资源使用和维护成本。每个租户可以被赋于一定的资源比如 CPU、内存。OceanBase集群初始内置了一个系统租户 sys可以用来管理OceanBase 集群。租户的资源是分配在资源池上的通过资源配置和设定资源池可以实现对租户资源的控制。
在创建租户之前需要至少一个空闲的资源池创建资源池需要先定义每个单元的规格。
我们称一个资源单元为 UNITUNIT是最小的资源分割单位。一个资源池中包含若干 UNIT一台Observer 只能有一个资源池的一个 UNIT。一个资源池只能赋予给一个租户一个租户可以包含多个资源池。
略过 SQL 的解析和处理这部分的主体代码都是在 rootserver 目录下统一的入口请点击阅读原文查看。
大概涉及到以下接口
create resource unit
SQL参考
这部分代码比较简单创建一个 UNIT 规格就是把这个规格记录在内部表__all_unit_config。在没有任何资源池引用这个规格时它并没有什么用可以随意的修改或者删除。
代码上可以从这个接口去阅读
int ObRootService::create_resource_unit(const obrpc::ObCreateResourceUnitArg
创建资源池需要定义这个资源池引用的规格这个资源处分布在哪几个 zone每个 zone 存在几个 UNIT这里的重点是要在哪些 server 上把这部分 UNIT 分配出来。
可以从这个接口去阅读
int ObRootService::create_resource_pool(const obrpc::ObCreateResourcePoolArg
__all_resource_pool、__all_unit。
具体如何分配 UNIT 可以参考这个接口
int ObUnitManager::allocate_pool_units(ObISQLClient
CREATE TENANT [IF NOT EXISTS] tenantname [tenant_characteristic_list] [opt_set_sys_var]tenant_characteristic_list: tenant_characteristic [, tenant_characteristic...]tenant_characteristic: COMMENT string |{CHARACTER SET | CHARSET} [] charsetname |COLLATE [] collationname|REPLICA_NUM [] num |ZONE_LIST [] (zone [, zone…]) |PRIMARY_ZONE [] zone |DEFAULT TABLEGROUP [] {NULL | tablegroup}|RESOURCE_POOL_LIST [](poolname [, poolname…])|LOGONLY_REPLICA_NUM [] num|LOCALITY [] locality descriptionopt_set_sys_var:{ SET | SET VARIABLES | VARIABLES } system_var_name expr [,system_var_name expr] ...
资源池创建成功后就可以引用这个资源池创建租户。创建租户分为三个事务为什么要分为三个事务呢我们可以带着这个问题从这个接口开始阅读代码
int ObRootService::create_tenant(const ObCreateTenantArg
int ObDDLService::create_tenant_env(share::schema::ObSchemaGetterGuard NULL);
事务一
确定租户使用的资源池并把这些资源池都赋予给这个租户。构建了ObTenanSchema包括租户的 localityprimary_zone等信息。创建这个租户的系统表的 Partition
事务二
这个事务是构建了租户内部的数据例如系统表的元信息内部用户database 等。大概包括以下内容
这个事务结束后实际上租户已经创建完成可以正常使用。
事务三
这个事务就是修改了租户的创建从CREATING到NORMAL。给出一个创建租户结束的标记。
为什么创建租户需要三个事务因为事务不能跨租户。
drop tenant
SQL参考
DROP TENANT [IF EXISTS] tenant_name [FORCE];
删除租户实际上只删除了租户的ObTenanSchema。租户删除了租户引用的资源池还是存在的
int ObRootService::drop_tenant(const ObDropTenantArg
DROP RESOURCE POOL poolname
只有没有租户引用的资源池才可以被删除
int ObRootService::drop_resource_pool(const obrpc::ObDropResourcePoolArg
DROP RESOURCE UNIT unitname
只有没有资源池引用的规格才可以被删除只涉及到内部表的修改接口如下
int ObRootService::drop_resource_unit(const obrpc::ObDropResourceUnitArgCPU 隔离和调度的代码位于 src/observer/omt。
所有 OceanBase 的一级数据库对象如表索引database/schema用户等在系统表和内存中都是用一个 uint64 作为 ID 标识的。为了实现方便很多时候在内存中这些 ID 里编码了租户 ID前 24bit是租户ID。
如果大家有任何疑问可以通过以下方式与我们进行交流
微信群扫码添加小助手将拉你进群哟
钉钉群33254054
github
https://github.com/oceanbase/oceanbase
博客问答
https://www.oceanbase.com/community/answer
gitee
https://gitee.com/oceanbase