OceanBase 原始碼解讀(五):租戶的一生
厭離,畢業於西北工業大學,現主要負責 OceanBase-RS 有關工作。
原始碼是 OceanBase 的“方向盤”,本系列主要圍繞“原始碼解讀”,通過文章闡述,幫助大家理清資料庫的內在本質。本文為 OceanBase 資料庫原始碼解讀系列文章的第五篇,將介紹社群版中建立、刪除租戶、資源隔離的相關程式碼。
OceanBase 資料庫是支援多租戶的,這裡租戶的概念類似於傳統資料庫的資料庫例項。租戶下可以建立資料庫,在租戶的資料庫下可以建立表。
多租戶特性可以降低資源使用和維護成本。每個租戶可以被賦於一定的資源(比如 CPU、記憶體)。OceanBase叢集初始內建了一個系統租戶 sys,可以用來管理OceanBase 叢集。租戶的資源是分配在資源池上的,通過資源配置和設定資源池可以實現對租戶資源的控制。
在建立租戶之前,需要至少一個空閒的資源池;建立資源池需要先定義每個單元的規格。
我們稱一個資源單元為 UNIT,UNIT是最小的資源分割單位。一個資源池中包含若干 UNIT,一臺Observer 只能有一個資源池的一個 UNIT。一個資源池只能賦予給一個租戶,一個租戶可以包含多個資源池。
略過 SQL 的解析和處理,這部分的主體程式碼都是在 rootserver 目錄下,統一的入口請點選 閱讀原文檢視。大概涉及到以下介面:
create resource unit
SQL參考:
1. CREATE RESOURCE UNIT unitname
2. MAX_CPU [=] cpunum,
3. MAX_MEMORY [=] memsize,
4. MAX_IOPS [=] iopsnum,
5. MAX_DISK_SIZE [=] disksize,
6. MAX_SESSION_NUM [=] sessionnum,
7. [MIN_CPU [=] cpunum,]
8. [MIN_MEMORY [=] memsize,]
9. [MIN_IOPS [=] iopsnum]
這部分程式碼比較簡單,建立一個 UNIT 規格,就是把這個規格記錄在內部表(__all_unit_config)。在沒有任何資源池引用這個規格時,它並沒有什麼用,可以隨意的修改或者刪除。
程式碼上可以從這個介面去閱讀:
int ObRootService::create_resource_unit(const obrpc::ObCreateResourceUnitArg& arg)
create resource pool
SQL參考:
1. CREATE RESOURCE POOL poolname
2. UNIT [=] unitname,
3. UNIT_NUM [=] unitnum,
4. ZONE_LIST [=] (‘zone’ [, ‘zone’ …]);
建立資源池需要定義這個資源池引用的規格,這個資源處分佈在哪幾個 zone,每個 zone 存在幾個 UNIT,這裡的重點是要在哪些 server 上把這部分 UNIT 分配出來。
可以從這個介面去閱讀:
int ObRootService::create_resource_pool(const obrpc::ObCreateResourcePoolArg& arg)
這裡涉及到的內部表有:__all_resource_pool、__all_unit。
具體如何分配 UNIT 可以參考這個介面:
int ObUnitManager::allocate_pool_units(ObISQLClient& client, const share::ObResourcePool& pool)
create tenant
SQL參考:
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 description'opt_set_sys_var:{ SET | SET VARIABLES | VARIABLES } system_var_name = expr [,system_var_name = expr] ...
資源池建立成功後,就可以引用這個資源池建立租戶。建立租戶分為三個事務,為什麼要分為三個事務呢?
我們可以帶著這個問題從這個介面開始閱讀程式碼
int ObRootService::create_tenant(const ObCreateTenantArg& arg, UInt64& tenant_id)
三個事務可以從這個介面閱讀:
int ObDDLService::create_tenant_env(share::schema::ObSchemaGetterGuard& schema_guard, const obrpc::ObCreateTenantArg& arg,
const common::ObRegion& region, share::schema::ObTenantSchema& tenant_schema, const int64_t frozen_version,
const common::ObString* ddl_stmt_str = NULL);
事務一
確定租戶使用的資源池,並把這些資源池都賦予給這個租戶。構建了ObTenanSchema,包括租戶的 locality,primary_zone等資訊。建立這個租戶的系統表的 Partition;
事務二
這個事務是構建了租戶內部的資料,例如系統表的元資訊,內部使用者,database 等。大概包括以下內容:
這個事務結束後,實際上租戶已經建立完成,可以正常使用。
事務三這個事務就是修改了租戶的建立,從CREATING到NORMAL。給出一個建立租戶結束的標記。
為什麼建立租戶需要三個事務?因為事務不能跨租戶。
drop tenant
SQL參考:
DROP TENANT [IF EXISTS] tenant_name [FORCE];
刪除租戶實際上只刪除了租戶的ObTenanSchema。租戶刪除了,租戶引用的資源池還是存在的.
int ObRootService::drop_tenant(const ObDropTenantArg& arg)
drop resource pool
SQL參考:
DROP RESOURCE POOL poolname;
只有沒有租戶引用的資源池才可以被刪除
int ObRootService::drop_resource_pool(const obrpc::ObDropResourcePoolArg& arg)
drop resource unit
SQL參考:
DROP RESOURCE UNIT unitname;
只有沒有資源池引用的規格才可以被刪除,只涉及到內部表的修改,介面如下
int ObRootService::drop_resource_unit(const obrpc::ObDropResourceUnitArg& arg)
租戶隔離租戶的資源是互相隔離的,CPU 隔離和排程的程式碼位於 src/observer/omt。
所有 OceanBase 的一級資料庫物件,如表,索引,database/schema,使用者等,在系統表和記憶體中都是用一個 uint64 作為 ID 標識的。為了實現方便,很多時候,在記憶體中這些 ID 裡編碼了租戶 ID,前 24bit是租戶ID。
如果大家有任何疑問,可以通過以下方式與我們進行交流:
微信群:掃碼新增小助手,將拉你進群喲~
釘釘群:33254054
github: https:// github.com/oceanbase/oc eanbase
部落格問答: oceanbase.com/community /answer
gitee: https:// gitee.com/oceanbase
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/70005215/viewspace-2795680/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- OceanBase 原始碼解讀(三):分割槽的一生原始碼
- OceanBase學習之路7|透過 MySQL 客戶端連線 OceanBase 租戶MySql客戶端
- OceanBase學習之路6|透過 Obclient 連線 OceanBase 租戶client
- OceanBase 原始碼解讀(八):事務日誌的提交和回放原始碼
- OceanBase 原始碼解讀(九):儲存層程式碼解讀之「巨集塊儲存格式」原始碼
- 技術分享 | OceanBase 租戶延遲刪除
- 技術分享 | OceanBase 資源及租戶管理
- 讀 NebulaGraph原始碼 | 查詢語句 LOOKUP 的一生原始碼
- OceanBase學習之路13|體驗多租戶特性
- OceanBase學習之路54|如何配置多租戶管理?
- OceanBase 原始碼解讀(十二):宏塊的垃圾回收和壞塊檢查原始碼
- 多租戶SaaS商城原始碼有哪些功能點?原始碼
- OceanBase 原始碼解讀(七):一文讀懂資料庫索引實現原理原始碼資料庫索引
- Laravel 原始碼的解讀Laravel原始碼
- 原始碼閱讀:SDWebImage(五)——SDWebImageFrame原始碼Web
- C#/C++ 透過ODBC連線OceanBase Oracle租戶C#C++Oracle
- 開源資料庫OceanBase原始碼解讀(九):tableAPI和OB多模型資料庫原始碼API模型
- 技術解讀資料庫如何實現“多租戶”?資料庫
- Nebula Graph 原始碼解讀系列|客戶端的通訊秘密——fbthrift原始碼客戶端
- OceanBase 儲存層程式碼解讀(一)引言
- PostgreSQL 原始碼解讀(3)- 如何閱讀原始碼SQL原始碼
- OceanBase學習之路40|如何將資源池分配給租戶?
- OceanBase學習之路53|多租戶管理引數如何設定?
- Nebula Graph 原始碼解讀系列|客戶端的通訊祕密——fbthrift原始碼客戶端
- Laravel 原始碼解讀Laravel原始碼
- reselect原始碼解讀原始碼
- Swoft 原始碼解讀原始碼
- Seajs原始碼解讀JS原始碼
- ReentrantLock原始碼解讀ReentrantLock原始碼
- MJExtension原始碼解讀原始碼
- Axios 原始碼解讀iOS原始碼
- SDWebImage原始碼解讀Web原始碼
- MJRefresh原始碼解讀原始碼
- Handler原始碼解讀原始碼
- LifeCycle原始碼解讀原始碼
- LinkedHashMap原始碼解讀HashMap原始碼
- ConcurrentHashMap原始碼解讀HashMap原始碼
- Redux原始碼解讀Redux原始碼