本文介绍Locality的使用方法。

Locality允许用户在Auto模式下控制数据库中各种粒度对象的物理存储位置,如数据库、表、分区的存储DN集合,从而针对不同业务的压力进行资源隔离。

当前Locality的能力如下:

  • 允许定义数据库、表、分区级别的Locality属性,扩容、分区变更以及其他DDL(缩容与备份除外)均会在保证Localiy约束的前提下改变数据分布。

  • 允许变更表组、分区组级别的Locality属性,修改后将自动触发相应的异步数据迁移任务。

版本限制

  • 实例内核版本需为5.4.14或以上。

  • 逻辑库的分区类型需为Auto模式。

说明

关于如何查看实例版本,请参见查看和升级实例版本

注意事项

  • 节点缩容后,涉及被缩容节点的Locality定义将会自动失效。

  • 当前Locality属性通过数据节点的ID定义,备份恢复后原有Locality属性将会自动失效。

定义数据库对象的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号存储节点)。

创建数据库时指定存储节点

在创建数据库时指定存储位置以实现数据隔离。

语法:

CREATE DATABASE database_name databse [database_option_list];

在实例中创建一个Auto模式数据库,并指定其locality,详细语法请参见CREATE DATABASE

示例:

CREATE DATABASE db1 LOCALITY='dn=polardbx-ng28-dn-0,polardbx-ng28-dn-1,polardbx-ng28-dn-2' MODE = 'auto';

您可以通过show create database查看数据库的定义,也可以通过show ds查看当前数据库中可用的存储节点。

mysql> 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)

mysql> 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)
说明

数据库的locality属性必须包含0号节点,表和分区的locality属性不受此限制。

创建单表时自动打散存储节点

在创建单表时会自动将单表打散到多个存储节点上,建立单表的物理表时将会自动根据DN节点上的单表数量和数据量进行均衡。

在实例中创建若干个逻辑单表,并指定其locality为"balance_single_table=on"。详细语法请参见CREATE TABLE(AUTO模式)

示例:

CREATE TABLE t_sgl1 (
  `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`)
) SINGLE locality = 'balance_single_table=on';

CREATE TABLE t_sgl2 (
  `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`)
) SINGLE locality = 'balance_single_table=on';

CREATE TABLE t_sgl3 (
  `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`)
) SINGLE locality = 'balance_single_table=on';

CREATE TABLE t_sgl4 (
  `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`)
) SINGLE locality = 'balance_single_table=on';

您可以通过show create table查看表的定义,也可以通过show topology查看逻辑表的各个分区的数据分布情况。

