找回密码
 立即注册
首页 业界区 安全 自动分区分裂 —— OceanBase 易用性史诗级增强 ...

自动分区分裂 —— OceanBase 易用性史诗级增强

虹姥 昨天 20:45
背景
随着数字化的发展,当今数据库的业务数据量激增,单表往往也能达到超大规模。此时,使用单机数据库往往无法容纳超大体量的业务,需要借助分布式数据库的可扩展能力,将数据打散在多个节点进行承载,达到负载均衡的效果。
在 OceanBase 中,通过将表进行分区,按照分区粒度将数据划分到集群的不同节点上,来实现负载均衡的目标。但这依赖用户能设计合理的分区规则才能更好地使用水平扩展能力,这不仅要求用户具备对各种分区方式有充分的理解,并且还要求用户对业务使用数据库的方式有深入的了解,甚至在有些场景中,采用手动分区很难达到各方面都比较优的效果。
自动分区分裂特性能自动地根据用户设定的分区阈值大小自动进行分区分裂,使得用户无须关注分区规划的前提下,也能用好 OceanBase 数据库的分布式能力。
本篇文章将首先介绍手动分区存在的痛点问题,接着描述自动分区是如何解决手动分区这些问题的,最后详细介绍自动分区的特点,使用场景,使用方式以及限制等。
使用手动分区的痛点

分布式数据库负载均衡的目标是让各个节点的资源使用尽量达到均衡,要达到这个目标,就需要设计出合理的分区,使得分区间的资源占用比较适中,分区过大可能存在负载不均衡,合并空间放大等问题,分区过小可能会导致元数据过多,性能不优等问题。在自动分区分裂特性发布之前,通常需要手动设计分区规则,这个过程通常是比较困难,以下以抽象出来的业务场景为例来说明手动分区的痛点问题。
假设有一个系统,里面有一张表,它的主键是(公司 ID,员工 ID),现在将这个系统部署在 OceanBase 上,它上面当前有一条 SQL 查询,按照公司 ID,员工 ID 进行点查,客户对数据库的期望。

  • 充分利用 OceanBase 分布式能力实现负载均衡。
  • 保障 SQL 性能。
为了满足点查的 SQL 性能比较优的需求,很自然地想到基于(公司 ID,员工 ID)进行 Key 分区,Key 分区基本上能保证数据量均衡,并且,也能够高效地按照公司 ID,员工 ID 进行查询。
目前,业务的需求都得到了满足,我们来看看如果业务发生一些变化后,会出现什么情况?
业务变化有两种,一种是业务的请求发生变化,另一种是业务的数据发生变化。
我们先来看业务的请求发生变化的场景。
业务请求发生变化

假如业务系统新增一个功能需求,它希望对每个公司的员工,进行按批处理,对应的 SQL 请求是一个范围扫描。如果在原来的 Key 分区上做范围扫描,会导致每个分区都参与范围扫描查询,特别是按批处理的场景如果每个批次数据量不大时,会带来比较多的 IO 放大和网络放大,SQL 的性能是不优的。
为了解决这个问题,一个解决办法就是按照 range(公司 ID,员工 ID)进行分区,但比较难以设置划分的分区的边界,因为运维人员或者开发人员很难知道每个公司的员工数量,也就比较难以进行均衡的划分。
即使这个是老的业务,我们提前知道数据,我们可以手工统计目前数据的分布,划分出一些边界,但这也会有新的问题,例如,随着业务的发展,每个公司可能在员工信息上会有变化,可能导致重新不均衡。
业务数据发生变化

假如某些公司因业务发展需要,招聘并入职了大量员工,如果不做任何人工干预,新入职的员工可能会分布在某个分区上,使得该分区的数据量远超其他分区,集群会重新变得不均衡。为了避免该问题,可能运维人员需要规划好新的机器,并提前创建好新的分区,以便新的分区能够负责新的数据,防止已有分区的数据量过大的问题,这给业务运维带来了复杂度。
总结下来,通过手动分区的方式,存在如下痛点:

  • 负载均衡与 SQL 性能在部分业务场景可能难以兼顾,使用 Key 分区能够将负载打散,但对范围查询不够友好,使用 Range 分区又存在无法手动操作的可能性。
  • 手动设计的分区规则只适用于当前的业务情况,如果业务发生变化,可能需要重新设计分区规则。
  • 设计分区规则时,运维人员和开发人员需要做充分的沟通,确保业务中的 SQL 正确使用上了分区键,存在一定的沟通成本。
