本文介紹了在AUTO模式資料庫中使用Locality關鍵字指定資料庫物件的儲存位置的方法。本文法僅適用於AUTO模式資料庫。
PolarDB-X支援在AUTO模式資料庫中,通過Locality關鍵字來指定資料庫、表或分區的儲存位置,以實現資料隔離或資料的均勻分布。
當前Locality關鍵字實現的能力如下:
- 允許定義資料庫、表、分區層級的Locality屬性,其他動作(縮容除外)均會在保證Locality約束的前提下改變資料分布。
- 允許變更表組、分區組層級的Locality屬性,修改後將自動觸發相應的非同步資料移轉任務。
前提條件
- 執行個體核心版本需為5.4.14及以上。
- 邏輯庫的分區類型需為AUTO模式。
如何查看執行個體版本,請參見查看和升級執行個體版本。
注意事項
- 節點縮容後,包含被縮容節點的Locality定義將會自動失效。
- 當前Locality屬性通過DN節點的ID定義,備份恢複後原有Locality屬性將會自動失效。
查看儲存節點資訊
假設已有一個PolarDB-X執行個體,您可以通過如下命令查看執行個體中的儲存節點資訊:
SHOW STORAGE;
返回結果如下:
+--------------------+----------------------------------+------------+-----------+----------+-------------+--------+-----------+-------+--------+
| STORAGE_INST_ID | LEADER_NODE | IS_HEALTHY | INST_KIND | DB_COUNT | GROUP_COUNT | STATUS | DELETABLE | DELAY | ACTIVE |
+--------------------+----------------------------------+------------+-----------+----------+-------------+--------+-----------+-------+--------+
| polardbx-ng28-dn-0 | polardbx-ng28-dn-0-cands-0:14289 | true | MASTER | 1 | 2 | 0 | false | null | null |
| polardbx-ng28-dn-1 | polardbx-ng28-dn-1-cands-0:14176 | true | MASTER | 1 | 1 | 0 | true | null | null |
| polardbx-ng28-dn-2 | polardbx-ng28-dn-2-cands-0:14568 | true | MASTER | 1 | 1 | 0 | true | null | null |
| polardbx-ng28-dn-3 | polardbx-ng28-dn-3-cands-0:16796 | true | MASTER | 1 | 1 | 0 | true | null | null |
| polardbx-ng28-gms | polardbx-ng28-dn-0-cands-0:14289 | true | META_DB | 2 | 2 | 0 | false | null | null |
+--------------------+----------------------------------+------------+-----------+----------+-------------+--------+-----------+-------+--------+
STORAGE_INST_ID
列為儲存節點名,即當前在Locality中使用的名字。INST_KIND
列為儲存節點類型,值為META_DB
的節點為中繼資料節點,不能用於儲存使用者資料。STATUS
列為儲存節點狀態,值為0
的節點為可用節點。DELTETABLE
列表明該節點是否可被縮容,值為false
的節點不可被縮容,其中包含中繼資料節點和一個指定儲存節點(下面簡稱為0號儲存節點)。
建立資料庫時指定儲存位置
在建立資料庫時指定儲存位置以實現資料隔離。
- 在執行個體中建立一個AUTO模式資料庫,並通過如下命令指定其儲存位置,詳細文法請參見CREATE DATABASE。
CREATE DATABASE db1 LOCALITY='dn=polardbx-ng28-dn-0,polardbx-ng28-dn-1,polardbx-ng28-dn-2' MODE = 'auto';
- 建立成功後,您可以通過如下語句查看資料庫的儲存位置資訊。
SHOW CREATE DATABASE `db1`;
返回結果如下:
+----------+--------------------------------------------------------------------------------------------------------------------+ | DATABASE | CREATE DATABASE | +----------+--------------------------------------------------------------------------------------------------------------------+ | db1 | CREATE DATABASE `db1` /* MODE = 'auto' LOCALITY = "dn=polardbx-ng28-dn-0,polardbx-ng28-dn-1,polardbx-ng28-dn-2" */ | +----------+--------------------------------------------------------------------------------------------------------------------+ 1 row in set (0.04 sec)
- 您還可以通過如下命令查看建立在該資料庫下的邏輯分庫和物理分庫資訊。
SHOW DS;
返回結果如下:
+----+--------------------+--------------------+---------------------------------+----------------------+---------+ | ID | STORAGE_INST_ID | DB | GROUP | PHY_DB | MOVABLE | +----+--------------------+--------------------+---------------------------------+----------------------+---------+ | 0 | polardbx-ng28-dn-0 | db1 | DB1_P00000_GROUP | db1_p00000 | 1 | | 1 | polardbx-ng28-dn-1 | db1 | DB1_P00001_GROUP | db1_p00001 | 1 | | 2 | polardbx-ng28-dn-2 | db1 | DB1_P00002_GROUP | db1_p00002 | 1 | | 3 | polardbx-ng28-gms | information_schema | INFORMATION_SCHEMA_SINGLE_GROUP | polardbx_info_schema | 0 | +----+--------------------+--------------------+---------------------------------+----------------------+---------+ 4 rows in set (0.04 sec)
說明 資料庫的儲存位置必須包含0號節點,表和分區的儲存位置不受此限制。
建立邏輯表時指定儲存位置
在建立邏輯表時指定儲存位置以實現資料隔離,目前支援在單表和Range、Hash、List三種分區方式的分區表中使用Locality關鍵字。
- 在執行個體中建立一個邏輯表,並指定其儲存位置。詳細文法參見CREATE TABLE(AUTO模式)。
CREATE TABLE t_order ( `id` bigint(11) NOT NULL AUTO_INCREMENT BY GROUP, `order_id` varchar(20) DEFAULT NULL, `buyer_id` varchar(20) DEFAULT NULL, `seller_id` varchar(20) DEFAULT NULL, `order_snapshot` longtext DEFAULT NULL, `order_detail` longtext DEFAULT NULL, PRIMARY KEY (`id`), KEY `l_i_order` (`order_id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8 locality = 'dn=polardbx-ng28-dn-1,polardbx-ng28-dn-2';
- 執行以下語句,查看錶的定義。
SHOW CREATE TABLE `t_order`;
返回資訊如下:
+---------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ | TABLE | CREATE TABLE | +---------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ | t_order | CREATE TABLE `t_order` ( `id` bigint(11) NOT NULL AUTO_INCREMENT, `order_id` varchar(20) DEFAULT NULL, `buyer_id` varchar(20) DEFAULT NULL, `seller_id` varchar(20) DEFAULT NULL, `order_snapshot` longtext, `order_detail` longtext, PRIMARY KEY (`id`), INDEX `l_i_order` (`order_id`) ) ENGINE = InnoDB DEFAULT CHARSET = utf8 /* LOCALITY='dn=polardbx-ng28-dn-1,polardbx-ng28-dn-2' */ | +---------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ 1 row in set (0.05 sec)
- 執行以下語句,查看邏輯表的各個分區的資料分布情況。
SHOW TOPOLOGY `t_order`;
返回資訊如下:
+----+------------------+--------------------+----------------+-------------+--------------------+ | ID | GROUP_NAME | TABLE_NAME | PARTITION_NAME | PHY_DB_NAME | DN_ID | +----+------------------+--------------------+----------------+-------------+--------------------+ | 0 | DB1_P00002_GROUP | t_order_18dV_00001 | p2 | db1_p00002 | polardbx-ng28-dn-2 | | 1 | DB1_P00001_GROUP | t_order_18dV_00000 | p1 | db1_p00001 | polardbx-ng28-dn-1 | | 2 | DB1_P00001_GROUP | t_order_18dV_00002 | p3 | db1_p00001 | polardbx-ng28-dn-1 | +----+------------------+--------------------+----------------+-------------+--------------------+ 3 rows in set (0.15 sec)
說明- 建立表時Locality關鍵字指定的儲存節點集合,必須是資料庫對應儲存節點集合的子集。
- 如果所建立的表為單表,則只允許Locality關鍵字聲明單個DN節點作為儲存節點。
- 當邏輯表與表組匹配時,表與表組、分區和分區組的Locality屬性必須完全相同才能匹配成功。
- 邏輯表、邏輯表的表組、邏輯表的GSI、邏輯表GSI的表組預設具備相同的Locality屬性。
建立邏輯表的分區時指定儲存位置
在建立邏輯表時,通過指定分區層級的儲存節點,可以將同一張邏輯表的不同分區分布在不同DN上。
- 在執行個體中建立一個邏輯表,並指定其分區的Locality。
CREATE TABLE orders_region( order_id int AUTO_INCREMENT primary key, customer_id int, country varchar(64), city varchar(64), order_time datetime not null) PARTITION BY LIST COLUMNS(country,city) ( PARTITION p1 VALUES IN (('China','Shanghai')) LOCALITY = 'dn=polardbx-ng28-dn-2', PARTITION p2 VALUES IN (('China','Beijing')) LOCALITY = 'dn=polardbx-ng28-dn-2', PARTITION p3 VALUES IN (('China','Hangzhou')) , PARTITION p4 VALUES IN (('China','Nanjing')) , PARTITION p5 VALUES IN (('China','Guangzhou')) , PARTITION p6 VALUES IN (('China','Shenzhen')) , PARTITION p7 VALUES IN (('China','Wuhan')) , PARTITION p8 VALUES IN (('America','New York')) ) LOCALITY = 'dn=polardbx-ng28-dn-0,polardbx-ng28-dn-1';
- 執行以下語句,查看錶的定義。
SHOW CREATE TABLE `orders_region`;
返回資訊如下:
+---------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ | TABLE | CREATE TABLE | +---------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ | orders_region | CREATE TABLE `orders_region` ( `order_id` int(11) NOT NULL AUTO_INCREMENT, `customer_id` int(11) DEFAULT NULL, `country` varchar(64) DEFAULT NULL, `city` varchar(64) DEFAULT NULL, `order_time` datetime NOT NULL, PRIMARY KEY (`order_id`), KEY `auto_shard_key_country_city` USING BTREE (`country`, `city`) ) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4 /* LOCALITY='dn=polardbx-ng28-dn-0,polardbx-ng28-dn-1' */ PARTITION BY LIST COLUMNS(`country`,`city`) (PARTITION `p1` VALUES IN (('China','Shanghai')) ENGINE = InnoDB LOCALITY='dn=polardbx-ng28-dn-2', PARTITION `p2` VALUES IN (('China','Beijing')) ENGINE = InnoDB LOCALITY='dn=polardbx-ng28-dn-2', PARTITION `p3` VALUES IN (('China','Hangzhou')) ENGINE = InnoDB, PARTITION `p4` VALUES IN (('China','Nanjing')) ENGINE = InnoDB, PARTITION `p5` VALUES IN (('China','Guangzhou')) ENGINE = InnoDB, PARTITION `p6` VALUES IN (('China','Shenzhen')) ENGINE = InnoDB, PARTITION `p7` VALUES IN (('China','Wuhan')) ENGINE = InnoDB, PARTITION `p8` VALUES IN (('America','New York')) ENGINE = InnoDB) | +---------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ 1 row in set (0.05 sec)
- 執行以下語句,查看邏輯表的各個分區的資料分布情況。
SHOW TOPOLOGY `orders_region`;
返回資訊如下:
+----+------------------+--------------------------+----------------+-------------+--------------------+ | ID | GROUP_NAME | TABLE_NAME | PARTITION_NAME | PHY_DB_NAME | DN_ID | +----+------------------+--------------------------+----------------+-------------+--------------------+ | 0 | DB1_P00002_GROUP | orders_region_RlsY_00000 | p1 | db1_p00002 | polardbx-ng28-dn-2 | | 1 | DB1_P00002_GROUP | orders_region_RlsY_00001 | p2 | db1_p00002 | polardbx-ng28-dn-2 | | 2 | DB1_P00001_GROUP | orders_region_RlsY_00003 | p4 | db1_p00001 | polardbx-ng28-dn-1 | | 3 | DB1_P00001_GROUP | orders_region_RlsY_00004 | p5 | db1_p00001 | polardbx-ng28-dn-1 | | 4 | DB1_P00001_GROUP | orders_region_RlsY_00006 | p7 | db1_p00001 | polardbx-ng28-dn-1 | | 5 | DB1_P00000_GROUP | orders_region_RlsY_00002 | p3 | db1_p00000 | polardbx-ng28-dn-0 | | 6 | DB1_P00000_GROUP | orders_region_RlsY_00005 | p6 | db1_p00000 | polardbx-ng28-dn-0 | | 7 | DB1_P00000_GROUP | orders_region_RlsY_00007 | p8 | db1_p00000 | polardbx-ng28-dn-0 | +----+------------------+--------------------------+----------------+-------------+--------------------+ 8 rows in set (0.25 sec)
說明 分區的儲存節點必須是資料庫儲存節點的子集,但可以不是邏輯表的儲存節點的子集。
修改表組的儲存節點
動態變更表組的儲存節點。
文法ALTER TABLEGROUP identifier SET LOCALITY = locality_option
locality_option:
'dn=storage_inst_id_list'
| ''
樣本以前文中的orders_region表為例,該表位於表組`tg3`中,現對其儲存節點進行變更:
ALTER TABLEGROUP `tg3` SET LOCALITY = `dn=polardbx-ng28-dn-0`;
變更操作後,表的拓撲如下:
SHOW TOPOLOGY `orders_region`;
+----+------------------+--------------------------+----------------+-------------+--------------------+
| ID | GROUP_NAME | TABLE_NAME | PARTITION_NAME | PHY_DB_NAME | DN_ID |
+----+------------------+--------------------------+----------------+-------------+--------------------+
| 0 | DB1_P00002_GROUP | orders_region_RlsY_00000 | p1 | db1_p00002 | polardbx-ng28-dn-2 |
| 1 | DB1_P00002_GROUP | orders_region_RlsY_00001 | p2 | db1_p00002 | polardbx-ng28-dn-2 |
| 2 | DB1_P00000_GROUP | orders_region_RlsY_00002 | p3 | db1_p00000 | polardbx-ng28-dn-0 |
| 3 | DB1_P00000_GROUP | orders_region_RlsY_00003 | p4 | db1_p00000 | polardbx-ng28-dn-0 |
| 4 | DB1_P00000_GROUP | orders_region_RlsY_00004 | p5 | db1_p00000 | polardbx-ng28-dn-0 |
| 5 | DB1_P00000_GROUP | orders_region_RlsY_00005 | p6 | db1_p00000 | polardbx-ng28-dn-0 |
| 6 | DB1_P00000_GROUP | orders_region_RlsY_00006 | p7 | db1_p00000 | polardbx-ng28-dn-0 |
| 7 | DB1_P00000_GROUP | orders_region_RlsY_00007 | p8 | db1_p00000 | polardbx-ng28-dn-0 |
+----+------------------+--------------------------+----------------+-------------+--------------------+
8 rows in set (0.17 sec)
在同一表組內,定義過Locality的分區的資料存放區位置,將遵從其Locality約束,其他分區將根據表組的Locality約束進行資料移轉。修改表組或分區組的儲存位置將會在元資訊變更後快速返回,後台產生相應表組的分區遷移任務非同步執行。
可通過information_schema.ddl_plan
查詢對應的分區遷移任務REBALANCE TABLEGROUP tg3
的執行進度。
SELECT * FROM information_schema.ddl_plan WHERE table_schema = "db1";
+----+---------------------+---------------------+--------------+------------------------------------------------------------------+---------+-----------+----------+-------------+--------+--------+---------------------+---------------------+----------------+
| ID | plan_id | job_id | table_schema | ddl_stmt | state | ddl_type | progress | retry_count | result | extras | gmt_created | gmt_modified | resource |
+----+---------------------+---------------------+--------------+------------------------------------------------------------------+---------+-----------+----------+-------------+--------+--------+---------------------+---------------------+----------------+
| 1 | 1465819565798723584 | 1465819579241467904 | db1 | REBALANCE TABLEGROUP `tg3` EXPLAIN=false ASYNC=true DEBUG=false | SUCCESS | REBALANCE | 100 | 0 | | | 2022-05-24 14:37:58 | 2022-05-24 14:38:11 | tablegroup:tg3 |
+----+---------------------+---------------------+--------------+------------------------------------------------------------------+---------+-----------+----------+-------------+--------+--------+---------------------+---------------------+----------------+
修改分區組的儲存節點
動態變更分區組的儲存節點。
文法ALTER TABLEGROUP identifier SET PARTITIONS part_name LOCALITY = locality_option
locality_option:
'dn=storage_inst_id_list'
| ''
樣本以前文中的orders_region表為例,該表位於表組`tg3`中,現對其分區p3的Locality進行變更:
ALTER TABLEGROUP `tg3` SET PARTITIONS p3 LOCALITY = `dn=polardbx-ng28-dn-1`;
變更後表的拓撲如下:
SHOW TOPOLOGY orders_region;
+----+------------------+--------------------------+----------------+-------------+--------------------+
| ID | GROUP_NAME | TABLE_NAME | PARTITION_NAME | PHY_DB_NAME | DN_ID |
+----+------------------+--------------------------+----------------+-------------+--------------------+
| 0 | DB1_P00002_GROUP | orders_region_RlsY_00000 | p1 | db1_p00002 | polardbx-ng28-dn-2 |
| 1 | DB1_P00002_GROUP | orders_region_RlsY_00001 | p2 | db1_p00002 | polardbx-ng28-dn-2 |
| 2 | DB1_P00001_GROUP | orders_region_RlsY_00002 | p3 | db1_p00001 | polardbx-ng28-dn-1 |
| 3 | DB1_P00000_GROUP | orders_region_RlsY_00003 | p4 | db1_p00000 | polardbx-ng28-dn-0 |
| 4 | DB1_P00000_GROUP | orders_region_RlsY_00004 | p5 | db1_p00000 | polardbx-ng28-dn-0 |
| 5 | DB1_P00000_GROUP | orders_region_RlsY_00005 | p6 | db1_p00000 | polardbx-ng28-dn-0 |
| 6 | DB1_P00000_GROUP | orders_region_RlsY_00006 | p7 | db1_p00000 | polardbx-ng28-dn-0 |
| 7 | DB1_P00000_GROUP | orders_region_RlsY_00007 | p8 | db1_p00000 | polardbx-ng28-dn-0 |
+----+------------------+--------------------------+----------------+-------------+--------------------+
8 rows in set (0.11 sec)
分區變更操作中的Locality屬性傳播
當前AUTO模式下的分區變更操作包括變更表組級分區(AUTO模式)和變更表類型及分區策略(AUTO模式)。
在分區變更操作中,新的分區組和表組一般自動繼承原有的Locality屬性,並且變更後的表組和分區組也將自動滿足資料分布約束,但是以下三種情形例外:
- 對於表的類型變更操作,當目標類型為單表或者廣播表時,表的Locality屬性預設為空白。
- 對於明確涉及資料熱點的分區變更操作,新分區Locality預設為空白。
- 對於merge partition操作,當原分區集合成員的Locality不同時,新分區Locality預設為空白。
分區變更操作涉及的Locality變更說明:
類型(簡稱) | 變更對象 | 變更對象的Locality屬性是否不變 | 備忘 |
分區表拆分變更 | 表 | 是 | - |
表的類型變更 | 表 | 僅在單表變更為分區表時不變。 | 分區表變更為單表和廣播表時Locality屬性會自動失效。 |
分區遷移(move partition) | 分區組 | 是 | - |
分區合并(merge partition) | 分區組 | 新分區僅在所有舊分區的locality屬性相同時繼承舊分區的locality。 | 無法繼承時,新分區Locality預設為空白值。 |
分區分裂(split partition) | 分區組 | 是 | - |
分區按熱點分裂(split by hot value) | 分區組 | 否 | 新分區Locality預設為空白值。 |
分區熱點值提取(extract) | 分區組 | 否 | 新分區Locality預設為空白值。 |
分區刪除(drop partition) | 分區組 | - | - |
分區新增(add partition) | 分區組 | 是 | - |
LIST分區值修改(modify partition) | 分區組 | 是 | - |
分區重新命名(rename partition) | 分區組 | 是 | - |
典型使用情境
- 建立資料庫時,可通過Localiy對邏輯庫層級的資料進行隔離,資料庫中的表和分區會自動分布在指定的DN上。
- 建立單表時,可通過Locality指定單表的儲存節點,從而避免單表數量過多對0號節點的儲存壓力。
- 建立分區表時,可通過指定分區層級的Locality,將同一張邏輯表的不同分區控制在不同的DN上,例如結合LIST分區可對同一張邏輯表中不同地區資料進行隔離。
- 當資料分區產生熱點資料時,可通過分區變更和Locality為熱點分區指定單獨的DN,從而隔離其實體儲存體資源。