mysql> SHOW CREATE TABLE `t_sgl1`;
+---------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| TABLE   | CREATE TABLE                                                                                                                                                                                                                                                                                                                                                                                        |
+---------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| t_order | CREATE TABLE `t_sgl1` (
	`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='balance_single_table=on' */ |
+---------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
1 row in set (0.05 sec)

mysql> SHOW TOPOLOGY `t_sgl1`;
+----+------------------+--------------------+----------------+-------------+--------------------+
| ID | GROUP_NAME       | TABLE_NAME         | PARTITION_NAME | PHY_DB_NAME | DN_ID              |
+----+------------------+--------------------+----------------+-------------+--------------------+
|  1 | DB1_P00001_GROUP | t_sgl1_92mv_00000  | p1             | db1_p00001  | polardbx-ng28-dn-1 |
+----+------------------+--------------------+----------------+-------------+--------------------+
3 rows in set (0.15 sec)

mysql> SHOW TOPOLOGY `t_sgl2`;
+----+------------------+--------------------+----------------+-------------+--------------------+
| ID | GROUP_NAME       | TABLE_NAME         | PARTITION_NAME | PHY_DB_NAME | DN_ID              |
+----+------------------+--------------------+----------------+-------------+--------------------+
|  1 | DB1_P00002_GROUP | t_sgl2_87fg_00000  | p1             | db1_p00002  | polardbx-ng28-dn-2 |
+----+------------------+--------------------+----------------+-------------+--------------------+
3 rows in set (0.15 sec)

mysql> SHOW TOPOLOGY `t_sgl3`;
+----+------------------+--------------------+----------------+-------------+--------------------+
| ID | GROUP_NAME       | TABLE_NAME         | PARTITION_NAME | PHY_DB_NAME | DN_ID              |
+----+------------------+--------------------+----------------+-------------+--------------------+
|  1 | DB1_P00002_GROUP | t_sgl3_64uj_00000  | p1             | db1_p00001  | polardbx-ng28-dn-1 |
+----+------------------+--------------------+----------------+-------------+--------------------+
3 rows in set (0.15 sec)

mysql> SHOW TOPOLOGY `t_sgl4`;
+----+------------------+--------------------+----------------+-------------+--------------------+
| ID | GROUP_NAME       | TABLE_NAME         | PARTITION_NAME | PHY_DB_NAME | DN_ID              |
+----+------------------+--------------------+----------------+-------------+--------------------+
|  1 | DB1_P00001_GROUP | t_sgl4_71mb_00000  | p1             | db1_p00002  | polardbx-ng28-dn-2 |
+----+------------------+--------------------+----------------+-------------+--------------------+
3 rows in set (0.15 sec)

此时逻辑单表已经被自动打散到多个存储节点上。

创建逻辑表时指定存储节点

在创建逻辑表时指定存储位置以实现数据隔离,目前Locality支持单表和Range、Hash、List三种分区方式的分区表。

语法:

CREATE [PARTITION] TABLE [IF NOT EXISTS] tbl_name
    (create_definition, ...)
    [table_options]
    [table_partition_definition]
    [local_partition_definition]

在实例中创建一个逻辑表,并指定其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命令查看表的定义,也可以通过show topology命令查看逻辑表的各个分区的数据分布情况。

mysql> 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)

mysql> 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。

  • 当逻辑表与表组匹配时,表与表组、分区和分区组的locality属性必须完全相同才能匹配成功。

  • 逻辑表、逻辑表的表组、逻辑表的GSI、逻辑表GSI的表组默认具备相同的locality属性。

创建逻辑表的分区时指定存储节点

在创建逻辑表时,通过指定分区级别的Locality,可以将同一张逻辑表的不同分区控制在不同DN上。

示例:

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查看表的定义,也可以通过show topology查看逻辑表的各个分区的数据分布情况。

mysql> 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)

mysql> 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)
说明

分区的locality属性必须是数据库locality属性的子集,但是可以不必从属于逻辑表的locality属性。

修改数据库对象的Locality属性

修改表组的存储节点

支持动态变更表组的locality属性。

语法:

ALTER TABLEGROUP identifier SET LOCALITY = locality_option
locality_option:
    'dn=storage_inst_id_list'
 |  ''

示例:

以前文中的orders_region表为例,该表位于表组`tg3`中,现对其locality进行变更:

ALTER TABLEGROUP `tg3` SET LOCALITY = `dn=polardbx-ng28-dn-0`;

变更操作后,表的拓扑如下:

mysql> 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约束进行数据迁移。

说明

修改表组或分区组的locality将会在元信息变更后快速返回,后台生成相应表组的分区迁移任务异步执行。可通过information_schema.ddl_plan查询对应的分区迁移任务REBALANCE TABLEGROUP tg3 的执行进度。

mysql> 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 |
+----+---------------------+---------------------+--------------+------------------------------------------------------------------+---------+-----------+----------+-------------+--------+--------+---------------------+---------------------+----------------+

修改分区组的存储节点

动态变更分区组的locality属性。

语法:

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`;

变更后表的拓扑如下:

mysql> 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属性

动态变更表的locality属性,注意,该操作将会触发数据迁移。

如须将设置了locality为"balance_single_table=on"的单表变更为相应分区表,需要显式通过repartition消去LOCALITY属性,例如:

ALTER TABLE t_sgl1 PARTITION BY HASH(ID) PARTITIONS 32 LOCALITY = "";

如须直接变更逻辑表的locality属性,同样可以直接通过repatition操作修改LOCALITY属性,例如:

ALTER TABLE t_sgl1 PARTITION BY HASH(ID) PARTITIONS 8 LOCALITY = "dn=dn1";

DDL操作中的Locality属性传播

当前Auto模式下的分区变更操作包括alter table group变更表类型及分区策略

在分区变更操作中,新的分区组和表组一般自动继承原有的Locality属性,并且变更后的表组和分区组也将自动满足数据分布约束,但是以下三种情形例外:

  • 对于表的类型变更操作,当目标类型为单表或者广播表时,表的locality属性默认为空。

  • 对于明确涉及数据热点的分区变更操作,新分区locality默认为空。

  • 对于merge partition操作,当原分区集合成员的locality不同时,新分区locality默认为空。

分区变更操作涉及的Locality如下表所示:

类型(简称)

变更对象

变更对象的Locality属性是否不变

分区表拆分变更

表的类型变更

仅在单表变更为分区表时不变。

分区迁移(move partition)

分区组

分区合并(merge partition)

分区组

新分区仅在所有旧分区的locality属性相同时继承旧分区的locality。

分区分裂(split partition)

分区组

分区按热点分裂(split by hot value)

分区组

分区热点值提取(extract)

分区组

分区删除(drop partition)

分区组

-

分区新增(add partition)

分区组

LIST分区值修改(modify partition)

分区组

分区重命名(rename partition)

分区组

典型使用场景

  • 建库时,可通过Localiy对逻辑库级别的数据进行隔离,数据库中的表和分区会自动分布于指定DN范围上。

  • 建立单表时,可通过Locality指定单表的存储节点,从而避免单表数量过多对0号节点的存储压力。

  • 建立分区表时,可通过指定分区级别的Locality,将同一张逻辑表的不同分区控制在不同DN上。例如结合LIST分区可对同一张逻辑表中不同地域数据进行隔离,参见创建逻辑表的分区时指定存储节点

  • 当数据分区产生热点数据时,可通过分区变更和Locality属性修改为热点分区指定单独的DN,从而隔离其物理存储资源,参见修改表的Locality属性