自动分区分裂如何解决问题

在讨论自动分区如何解决问题之前,我们先来简单的了解下 OceanBase 的自动分区的大致流程,在 OceanBase 中,当一个分区的数据量达到数据量阈值后,会自动地将数据按照主键或者主键前缀的 Range 进行一分为二,这里面有两个好处:

  • 有了自动分区后,每个分区的数据量会维持在大小适中的状态,当每个分区的数据量都差不多时,对负载均衡比较友好。
  • 自动分区是按照 Range 自动分区的,它既适合范围查询,也适合点查询。
如果使用自动分区,按照一定数据量阈值,进行自动拆分 range 分区,那么就能够解决上述需求。

  • 业务的第一个需求是负载均衡,自动分区分裂能够按照数据量阈值大小进行分裂,有助于负载均衡模块达到更好的均衡效果;
  • 业务的第二个需求是按照公司 ID,员工 ID 进行点查询,在 Range 分区下,进行一次分区裁剪就能定位到对应的分区,之后在对应的分区查询,效率是比较高的;
  • 业务的第三个需求是对员工进行批处理查询,本质上主键的范围查询,在自动分区下通常只会查询其中某个分区,效率也是比较高的;
  • 业务的第四个需求是已有分区的数据出现变化,此时达到数据量阈值后,会重新切分成大小适中的分区,达到动态均衡。
总体来看自动分区存在三个业务价值:

  • 自动分区的能够满足不同工作模式下的负载的性能需求。自动分区采用主键或者主键前缀的 Range 分区方式,它能够很好地满足数据库中的范围和点查询的需求,并且能够避免手动 Range 分区无法找到合适切分点的问题。
  • 自动分区能够满足分布式数据库的负载均衡需求,它会自动地按照数据量对分区进行分裂,在用户无须关注分区键的数据分布规则的前提下,自动生成数据量适合且均衡的分区,使得数据库内部更容易在机器间进行负载均衡。
  • 自动分区能够轻松应对变化,当业务的数据分布发生了变化后或业务的数据量发生变化后,可能导致不同分区的数据不均衡,此时自动分区能够按照阈值重新分裂不均衡的分区,使得分区间重新均衡;当业务访问量发生变化,新增了机器后,可能导致机器间的不均衡,此时,自动分区已经切分好了多个大小适合的分区,可以将已有机器上的分区 transfer 到新加的机器上,使得机器间能够更加均衡。
自动分区能够很好地解决手动分区存在的痛点问题,在用户准备用 OceanBase 自动分区之前,通常会关注自动分区对业务的影响以及使用的便捷性等,我将通过对 OceanBase 自动分区的特点介绍,来解答用户关注的问题。
自动分区分裂的特点

OceanBase 自动分区具备三个特点:

  • Online:不阻塞业务的普通 DML 和查询。
  • 使用资源少:分裂过程中使用的资源量较少。
  • 使用简单:只需要打开两个租户级的配置项,就能使用上自动分区分裂功能。
为了避免分裂对正常业务的影响,我们主要做了两方面的工作,一方面,当表上存在业务的普通 DML 和查询时,如果此时做自动分裂,会将查询和 DML 的流量自动转移到新分区继续处理,对正在执行的 DML 和查询的性能影响比较小;另一方面,我们做了一些优化使得分裂操作本身占用的资源比较少,包括重用大部分的数据、网络只同步逻辑操作等,充分节省了磁盘空间、带宽、网络带宽、CPU 和内存资源等。
我们在系统中只有一个分区的情况下,对这个分区进行分裂,模拟分裂带来影响最显著的场景,观察分裂对性能的影响。在面向 OLTP 场景的 sysbench 场景的测试,我们测试了点查,范围查和写入,性能影响在 4% ~ 8% 左右,参考下图。
1.png

