×
技术社区 >  技术博客 >  海量数据迁移神器: OceanBase 分区交换(Exchange Partition)

海量数据迁移神器: OceanBase 分区交换(Exchange Partition)

一、什么是分区交换

分区交换(Exchange Partition)是一种数据库 DDL 操作,允许用户将一个非分区表的数据与分区表中某个分区(或子分区)的数据进行"互换"。其本质并非真正搬运数据,而是通过交换底层元数据中 Tablet(数据分片)与表的映射关系,实现数据的瞬间"置换"。

在 OceanBase 中,分区交换通过以下 SQL 语法触发:

-- MySQL 模式:分区与非分区表交换
ALTER TABLE partitioned_table EXCHANGE PARTITION p_name WITH TABLE non_partitioned_table;

-- Oracle 模式:还支持子分区交换
ALTER TABLE partitioned_table EXCHANGE SUBPARTITION sp_name WITH TABLE non_partitioned_table;

二、为什么需要分区交换:解决的核心痛点

2.1 传统数据导入导出的效率瓶颈

假设有一个按时间范围分区的大表 orders,需要把 2024 年 1 月的历史数据归档。传统方式需要:

  1. CREATE TABLE orders_202401 AS SELECT * FROM orders WHERE order_date BETWEEN '2024-01-01' AND '2024-02-01'
  2. 删除分区数据:ALTER TABLE orders TRUNCATE PARTITION p202401

第一步是一次全量数据扫描+写入,数据量大时耗时极长。而分区交换只需要交换元数据映射,几乎是瞬时的 O(1) 操作。

2.2 ETL 与数据仓库场景的刚需

在数据仓库场景中,分区交换是 ETL 流水线中的关键环节:

  • 增量加载:先将新数据批量导入到一个与分区结构相同的非分区表,再通过一次 EXCHANGE 将其"挂"到分区表上,整个过程不阻塞在线查询。
  • 数据归档:将过期分区交换到独立表后,再对独立表做冷存储处理或 DROP,避免分区表上执行高代价的 DELETE。
  • 数据修复:对某个分区的数据进行离线修复后,通过交换重新上线。

2.2 配合旁路导入,高效加载数据

  • 专门服务于分区级别的旁路导入。Direct Load 先将数据直接写入一个中间表的 Tablet,再通过分区交换将 Tablet 挂到目标分区表的对应分区上,从而绕过 SQL 层逐行写入的开销,实现高速数据导入。
  • 即通过全量旁路导入的方式将数据快速导入新建非分区表中,然后利用分区交换功能将非分区表中的数据快速导入分区表中,加快现有分区表增量数据导入的性能。

三、分区交换的底层机制

要理解分区交换,需要先理解 OceanBase 的三级映射结构:

表(Table) → 分区(Partition) → 数据分片(Tablet)
  • Table:用户看到的逻辑表,拥有全局唯一的 table_id。
  • Partition:表的分区,每个分区有独立的分区名和分区键范围。
  • Tablet:OceanBase 最小的存储单元,真正承载数据。每个 Tablet 有全局唯一的 tablet_id。

分区交换的本质是:在事务保护下,修改分区表中某个分区所指向的 Tablet ID,同时修改非分区表所指向的 Tablet ID,使两者互换。

四、OceanBase 4.4.2 版本的分区交换能力

4.1 支持的交换模式

在详细介绍交换模式前,需要先理解 OceanBase 的分区层级结构,这是理解交换模式的基础:

  • 一级分区表:表按某个分区键分成若干分区。例如 orders 表按日期分成 p2024q1、p2024q2 等分区。
  • 二级分区表(复合分区表):表先按一个键做一级分区,再在每个一级分区内按另一个键做二级分区(子分区)。例如 orders 表先按日期分区,再在每个日期分区内按地区分成 sub_east、sub_west 等子分区。
  • 非分区表:普通表,整张表就是一个 Tablet。

分区交换的本质是在这些层级之间交换 Tablet 的归属关系。源码中定义了 5 种交换类型,但 4.4.2 版本实际实现了以下 3 种:

模式一:一级分区 ↔ 非分区表(PART_AND_NONPART)

这是最基础、最常用的模式。将分区表中的某一个分区与一张普通非分区表交换 Tablet。

交换前:                          交换后:
分区表 orders                     分区表 orders
├── p2024q1  (Tablet_A)           ├── p2024q1  (Tablet_A)
├── p2024q2  (Tablet_B)    ←→     ├── p2024q2  (Tablet_X)  ← 原暂存表的数据
└── p2024q3  (Tablet_C)           └── p2024q3  (Tablet_C)

非分区表 staging (Tablet_X)       非分区表 staging (Tablet_B)  ← 原p2024q2的数据

SQL 语法:

ALTER TABLE orders EXCHANGE PARTITION p2024q2 WITH TABLE staging;

使用场景:将批量准备好的数据(staging 表)快速导入到分区表的某个分区中,或将某个分区的数据快速导出到普通表进行处理。

支持模式:MySQL 和 Oracle 模式均支持,从 4.3.1.0 版本起可用。

模式二:子分区 ↔ 非分区表(SUBPART_AND_NONPART)

与模式一类似,但操作粒度更细——交换的是二级分区表中的某一个子分区与非分区表。

交换前:                                交换后:
分区表 orders                           分区表 orders
├── p2024q1                             ├── p2024q1
│   ├── sub_east  (Tablet_A1)           │   ├── sub_east  (Tablet_A1)
│   └── sub_west  (Tablet_A2)           │   └── sub_west  (Tablet_A2)
├── p2024q2                             ├── p2024q2
│   ├── sub_east  (Tablet_B1)    ←→     │   ├── sub_east  (Tablet_X)  ← 原暂存表
│   └── sub_west  (Tablet_B2)           │   └── sub_west  (Tablet_B2)
└── ...                                 └── ...

非分区表 staging (Tablet_X)             非分区表 staging (Tablet_B1)  ← 原sub_east数据

SQL 语法(仅 Oracle 模式):

ALTER TABLE orders EXCHANGE SUBPARTITION sub_east OF p2024q2 WITH TABLE staging;

模式三:一级分区 ↔ 一级分区表(SUBPART_AND_PART)

这是最复杂的模式。将二级分区表中的某个一级分区下的所有子分区,与另一张一级分区表的所有分区进行批量交换。注意:这里交换的不是单个 Tablet,而是一组 Tablet 的批量互换。

交换前:                                  交换后:
二级分区表 orders                         二级分区表 orders
├── p2024q1                               ├── p2024q1
│   ├── sub_east  (Tablet_A1)             │   ├── sub_east  (Tablet_A1)
│   └── sub_west  (Tablet_A2)             │   └── sub_west  (Tablet_A2)
├── p2024q2                               ├── p2024q2
│   ├── sub_east  (Tablet_B1)      ←→     │   ├── sub_east  (Tablet_Y1)  ← 原分区表的p1
│   └── sub_west  (Tablet_B2)             │   └── sub_west  (Tablet_Y2)  ← 原分区表的p2
└── ...                                   └── ...

一级分区表 exchange_target                一级分区表 exchange_target
├── p1  (Tablet_Y1)                       ├── p1  (Tablet_B1)  ← 原sub_east
└── p2  (Tablet_Y2)                       └── p2  (Tablet_B2)  ← 原sub_west

SQL 语法:

ALTER TABLE orders EXCHANGE PARTITION p2024q2 WITH TABLE exchange_target;

为什么这样设计?这个模式的典型场景是:业务先将某个一级分区的数据通过 Direct Load 等方式导入到一张独立的一级分区表中(作为暂存),再整批交换回二级分区表的某个一级分区下。要求一级分区下的子分区数量与暂存表的分区数量完全一致,且分区键类型、分区边界必须匹配

当前版本分区交换也有自身的使用限制,具体参考官方文档说明:https://www.oceanbase.com/docs/common-oceanbase-database-cn-1000000005283578

精选推荐