分区交换(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;
假设有一个按时间范围分区的大表
orders,需要把 2024 年 1 月的历史数据归档。传统方式需要:
CREATE TABLE orders_202401 AS SELECT * FROM orders WHERE order_date BETWEEN '2024-01-01' AND '2024-02-01'ALTER TABLE orders TRUNCATE PARTITION p202401第一步是一次全量数据扫描+写入,数据量大时耗时极长。而分区交换只需要交换元数据映射,几乎是瞬时的 O(1) 操作。
在数据仓库场景中,分区交换是 ETL 流水线中的关键环节:
要理解分区交换,需要先理解 OceanBase 的三级映射结构:
表(Table) → 分区(Partition) → 数据分片(Tablet)
分区交换的本质是:在事务保护下,修改分区表中某个分区所指向的 Tablet ID,同时修改非分区表所指向的 Tablet ID,使两者互换。
在详细介绍交换模式前,需要先理解 OceanBase 的分区层级结构,这是理解交换模式的基础:
orders 表按日期分成
p2024q1、
p2024q2 等分区。orders 表先按日期分区,再在每个日期分区内按地区分成
sub_east、
sub_west 等子分区。分区交换的本质是在这些层级之间交换 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
如果在操作过程中遇到问题,欢迎在评论区留言交流,后续我们会持续分享更多实战运维干货,记得
关注不迷路,下次见~
来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/70047467/viewspace-3181418/ ,如需转载,请注明出处,否则将追究法律责任。