2.png

3.png

实际生产环境中,分区数有很多个,同时在分裂的分区数只有一少部分,此时,分裂的影响会更小。
为了让用户方便的使用自动分区,我们对于一些场景,例如全局索引,HBase 等 KV 场景,默认放开了分裂,用户无须配置即可使用,对于其他场景,用户也只需要配置两个租户级的参数,即可使用上自动分裂。
使用场景

当前 OceanBase 在行存表模式下支持了自动分区分裂,所以,它适用于的业务场景主要是行存表所适用的业务场景,包括 KV 场景,以及 OLTP 场景。
KV 场景

在尚未支持的自动分区的 OceanBase 版本中,默认推荐的是按照 Key 方式进行预分区,分区数量一般设置数百到上千,这种使用方式通常能较好地将数据量进行打散,支持点查的负载,但对于范围扫描的负载不够友好,需要扫描所有的分区,同时 Key 分区的方式把新老数据打散了,不方便做分区级的数据管理。
由于 OceanBase 自动分区一期支持的自动 Range / Range Columns 分区,它继承了 Range 分区的优势之一,比较适合范围扫描的场景,同时它还有普通 Range 分区所不具有的自动按照数据量分裂的能力,将数据量打散。为了避免写热点,在自动分区下,尽量避免按照主键追加写入。如果业务上在读、写没有明显的按照主键范围的热点,那么即使业务负载都是点查,也能够使用自动分区将业务的负载打散。
自动扩展的 OLTP

在尚未支持自动分区的 OceanBase 版本中,如果为了更好地利用分布式集群的能力,用户需要结合业务规则设计相关的相关的分区,以便将数据量,业务负载打散到各个节点上。而支持自动分区后,我们可以默认对所有的表都是自动分裂的,用户在业务开始阶段就创建普通的非分区表,当业务体量增长时,由数据库本身自动的进行分区分裂,达到自动的负载均衡。
为了更有助于帮助大家理解适用的场景,我们列举一部分例子介绍下自动分区的使用场景。
业务平滑迁移

第一个场景是业务平滑迁移。目前业界已经有支持自动分裂的 KV 数据库和分布式关系型数据库,无论是自动可扩展的 KV 数据库,或者分布式关系型数据库,他们在源库的表结构通常是不带分区的。如果希望迁移到 OceanBase,享受到高压缩和高性能等优势,但又不想对一张张表做分区的修改,那么可以把表结构原封不动迁移过来,利用自动分区就能使用上分布式数据库的能力,使得业务迁移流程更加顺畅。
负载均衡

第二个场景就是尽可能利用上各个节点的资源。
这里可能有两种场景,第一个场景是多个 zone,每个 zone 虽然只有一台机器,但 3 个 zone 加起来就有 3 台机器了,为了充分的利用这 3 台机器资源,我们一般会用 random 部署模式,希望将负载打散到多个节点上,如果表只有单分区的话,是做不到打散的,因为一个分区只能有一个 Leader,这样就无法重复利用资源了。
4.png

如果对表开自动分区,当分裂出多个分区后,可以将所有分区的 Leader 均匀地分布在多个节点上,这样就能实现负载均衡。
5.png

同样地,如果一个 zone 本身就有多个节点了,那么即使是非 random 部署的形态下,它也有多个节点的资源可用。此时,也可以利用分裂的能力,生成多个分区,将分区迁移到不同的节点上,实现负载均衡。
自动应对业务的增长

我们碰到一些客户,他们可能有比较多的业务,可能他们自己也难预测哪些业务的规模未来会增长比较大。
为了应对这种可能出现增长的情况,那么在手动分区时代,我们通常建议客户配置比较多的分区数,以应对未来数据量或者业务流量暴涨的情况。比如每张表都配置 256 个分区,当集群的业务数据量较多时,分区数量会比较大,这个是不优的。如果采用自动分裂后,会自动根据表的分区的数据量进行自动的分裂。

  • 如果业务规模小的表,它的数据量也小,也就不会分裂,占用的分区数就比较少。
  • 如果业务发展的好,规模大的表,随着数据量增加,能够生成匹配业务规模的分区数,自动应对业务规模的增长。
