對於電商或SaaS等多租戶業務情境,您可能需要為不同層級的租戶(如VIP客戶與普通客戶)提供差異化的服務品質和資源保障。傳統方案往往面臨資源隔離不徹底、租戶擴縮容操作複雜等挑戰。PolarDB-X提供儲存資源集區功能,允許您將物理資料節點(DN)邏輯劃分為不同的資源群組。通過將資料庫或表分區綁定到指定的資源集區,您可以輕鬆實現租戶間的實體資源隔離、靈活調整資源分派,從而有效保障核心業務的穩定性並簡化營運管理。
功能簡介
儲存資源集區(Storage Pool)是PolarDB-X提供的一種資源管理能力,它允許您將執行個體中的物理資料節點(DN)劃分為若干個邏輯資源群組。每個資源集區由一個或多個DN組成,不同資源集區之間DN互不重疊。
您可以將資料庫、表或表分區等資料庫物件與特定的資源集區進行綁定,從而將這些對象的資料物理地隔離在指定的DN節點上。當資源集區內的節點或資料庫物件的綁定關係發生變更時,系統會自動觸發資料移轉,以滿足新的資源布局要求。
該功能主要用於實現多租戶情境下的資源隔離、服務分級以及業務負載的精細化管理。

適用範圍
執行個體核心版本需為
5.4.20-20250806及以上。邏輯庫的分區模式(
MODE)需為auto模式。
使用說明
儲存資源集區
建議您使用PolarDB分布式版控制台中的資料節點管理功能來建立和管理儲存資源集區。以下關於儲存資源集區的相關SQL語句僅用於輔助理解其工作原理,不建議您在業務環境中直接執行。
查看儲存資源集區
在進行任何操作前,您首先需要瞭解當前執行個體已有的資源集區及其狀態。
系統預設資源集區
一個PolarDB-X執行個體預設包含兩個系統儲存池:
_default:預設儲存池。初始狀態下,它包含執行個體中所有的活躍資料節點(DN)。如果您在建立資料庫物件時未指定資源集區,資料將預設存放在此池中。_recycle:回收儲存池。它用於存放從其他資源集區中移除、或尚未分配的空閑資料節點。這些節點是建立新資源集區或為現有資源集區擴容的來源。
查詢方法
您可以通過查詢information_schema.storage_pool_info視圖來擷取所有資源集區的詳細資料。
SELECT * FROM information_schema.storage_pool_info;輸出樣本
+------+----------+-----------------------------------------------------+-----------------+---------------------------+--------+---------------------+---------------------+
| ID | NAME | DN_ID_LIST | IDLE_DN_ID_LIST | UNDELETABLE_DN_ID | EXTRAS | GMT_CREATED | GMT_MODIFIED |
+------+----------+-----------------------------------------------------+-----------------+---------------------------+--------+---------------------+---------------------+
| 1 | _default | dn0,dn1,dn2,dn3,dn4,dn5,dn6,dn7,dn8,dn9 | | dn0 | NULL | 2024-04-15 19:46:05 | 2024-04-15 19:46:05 |
| 2 | _recycle | | | | NULL | 2024-04-15 19:46:05 | 2024-04-15 19:46:05 |
+------+----------+-----------------------------------------------------+-----------------+---------------------------+--------+---------------------+---------------------+變更儲存資源集區
您可以向現有資源集區中添加節點(擴容),或從中移除節點(縮容)。移除節點後,儲存池將自動變更為_recycle儲存池。然而,您無法移除資源集區中的UNDELETABLE_DN_ID。每個儲存資源集區必須至少包含一個DN節點,並且其中一個DN將被指定為UNDELETABLE DN。在資源集區未被刪除之前,該節點無法被移除。
縮容
從資源集區移除節點。縮容時,節點上的資料會自動非同步遷移。
-- 從資源集區移除節點(節點上的資料會自動遷移)
ALTER STORAGE POOL <pool_name> DRAIN NODE "<dn_id_list>";樣本
對_default儲存池進行縮容,僅dn0保留在_default儲存池中,其他節點均放入_recycle儲存池中。
ALTER STORAGE POOL _default DRAIN NODE 'dn1,dn2,dn3,dn4,dn5,dn6,dn7,dn8,dn9';查看儲存資源集區,結果如下:
SELECT * FROM information_schema.storage_pool_info;
+------+----------+-----------------------------------------------------+-----------------+---------------------------+--------+---------------------+---------------------+
| ID | NAME | DN_ID_LIST | IDLE_DN_ID_LIST | UNDELETABLE_DN_ID | EXTRAS | GMT_CREATED | GMT_MODIFIED |
+------+----------+-----------------------------------------------------+-----------------+---------------------------+--------+---------------------+---------------------+
| 1 | _default | dn0 | | dn0 | NULL | 2024-04-15 19:46:05 | 2024-04-15 19:46:05 |
| 2 | _recycle | dn1,dn2,dn3,dn4,dn5,dn6,dn7,dn8,dn9 | | | NULL | 2024-04-15 19:46:05 | 2024-04-15 19:46:05 |
+------+----------+-----------------------------------------------------+-----------------+---------------------------+--------+---------------------+---------------------+擴容
向資源集區添加節點。
- 向資源集區添加節點
ALTER STORAGE POOL <pool_name> APPEND NODE "<dn_id_list>";新增的節點不得包含任何資料庫物件。
不同資源集區的DN之間不能互相交叉。
同一儲存資源集區內部允許包含不同規格的DN節點。
樣本
對_default儲存池擴容,將dn1節點放回_default儲存池。
ALTER STORAGE POOL _default APPEND NODE 'dn1';查看儲存資源集區,結果如下:
SELECT * FROM information_schema.storage_pool_info;
+------+----------+-----------------------------------------------------+-----------------+---------------------------+--------+---------------------+---------------------+
| ID | NAME | DN_ID_LIST | IDLE_DN_ID_LIST | UNDELETABLE_DN_ID | EXTRAS | GMT_CREATED | GMT_MODIFIED |
+------+----------+-----------------------------------------------------+-----------------+---------------------------+--------+---------------------+---------------------+
| 1 | _default | dn0,dn1 | | dn0 | NULL | 2024-04-15 19:46:05 | 2024-04-15 19:46:05 |
| 2 | _recycle | dn2,dn3,dn4,dn5,dn6,dn7,dn8,dn9 | | | NULL | 2024-04-15 19:46:05 | 2024-04-15 19:46:05 |
+------+----------+-----------------------------------------------------+-----------------+---------------------------+--------+---------------------+---------------------+建立儲存資源集區
您可以將回收池(_recycle)中的空閑資料節點(DN)組合起來,建立一個新的自訂儲存資源集區。
CREATE STORAGE POOL <pool_name> DN_LIST = "<dn_id_1>,<dn_id_2>,..." UNDELETABLE_DN = "<dn_id>";參數說明
pool_name:自訂資源集區的名稱。DN_LIST:該資源集區包含的資料節點ID列表,這些節點必須是閒置。UNDELETABLE_DN:指定一個不可刪除的節點,以保證資源集區的最低可用性。
規則說明
每個儲存資源集區必須至少包含一個DN節點,並且其中一個DN將被指定為
UNDELETABLE DN。在資源集區未被刪除之前,該節點無法被移除。在建立儲存資源集區時,指定的DN上需不包含任何資料庫物件。
不同資源集區的DN之間不能互相交叉。
同一儲存資源集區內部允許包含不同規格的DN節點。
樣本
-- 建立一個名為pool_1,包含dn4, dn5, dn6三個節點的資源集區
CREATE STORAGE POOL pool_1 DN_LIST="dn4,dn5,dn6" UNDELETABLE_DN="dn4";
-- 建立一個名為pool_2,包含dn7一個節點的資源集區
CREATE STORAGE POOL pool_2 DN_LIST="dn7" UNDELETABLE_DN="dn7";
-- 建立一個名為pool_3,包含dn8, dn9三個節點的資源集區
CREATE STORAGE POOL pool_3 DN_LIST="dn8,dn9" UNDELETABLE_DN="dn8";關聯儲存資源集區與資料庫物件
定義關聯關係
在建立資料庫、表或分區時,可以通過LOCALITY子句指定其資料存放的資源集區。允許指定多個儲存資源集區(storage_pools),並單獨指定一個預設儲存資源集區列表(primary_storage_pool)。一個完整的儲存池綁定聲明如下:
CREATE DATABASE | TABLE ... LOCALITY = "storage_pools=<pool_list>;primary_storage_pool=<pool_name>";參數說明
storage_pools:允許該資料庫物件使用的所有資源集區列表。對於廣播表,它會在該列表的所有資源集區中棄置站台。primary_storage_pool:預設使用的資源集區。如果不顯式為子物件(如表、分區)指定LOCALITY,它們將預設使用此主資源集區。說明在顯式為子物件(如表、分區)指定儲存資源集區時,需從屬於其上一級對象,即資料庫物件所具備的儲存資源集區(
storage_pools)。
樣本
-- 建立一個資料庫,其資料預設存放在pool_vip中
CREATE DATABASE db_test MODE = "auto" LOCALITY = "storage_pools=pool_1,pool_2,pool_3;primary_storage_pool=pool_1,pool_2";變更關聯關係
對於資料庫、表組或分區,允許直接變更其儲存資源集區。您可以修改其LOCALITY定義,以實現資料的線上遷移。
如果對對象關聯的儲存資源集區進行追加,除了擴增廣播表的節點範圍外,不會進行其他動作。
如果對對象關聯的儲存資源集區進行刪減,則需消除該對象及其子物件在被刪除資源集區上所有對象的儲存資源集區定義,並進行遷移。
(庫層級不支援此操作)如果完全清除對象關聯的儲存資源集區,則等同於將該對象關聯的資源集區變更為預設資源集區。
ALTER DATABASE | TABLE <object_name> [SET] LOCALITY = "...";此操作會觸發背景資料移轉任務,將資料從舊的資源集區移動到新的資源集區,整個過程對應用線上。
對於庫層級的對象,無論如何變更關聯的儲存資源集區,都不允許在
storage_pools列表中刪除primary_storage_pool,也不允許變更已定義的primary_storage_pool,對於表組和分區則沒有此限制。
樣本
ALTER TABLE db_test LOCALITY = "storage_pools=pool_1;primary_storage_pool=pool_1";情境樣本
情境一:庫級租戶
以一個電商平台(以下簡稱X公司)為例,其系統需要維護多個賣家的訂單,其中包含有若干流水顯著較高的大賣家和大部分小賣家,X公司對於大小賣家的資源劃分要求如下:
大賣家需要使用單獨的儲存資源儲存資料,確保線上流量穩定,同時需要提供單獨的跑批資料分析能力。
小賣家需要共用一組儲存資源,並且小賣家佔用的資源需要儘可能在該組資源中保持均衡。
部分小賣家隨著時間演化可能演變為大賣家,部分大賣家可能遷移到其他平台或者從其他平台遷入。
租戶定義
X公司的需求可以通過庫級資源隔離實現,然後按大賣家的需求,將已有的儲存節點劃分為若干儲存池,對於小賣家的共用庫,可直接建在預設儲存池之上:
CREATE STORAGE POOL sp1 dn_list="dn4,dn5,dn6" undeletable_dn="dn4";
CREATE STORAGE POOL sp2 dn_list="dn7,dn8,dn9" undeletable_dn="dn7";
CREATE DATABASE orders_comm MODE = "auto"
LOCALITY= "storage_pools='_default'"; /* 小賣家共用_default儲存池(dn1, dn2, dn3 */
CREATE DATABASE orders_seller1 MODE = "auto"
LOCALITY= "storage_pools='sp1'"; /* 大賣家1使用sp1儲存池(dn4, dn5, dn6) */
CREATE DATABASE orders_seller2 MODE = "auto"
LOCALITY= "storage_pools='sp2'"; /* 大賣家2使用sp2儲存池(dn7, dn8, dn9) */
...通過上述建庫語句,應用可獲得以下效果:
大賣家之間、大賣家與小賣家之間各自使用單獨儲存資源儲存,儲存資源完全隔離。
小賣家之間共用預設儲存池的資源dn1~dn3。
大小賣家之間的建表語句可以完全獨立,可以自行決定每個賣家的表結構定義以及儲存資源。
資源均衡
小賣家的庫內部可以使用Locality的單表打散模式全部建成單表,也可以建成分區表。當小賣家之間也存在資料分布的差異,需要在小賣家內部均衡資源分派時,只需直接調用儲存池層級的資源均衡語句。
REBALANCE TENANT "_default" POLICY="data_balance";REBALANCE將會自動按照儲存池內的對象屬性定義均衡相應的單表和分區分布,與執行個體層級的擴縮容一樣,該操作將自動滿足資源約束,並且儘可能均衡所有單表和所有分區在dn1~dn3上的分布。
租戶遷入及遷出
當平台遷入新的大賣家時,可在執行個體中加入新的儲存節點(預設加入到_recycle儲存池),然後使用該節點單獨建立儲存池,並建立大賣家相關的庫使之獨佔新的儲存池。
CREATE STORAGE POOL spn dn_list = "dn10,dn11,dn12" undeletable_dn="dn10";
/* 新定義儲存池spn (dn10, dn11, dn12) */
CREATE DATABASE orders_sellern MODE = "auto"
LOCALITY="storage_pools='spn'";
/* 大賣家N使用spn儲存池 */如果大賣家遷出,可刪除相應庫並且釋放相應資源。
DROP DATABASE orders_sellern;
DELETE STORAGE POOL spn;/* 刪除儲存池,相應的節點將會自動進入_recycle儲存池 */
ALTER STORAGE POOL _recycle DRAIN NODE "dn7, dn8, dn9"; /* 在叢集中釋放相應的節點 */在新增以及刪除上述儲存池和庫時,已有的業務不會受到影響,對應用幾乎是透明無感的。
情境二:分區級租戶
對於情境一中X公司的需求,也可以通過分區級資源隔離實現,相比於庫級租戶,分區級租戶可以提供完全一致的資源隔離能力,並且具備更多優勢:
所有分區共用邏輯表的定義,加減列、加減索引等資料營運操作以及廣播表的下推關係均由資料庫自動維護。
通過分區分裂、分區合并等已有的分區管理能力,可以獲得更加靈活的資源變更能力,如將部分租戶升級到VIP服務、合并部分租戶的資源等等。
租戶定義
首先將儲存節點劃分為相應的儲存池,然後使用全部儲存池建立一個公用庫。
CREATE DATABASE orders_db MODE = "auto"
LOCALITY = "storage_pools='_default,sp1,sp2,...',primary_storage_pool='_default'"
USE orders_db;
CREATE TABLE commodity(
commodity_id int,
commodity_name varchar(64)
) BROADCAST;
/*commodity作為一張廣播表,將會在所有的儲存池上建立分表,因此可與orders_sellers的任何一個分區進行join下推。*/
CREATE TABLE orders_sellers(
order_id int AUTO_INCREMENT primary key,
customer_id int,
commodity_id int,
country varchar(64),
seller_id int,
order_time datetime not null)
partition BY list(seller_id)
(
partition p1 VALUES IN (1, 2, 3, 4),
partition p2 VALUES IN (5, 6, 7, 8),
/*orders_seller的分區p1, p2預設會使用_default儲存池中的節點進行儲存,共用_default儲存池中的資源。*/
...
partition pn VALUES IN (k) LOCALITY = "storage_pools='sp1'",
partition pn+1 VALUES IN (k+1, k+2) LOCALITY = "storage_pools='sp2'",
/*orders_seller的分區pn, pn+1會分別使用sp1, sp2儲存池中的節點進行儲存,分別獨自佔用相應儲存節點的資源。*/
...
) LOCALITY = "storage_pools='_default,sp1,sp2,...'";庫的定義中包含了全部儲存池,但是同時定義了primary_storage_pool為_default儲存池,因而orders_sellers中的分區預設會使用_default儲存池作為儲存節點列表,而廣播表會自動分布在所有儲存池節點上。
不同分區的定義包含不同的租戶集合,並且可以自行指定分區的儲存資源。
租戶遷入和遷出
對於新增的小租戶,可以直接添加分區,預設不遷移資料,只產生新分區。
ALTER TABLE orders_sellers ADD PARTITION
(PARTITION p3 values in (32, 33));對於新增的大租戶,可向已有的儲存節點中添加節點,並且加入到分區路由直接添加分區,同時指定其佔用的儲存池。
CREATE STORAGE POOL spn dn_list = "dn10,dn11,dn12" undeletable_dn="dn10";
/*向執行個體中新增了一個儲存池spn.*/
ALTER DATABASE orders_db SET LOCALITY =
"storage_pools='_default,sp1,sp2,...,spn',primary_storage_pool='_default'"
/*向orders_db的儲存池列表中添加spn, 這一修改將會自動觸發廣播表遷移到新的儲存池節點之上。*/
ALTER TABLE orders_sellers ADD PARTITION
(PARTITION p4 values in (34) LOCALITY="storage_pools='spn');
/*在orders_sellers中新增一個租戶分區,並且該分區分布在自訂的儲存池spn上。*/同樣,對於租戶遷出,可直接刪除相應分區並釋放儲存池資源。
ALTER TABLE orders_sellers DROP PARTITION p4;或者變更相應的分區定義,在分區內部刪除小賣家。
ALTER TABLE orders_sellers MODIFY PARTITION p1 DROP VALUES (4, 5);對分區級租戶而言,所有分區共用邏輯表的定義,因而資料模式變更可由資料庫統一維護。上述分區變更語句均為online操作,僅影響實際操作涉及的分區,對其他分區的已有業務均無影響。
租戶服務等級變更
當小賣家的服務等級需要升級為VIP層級時,可修改分區定義,將其單獨分配到一個儲存池上:
ALTER TABLE orders_sellers SPLIT PARTITION p2 INTO
(PARTITION p2 VALUES in (6, 7, 8) ,
PARTITION `pn+2` VALUES in (5) LOCALITY = "storage_pools='spn+3'");同樣,可以根據對大賣家的服務等級進行降級。
ALTER TABLE orders_sellers MERGE PARTITION p1, pn TO p1 LOCALITY="";上述操作的效果將直接合并p1和pn分區的資料,並且新分區仍然儲存於預設儲存池之上。
在保留庫級租戶資源隔離的能力的基礎上,分區級租戶通過完善的分區管理介面提供了更加靈活的租戶資源變更和控制能力。
資源均衡
當租戶間在分區層級出現負載不均時,同樣可以通過儲存池層級的REBALANCE操作在公用儲存池中進行負載平衡。
REBALANCE TENANT "_default" POLICY="data_balance";情境三:單機到分布式的遷移演化
以一個從單機關係型資料庫到分散式資料庫的遷移過程為例,在遷移初期,使用者希望儘可能複用原有的使用模式,在享有分散式資料庫scale out能力的同時,儘可能做到無痛改造;隨著業務逐步發展,以表為單位逐步推動部分業務負載較大的單表進一步演化到分布式表,同時確保儘可能不影響已有業務的庫表模型和資源佔用。
通過儲存池定義不同表的儲存資源,即可實現單表與分布式表共存的集中分布式一體化使用模式,協助使用者平滑演化到分散式資料庫。
建庫建表
除少數具有廣播表語義的表外,使用者可使用單表打散模式在PolarDB-X中複用原有的單機建表語句,從而實現存量業務的一鍵遷移改造。
CREATE DATABASE orders_db MODE = "auto" DEFAULT_SINGLE=on
LOCALITY = "storage_pools='_default',primary_storage_pool='_default'";
use orders_db;
CREATE TABLE orders_region1(
order_id int AUTO_INCREMENT primary key,
customer_id int,
country varchar(64),
city int,
order_time datetime not null);
CREATE TABLE orders_region2(
order_id int AUTO_INCREMENT primary key,
customer_id int,
country varchar(64),
city int,
order_time datetime not null);
CREATE TABLE orders_region3(
order_id int AUTO_INCREMENT primary key,
customer_id int,
country varchar(64),
city int,
order_time datetime not null);
CREATE TABLE commodity(
commodity_id int,
commodity_name varchar(64)
) BROADCAST;上述建庫和建表語句實現了兩個效果:
所有應用單機建表語句的單表將會自動按照資料量和表的數量自動在_default儲存池中均衡。
廣播表將在_default儲存池的所有節點上建立分表。
隔離部分單表
部分單表承載的資料量和訪問量過大,可以在執行個體中添加新的儲存節點,並將負載過大的單表單獨隔離到新的節點上:
ALTER DATABASE orders_db set LOCALITY = "storage_pools='_default,sp1',primary_storage_pool='_default'";
/* 對資料庫的變更將會自動處理廣播表的分表擴張行為。 */
ALTER TABLE orders_region_single1 single LOCALITY = "storage_pools='sp1'";
/* 將業務負載較大的單表隔離到sp1儲存池的節點上。*/分布式改造
隨著業務演化,使用者可將超出單個物理表負載限制的表改造為分布式表,並且指定其所使用的儲存節點:
ALTER DATABASE orders_db set LOCALITY = "storage_pools='_default,sp1,sp2,sp3',primary_storage_pool='_default'";
ALTER TABLE orders_region_single2 partition by hash(order_id) partitions 16
LOCALITY = "storage_pools='sp2'";
/* orders_region_single2 使用儲存池sp2 */
ALTER TABLE orders_region_single3 partition by hash(order_id) partitions 16
LOCALITY = "storage_pools='sp3'";
/* orders_region_single3 使用儲存池sp3 */拆分變更允許使用者以online執行的方式自訂目標表的分區方式和儲存資源,從而做到表層級的業務模型改造,協助使用者無痛實現從單表到分布式表的演化。