基于湖库一体架构,统一管理结构化、半结构化与非结构化等多模态数据,一个系统承载事务处理、实时分析与 AI 工作负载。
CTAS 大数据量导入 DDL 超时优化解决方案
更新时间:2026-08-25 02:41
问题现象
在使用 OceanBase 数据库执行大数据量表复制或迁移操作时,用户通常采用 CREATE TABLE AS SELECT(CTAS)语句一次性完成建表与数据导入。当源表数据量较大时,CTAS 语句执行超过 1000 秒后报错超时,导致任务失败。
问题原因
OceanBase 数据库中,一般 DDL 语句的超时时间由集群级隐藏参数 _ob_ddl_timeout 控制,默认值为 1000 秒,修改后动态生效。该参数影响的范围是集群级别,在 SYS 租户下通过 ALTER SYSTEM SET 进行修改。
- 受
_ob_ddl_timeout控制的 DDL:CREATE TABLE AS SELECT(CTAS)目前属于受该参数控制的 DDL。这意味着当源表数据量巨大、复制耗时超过 1000 秒时,CTAS 会直接超时失败。 - 不受
_ob_ddl_timeout限制的 DDL:创建索引(CREATE INDEX)、创建外键约束、创建 check 约束等会受表中数据量影响的 DDL,其内部超时时间为 102 年,可简单理解为不会受 1000 秒限制而超时。
关键信息
查看当前 DDL 超时参数
在 SYS 租户下查看 _ob_ddl_timeout 当前值:
-- 通过虚拟表查看
SELECT * FROM oceanbase.__all_virtual_tenant_parameter_stat WHERE name LIKE '_ob_ddl_timeout';
-- 查看是否被修改过(非默认值查询)
SELECT name, data_type, value FROM oceanbase.__all_sys_parameter WHERE name = '_ob_ddl_timeout';
若 __all_sys_parameter 中查询为空,说明集群从未修改过该参数,当前使用默认值 1000 秒。
修改 DDL 超时参数(不推荐作为常规方案)
在 SYS 租户下执行:
ALTER SYSTEM SET _ob_ddl_timeout = '1h';
支持的时间单位包括 s(秒)、m(分钟)、h(小时)、d(天)。修改后动态生效。
注意:虽然可以调大 _ob_ddl_timeout,但 1000 秒默认值通常已足够长。DDL 超时大多是由于并发执行大批量 DDL 导致在 RS 队列中排队时间超过阈值,或 CTAS 数据量过大导致。对于大数据量导入场景,更推荐改用 INSERT INTO SELECT 结合旁路导入或并行 DML 的方案。
问题的风险及影响
- 业务影响程度:中。CTAS 超时失败后需要重新执行或调整方案,影响数据迁移、备份恢复、报表生成等批处理任务的时效性。
- 数据丢失风险:CTAS 超时失败后会话回滚,不会产生脏数据或数据丢失风险。
适用版本
OceanBase 数据库 V3.x、V4.x 版本。
解决方法
4.3.4 及之后版本
4.3.4 版本开始,支持 CREATE TABLE AS SELECT 旁路导入
CREATE TABLE AS SELECT 语句通过设置 DIRECT() Hint 来指定旁路导入的导数方式,在未指定 Hint 时能基于配置项 default_load_mode 确定导入数据的行为。
CREATE /*+ [APPEND | DIRECT(need_sort,max_error,load_type)] parallel(N) */ TABLE table_name [AS] select_sentence
| 参数 | 描述 |
|---|---|
APPEND 或 DIRECT() |
使用 Hint 启用旁路导入功能。 * APPEND Hint 默认等同于使用的 DIRECT(true, 0),同时可以实现在线收集统计信息(GATHER_OPTIMIZER_STATISTICS Hint)的功能。* DIRECT() 参数解释如下:- need_sort:表示写入的数据是否需要排序,值为 bool 类型:* true:表示需要排序。* false:表示不需要排序。- max_error:表示最大容忍的错误行数。值为 INT 类型,超过这个数值导入任务执行会失败。- full:表示全量旁路导入,可选项,取值须使用英文单引号包起来。 |
parallel(N) |
加载数据的并行度,必填项,取值是大于 1 的整数。 |
使用示范
- 指定
CREATE TABLE AS SELECT语句的 Hint- 使用
APPENDHint 旁路导入数据。CREATE /*+ append parallel(4) */ TABLE tbl2 AS SELECT * FROM tbl1; - 使用
DIRECTHint 旁路导入数据。CREATE /*+ direct(true, 0, 'full') parallel(4) */ TABLE tbl2 AS SELECT * FROM tbl1;
- 使用
- 不指定
CREATE TABLE AS SELECT语句的 Hint 设置配置项default_load_mode的值为FULL_DIRECT_WRITE。ALTER SYSTEM SET default_load_mode ='FULL_DIRECT_WRITE';CREATE TABLE tbl2 AS SELECT * FROM tbl1;
3x 之后 ~ 4.3.4 之前版本
针对大数据量导入场景,建议将 CREATE TABLE AS SELECT 拆分为以下两步,并采用相应优化手段
步骤一:单独创建目标表结构
步骤二:使用 INSERT INTO SELECT 导入数据并提速
方案 A:旁路导入 + 并行 DML(推荐,V4.x 适用)
旁路导入通过 Hint 使用 append 和 enable_parallel_dml 来跳过事务缓冲区,直接写入存储层,大幅提升大数据量写入性能。
语法示例:
INSERT /*+ append enable_parallel_dml parallel(16) */ INTO new_tbl SELECT * FROM large_tbl;
参数说明:
append:走旁路导入路径。enable_parallel_dml parallel(N):指定并行度 N,开启并行 DML。
执行计划确认(Oracle 模式示例):
EXPLAIN EXTENDED INSERT /*+ append enable_parallel_dml parallel(16) */ INTO new_tbl SELECT * FROM large_tbl;
在返回结果的 Note 中应包含 Direct-mode is enabled in insert into select,确认已走旁路导入。
旁路导入使用限制:
- 只支持 PDML(并行 DML),非 PDML 场景无法使用旁路导入。
- 导入过程中会加表锁,同一表不能同时被多个旁路导入语句写入。
- 不支持在触发器(Trigger)中使用。
- 支持 LOB 类型,但 LOB 会走原事务写入路径,性能较差。
- 旁路导入属于 DDL 语句,无法在多行事务中执行;Autocommit 必须设置为 1;不能在 BEGIN 块中执行。
并行 DML 优先级说明:
- SQL 语句中的 Hint(如
PARALLEL(3))优先级高于会话级强制指定的并行度。 ENABLE_PARALLEL_DML必须配合PARALLEL(N)使用(当目标表 Schema 未指定表级并行度时)。
并行 DML 不支持的限制:
- 不支持 REPLACE、INSERT INTO ON DUPLICATE KEY UPDATE、多表 DML。
- 表上存在触发器、外键、唯一索引时,不支持并行 DML。
方案 B:会话级开启并行 DML(V4.x 适用)
Oracle 模式
ALTER SESSION ENABLE PARALLEL DML;
-- 或强制指定并行度
ALTER SESSION FORCE PARALLEL DML PARALLEL 6;
MySQL 模式
SET _FORCE_PARALLEL_DML_DOP = 6;
开启后执行:
INSERT /*+ append */ INTO new_tbl SELECT * FROM large_tbl;
3x 版本
分批导入 + 调整超时(V3.x 适用)
OceanBase V3.x 不支持旁路导入和并行 DML,建议采用以下方式:
- 拆分为多个小批次:按主键或分区键范围分批插入,避免单条 INSERT 语句执行时间过长。
- 调大 DML 超时时间:
SET ob_query_timeout = 3600000000; -- 单位:微秒,示例为 1 小时 - 使用并行 HINT(如 PARALLEL Hint 优化 SELECT 阶段并行度)。
规避方式
- 大数据量复制避免使用 CTAS:在预估数据量超过千万级或执行时间可能超过 1000 秒时,尽量启用旁路导入与并行 DML。
- 评估 DDL 超时影响:在执行批量 DDL 任务前,检查当前状态,避免并发 DDL 过多。