6.png

手自一体

OceanBase 支持为每张表独立地设置是否开启自动分区,也就是可以单独地为每张表选择使用自动分区还是手动分区,有可能有些场景我们需要为部分表选择手动分区管理。
例如,为了业务层面的分区管理以及更细致的性能调优等等,此时,我们可以针对这部分表单独使用创建指定的分区规则,其他表还是走自动分区的方式。
一般情况下,多数表建议走自动分区,只有少部分有特殊需求的表手动设置分区规则,这样整体上也能节省很多表的分区规则配置。
7.png

全局索引自动分裂

还有一部分业务场景中,可能之前就已经对主表已经建了分区。但有些查询不带分区键,这个时候就需要创建全局索引来避免对所有的分区进行扫描。
一般索引的查询多为范围扫描,所以比较适合用 range 分区,但全局索引的索引键的类型通常多变,存在无法确定分区上下界的问题。因此,这种情况也非常适合对全局索引单独开自动分区。特别值得注意的是,这种情况即使主表是列存表,但全局索引是行存的,我们也能对它进行自动分裂。
8.png

使用方法

使用入门

要使用自动分区功能,只需要关注两个配置项:

  • enable_auto_split:租户级别配置项,控制这个租户是否开启自动分区功能,默认关闭。
  • auto_split_tablet_size:租户级别配置项,控制这个租户开启自动分区功能之后触发分裂的阈值,默认值 2 GB。
如果用户需要开启自动分区,并且内存资源足够,我们使用 ALTER SYSTEM SET enable_auto_split = true; 来打开自动分区。由于租户内存资源一般有限制,而我们支持的 tablet 数量跟租户内存大小有关,一般经验计算公式是 1GB 能分配 2W 个 tablet,所以,为了避免 tablet 数量过多,我们可以调整 auto_split_tablet_size 来避免因数据量太大而分配太多的 tablet。
进阶使用

通过租户级的配置使得用户能够很容易地将自动分区使用起来,但这种使用方式是将租户内所有的业务全部打开自动分区模式。
刚刚提到还有一些手动和自动分区一体化的场景,例如:

  • 用户的一个新集群或者新业务,打算上 OceanBase,先对部分表尝鲜自动分区功能,那么可以使用建表时是否开启自动分区来控制。
  1. -- 创建自动分区的非分区表(使用默认配置的 128MB 为分裂阈值)
  2. CREATE TABLE auto_pt2 (c1 int, c2 int, primary key(c1));
  3.                                 PARTITION BY RANGE ();
  4. -- 创建自动分区的非分区表(分裂阈值为 1024MB,使用用户配置)
  5. CREATE TABLE auto_pt3 (c1 int, c2 int, primary key(c1))
  6.                                 PARTITION BY RANGE () SIZE('1024MB');
复制代码

  • 用户的原有的OceanBase集群,升级到支持自动分区的OceanBase版本,并想部分表试用自动分区功能,那么可以使用修改自动分区属性来控制
  1. -- 业务从老版本 OceanBase 升级来的表 t1,未开启自动分区
  2. CREATE TABLE t1 (C1 INT, C2 INT, PRIMARY KEY(C1))
  3.                 PARTITION BY RANGE(C1) SIZE('10GB')
  4.     (PARTITION p0 VALUES LESS THAN(100),
  5.      PARTITION p1 VALUES LESS THAN(200),
  6.      PARTITION p_max VALUES LESS THAN (MAXVALUE)
  7.     );
  8. -- 修改表 t1 为自动分区表
  9. ALTER TABLE t1 PARTITION BY RANGE() SIZE('128MB');
复制代码

  • 用户对主表能够设计出分区,但对于全局索引比较难以手工设置好的range分区规则,那么可以通过全局索引自动分裂配置来控制
  1. -- 打开全局索引自动分裂配置项
  2. ALTER SYSTEM SET global_index_auto_split_policy = 'ALL';
  3. -- 添加分区表上的全局索引,将自动开启全局索引的自动分裂
  4. ALTER TABLE t1 ADD INDEX(c1) GLOBAL;
复制代码
9.png

What's more ?

以下这部分内容,属于 OceanBase 分区的前置知识点。
大家可以选择性地进行阅读。
为什么分区能让查询变快?

在 OceanBase 社区论坛中,一个很常见的用户问题问题:“按日期分区是否能达到让查询变快的目的?”
个人理解,分区除了可以让一张超级大表的数据比较均衡地负载在不同的数据库节点上,另外一个目的就是加速查询。因为查询时会利用过滤条件里面的分区键进行分区裁剪。
例如下面这两个例子:

  • 如果过滤条件里有分区键,计划中可以看到 partitions(p0),说明只扫描了 p0 这一个分区的数据。
10.png


  • 如果过滤条件里没有分区键,计划中可以看到 partitions(p[0-1]),说明扫描了 p0 和 p1 全部所有分区的数据。其中 PX PARTITION ITERATOR 算子就是用来循环扫描所有分区的迭代器。
11.png

为什么主键必须包含全部分区键?

很多社区用户会问:“有一张订单流水表,数据很大,想考虑按年份对数据进行分区。现在只有 ID 列是主键。尝试了一下好像无法按日期进行分区。是必须要把日期做成和 ID 的联合主键才可以分区么?”
答案是对的,主键必须包含所有分区键。
因为主键的唯一性检查是在各个分区内部进行的,如果主键不包含全部分区键,这个检查就会失效。所以 MySQL 及其他数据库,一般情况下,也都会有这个要求。
  1. -- 如果主键不包含全部分区键,建表就会失败报错,报错信息也挺明确的。
  2. create table t1(c1 int,
  3.                 c2 int,
  4.                 c3 int,
  5.                 primary key (c1))
  6. partition by range (c2)
  7.   (partition p1 values less than(3),
  8.    partition p1 values less than(6));
  9. ERROR 1503 (HY000): A PRIMARY KEY must include all columns in the table's partitioning function
复制代码
说明:
对于这个限制,前一阵儿还有一位数据库界的 KOL 老师认为上面的写法过于绝对了,尝试举出反例,最后终于找到一个叫 pg_pathman 的第三方 pg 插件。
这类第三方插件为了提升设置分区的灵活性,不要求分区键是主键或者唯一键的子集,但往往也会导致数据库中的主键和唯一键都不再保证唯一性,进而可能引入比较严重的正确性问题。不过终究也算是打破了这个限制。
最后在上面那段话中,又加入了 “一般情况下” 这几个字。
下面举个例子解释下原因:

  • 我们创建了一张表,主键是 c1 和 c2,分区键是 c2,小于 3 的值在 p0 分区,大于等于 3 且小于 6 的值在 p1 分区。然后插入了两个行,第一行在 p0 分区,第二行在 p1 分区。
  1. create table t1(c1 int,
  2.                 c2 int,
  3.                 c3 int,
  4.                 primary key (c1, c2))
  5. partition by range (c2)
  6.   (partition p0 values less than(3),
  7.    partition p1 values less than(6));
  8. Query OK, 0 rows affected (0.146 sec)
  9. obclient [test]> insert into t1 values(1, 2, 3);
  10. Query OK, 1 row affected (0.032 sec)
  11. obclient [test]> insert into t1 values(1, 5, 3);
  12. Query OK, 1 row affected (0.032 sec)
  13. obclient [test]> select * from t1;
  14. +----+----+------+
  15. | c1 | c2 | c3   |
  16. +----+----+------+
  17. |  1 |  2 |    3 |
  18. |  1 |  5 |    3 |
  19. +----+----+------+
  20. 2 rows in set (0.032 sec)
复制代码

  • 如果主键只有 c1 而没有 c2,那么在 p0 和 p1 分区内对 c1 列的唯一性检测都会成功,因为在各个分区内 c1 列的值都不重复(每个分区都只有一行数据,在分区内自然不会重复),然后就会判定插入的数据符合主键约束。
  1. obclient [test]> select * from t1 PARTITION(p0);
  2. +----+----+------+
  3. | c1 | c2 | c3   |
  4. +----+----+------+
  5. |  1 |  2 |    3 |
  6. +----+----+------+
  7. 1 row in set (0.033 sec)
  8. obclient [test]> select * from t1 PARTITION(p1);
  9. +----+----+------+
  10. | c1 | c2 | c3   |
  11. +----+----+------+
  12. |  1 |  5 |    3 |
  13. +----+----+------+
  14. 1 row in set (0.034 sec)
复制代码

  • 但实际上在分区间会有重复值 c1 = 1,数据并不符合主键约束(主键只有 c1 列),所以所有数据库在分区时,都要求主键包含全部分区键。
分区表应该优先考虑哪种分区方式?

分布式数据库的优势在于对于空间问题和请求访问问题分而治之。针对每个分区的访问,由该分区所在的节点响应即可。 即使该 SQL 并发很高,由于访问的是不同的分区,分别由不同的节点提供服务。每个节点自身也有一定能力满足一定的 QPS,所有节点集中在一起就能提供更大的 QPS。这个时候如果扩容节点数量,该 SQL 总的 QPS 也能获得相应的提升,这是分布式数据库里最好的情形。
分区的目标是将大量数据和访问请求均匀分布在多个节点上,一是想充分利用资源进行并行计算,消除查询热点问题;二是想利用分区裁剪来提升查询效率。 如果每个节点均匀承担数据和请求,那么理论上 10 个节点就应该能承担 10 倍于单节点的数据量和访问量。然而如果分区是不均匀的,一些分区的数据量或者请求量会相对比较高,出现数据偏斜(skew),这个可能导致节点资源利用率和负载也不均衡。偏斜集中的数据我们又称为热点数据。避免热点数据的直接方法就是数据存储时随机分配(没有规则)给节点,缺点是读取的时候不知道去哪个分区找该记录,只有扫描所有分区了,所以这个方法意义不大。实际常用的分区策略都是有一定的规则。
用户必须在业务查询条件明确的情况下,根据真实业务场景进行分区规划,不要在场景不明确的情况下随意进行分区规则。 在规划分区时,建议尽量保证各个分区的数据量相对均衡。
最常用的三种分区方式如下:

  • HASH 分区:一般适用于分区列 NDV(不同值的种类)较大,且难以划分出明确范围的情况。优点是容易让没有特定规则的数据也能够在不同的分区内均匀分布,缺点是在范围查询时难以进行分区裁剪。
  • RANGE 分区:一般适用于分区键容易划分出明确的范围的情况,例如可以把记录流水信息的大表,根据表示信息时间的列做 RANGE 分区。
  • LIST 分区:一般适用于需要显式控制各行数据如何映射到具体的某一个分区时,优点是可以对无序或无关的数据集进行精准分区,缺点是在范围查询时难以进行分区裁剪。
为了更好地支持并行计算和分区裁剪,OceanBase 还支持二级分区。OceanBase 数据库 MySQL 模式目前支持 HASH、RANGE、LIST、KEY、RANGE COLUMNS 和 LIST COLUMNS 六种分区类型,二级分区为任意两种分区类型的组合。
例如在用户账单领域,数据库往往需要按照 user_id 做 HASH 一级分区,然后再在各个一级分区内部,继续按照账单创建时间做 RANGE 二级分区。
12.png

尽管 OceanBase 数据库在组合分区上支持 RANGE + HASH 和 HASH + RANGE 两种组合,但是对于 RANGE 分区的分区操作 add / drop,必须是 RANGE 分区做为一级分区的方式。所以针对例如数据量较大的流水表,为了维护方便(新增和删除分区),建议使用 RANGE + HASH 组合方式(时间列 range 一级分区 + 业务列 hash 二级分区)。
总结一下:

  • 分区优先考虑用时间列 range 一级分区 + 业务 hash 二级分区。
  • 否则要根据数据聚集维度和常用查询语句来设计分区。
参考自这个 OceanBase 社区公众号中的一篇文章 《OceanBase PoC 经验总结(二)—— AP 业务》
如何进行手动分区分裂?

OceanBase 数据库支持在分区表中手动进行分区分裂(REORGANIZE)操作,即将一个已有的分区拆分为多个分区。这个功能可以指定需要分裂的分区和新分区的分裂位点进行手动执行分区分裂命令,根据需求和数据增长情况对分区进行调整。
OceanBase 当前(4.4.0 及以下版本)仅支持对 Range / Range Columns 分区的一级分区表进行手动分区分裂操作。
示例:

  • 创建 Range 分区的一级分区表 test_tbl1。
  1. CREATE TABLE test_tbl1(col1 INT, col2 INT, PRIMARY KEY(col1))
  2.     PARTITIONBYRANGE(col1)
  3.     (PARTITION p0 VALUESLESSTHAN(100),
  4.      PARTITION p1 VALUESLESSTHAN(200),
  5.      PARTITION p2 VALUESLESSTHAN(300),
  6.      PARTITION p_max VALUESLESSTHAN (MAXVALUE));
复制代码

  • 把 test_tbl1 表的分区 p0 分裂成三个新的分区,分裂的位置是在 30 和 60 这两个值所对应的行上。分裂后,原来的分区 p0 被分成三个新的分区 p0_1、p0_2 和 p0。
  1. ALTER TABLE test_tbl1
  2.     REORGANIZE PARTITION p0 INTO (
  3.         PARTITION p0_1 VALUES LESS THAN (30),
  4.         PARTITION p0_2 VALUES LESS THAN (60),
  5.         PARTITION p0 VALUES LESS THAN (100));
复制代码

  • 把 test_tbl1 表的分区 p_max 分裂成三个新的分区,分裂的位置是在 400 和 500 这两个值所对应的行上。分裂后,原来的分区 p_max 被分成三个新的分区 p_max_1、p_max_2 和 p_max_3。
  1. ALTER TABLE test_tbl1
  2.     REORGANIZE PARTITION p_max INTO (
  3.         PARTITION p_max_1 VALUES LESS THAN (400),
  4.         PARTITION p_max_2 VALUES LESS THAN (500),
  5.         PARTITION p_max_3 VALUES LESS THAN (MAXVALUE));
复制代码

  • 查看表 test_tbl1 的结构和定义。
  1. SHOW CREATE TABLE test_tbl1 \G
复制代码
返回结果如下:
  1. *************************** 1. row ***************************
  2.        Table: test_tbl1
  3. Create Table: CREATE TABLE `test_tbl1` (
  4.   `col1` int(11) NOT NULL,
  5.   `col2` int(11) DEFAULT NULL,
  6.   PRIMARY KEY (`col1`)
  7. ) ORGANIZATION INDEX DEFAULT CHARSET = utf8mb4 ROW_FORMAT = DYNAMIC
  8. partition by range(col1)
  9. (partition `p0_1` values less than (30),
  10. partition `p0_2` values less than (60),
  11. partition `p0` values less than (100),
  12. partition `p1` values less than (200),
  13. partition `p2` values less than (300),
  14. partition `p_max_1` values less than (400),
  15. partition `p_max_2` values less than (500),
  16. partition `p_max_3` values less than (MAXVALUE))
  17. 1 row in set (0.003 sec)
复制代码
最后为大家推荐这个 OceanBase 开源负责人老纪的公众号「老纪的技术唠嗑局」,会持续更新和 #数据库、#AI、#技术架构 相关的各种技术内容。欢迎感兴趣的朋友们关注!
「老纪的技术唠嗑局」不仅希望能持续给大家带来有价值的技术分享,也希望能和大家一起为开源社区贡献一份力量。如果你对 OceanBase 开源社区认可,点亮一颗小星星✨吧!你的每一个Star,都是我们努力的动力。

来源:程序园用户自行投稿发布,如果侵权,请联系站长删除
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!
您需要登录后才可以回帖 登录 | 立即注册