基于湖库一体架构,统一管理结构化、半结构化与非结构化等多模态数据,一个系统承载事务处理、实时分析与 AI 工作负载。
DDL 诊断增强之实时进度展示
更新时间:2026-08-13 07:41
在生产环境中遇到的数据库问题之一是 DDL(数据定义语言)操作执行缓慢,难以快速诊断慢的原因。OceanBase 数据库 V4.1 提供了实时 DDL 进度展示功能,通过查询 GV$SESSION_LONGOPS 视图,可以展示 DDL 操作的执行状态和进度。本文将介绍如何使用该视图来监控 DDL 操作的实时进度。
GV$SESSION_LONGOPS 视图的介绍和字段说明
在 OceanBase 数据库中,GV$SESSION_LONGOPS 视图的字段及其含义如下:
| 列名 | 类型 | 说明 |
|---|---|---|
| SID | bigint(20) | Session ID |
| TRACE_ID | varchar(64) | Trace ID |
| OPNAME | varchar(128) | 具体 DDL 操作名 |
| TARGET | varchar(128) | DDL 操作对象 |
| SVR_IP | varchar(46) | 机器 IP |
| SVR_PORT | bigint(20) | 机器 Port |
| START_TIME | bigint(20) | 开始时间 |
| ELAPSED_SECONDS | decimal(24,4) | 已消耗时间 |
| TIME_REMAINING | bigint(20) | 预估剩余时间 |
| LAST_UPDATE_TIME | bigint(20) | 记录更新时间 |
| MESSAGE | varchar(500) | 补充信息 |
监测 DDL 进度的基本步骤
要监测 DDL 操作的进度,首先需要创建两个会话(session),一个用于执行 DDL,另一个用于查询 GV$SESSION_LONGOPS 视图,两个 session 都以普通租户登录。
使用示例,包括建索引、添加主键和删列等常见 DDL 操作。
观测建索引
建索引的主要时间一般发生在索引数据补全,在某些环境,可能因为建索引的时,还有并发的事务未执行完成,也有可能在等待事务结束部分,进度观测例子中主要展示下这两个部分的进度。
等待事务结束阶段
select * from oceanbase.gv$session_longops\G
输出结果如下:
*************************** 1. row ***************************
SID: -1
TRACE_ID: YE5186458A15C-0005EF63AE10FBBB-0-0
OPNAME: create index
TARGET: __idx_500005_i1
SVR_IP: xxx.xxx.xxx.xxx
SVR_PORT: 58648
START_TIME: 2022-12-09
ELAPSED_SECONDS: 7
TIME_REMAINING: 0
LAST_UPDATE_TIME: 2022-12-09
MESSAGE: TENANT_ID: 1004, TASK_ID: 2, STATUS: WAIT TRANS END, PENDING_TX_ID: 76
在 MESSAGE 字段中,会展示 WAIT TRANS END,显示未结束的事务 ID(如 PENDING_TX_ID: 76),可进一步通过 __all_virtual_trans_stat 表中的 trans_id 字段来获取对应的事务信息。
数据补全阶段
select * from oceanbase.gv$session_longops\G
输出结果如下:
*************************** 1. row ***************************
SID: -1
TRACE_ID: YE5186458A15C-0005EF60F182F228-0-0
OPNAME: create index
TARGET: __idx_500008_i1
SVR_IP: xxx.xxx.xxx.xxx
SVR_PORT: 58648
START_TIME: 2022-12-09
ELAPSED_SECONDS: 38
TIME_REMAINING: 0
LAST_UPDATE_TIME: 2022-12-09
MESSAGE: TENANT_ID: 1004, TASK_ID: 6, STATUS: REPLICA BUILD, ROW_SCANNED: 10000000, ROW_SORTED: 19771966, ROW_INSERTED: 0
在 MESSAGE 字段中,TENANT_ID 为租户 ID,TASK_ID 为 DDL 的任务 ID,STATUS 为 DDL 执行到的状态,REPLICA BUILD 数据补全阶段,并提供 ROW_SCANNED(扫描主表数据)、ROW_SORTED(排序)、ROW_INSERTED(写入到索引表阶段)等信息。由于排序阶段可能进行多轮归并,所以 ROW_SORTED 通常比 ROW_SCANNED 和 ROW_INSERTED 要多。
注意
建索引的主要时间一般发生在索引数据补全,在某些环境,可能因为建索引的时,仍存在并发的事务尚未执行完成,也有可能在等待事务结束部分,所以进度观测例子中主要展示这两个部分的进度。
各个字段含义。
sid:现在没有填值,为默认的 -1。
trace_id: OBServer 程序日志的ID,可以用该ID来搜索相关的日志文件。
opname:建索引时,会展示 create index 信息。
target:建索引时,展示正在创建的索引名。
svr_ip: 调度任务在哪个 OBServer 执行。
svr_port:调度任务在哪个 OBServer 执行。
start_time:索引构建开始时间,这里只精确到日期,跟 Oracle 是兼容的。
elapsed_seconds: 索引构建执行的时间,单位为秒。
time_remaining: 兼容 Oracle 的字段,暂时还没有实现剩余时间预测的能力。
last_update_time: 统计信息收集的时间,也是精确到日期,跟 Oracle 是兼容的。
message:里面包含了多个信息,TENANT_ID 为租户 ID,TASK_ID 为 DDL 的任务 ID,STATUS 为 DDL 执行到的状态,REPLICA BUILD 指的是数据补全阶段,索引数据补全主要分为扫描主表数据,排序,写入到索引表阶段,三个阶段处理的行数分别对应于ROW_SCANNED, ROW_SORTED 和 ROW_INSERTED,因排序阶段可能会进行多轮归并,所以ROW_SORTED 的行数通常比 ROW_SCANNED 和 ROW_INSERTED 要多。
观测添加主键
观测下数据补全阶段。
数据补全阶段,主表变更记录
select * from oceanbase.gv$session_longops\G
输出结果如下:
*************************** 2. row ***************************
SID: -1
TRACE_ID: YE5186458A15C-0005EF60F182F22F-0-0
OPNAME: add primary key
TARGET: t1
SVR_IP: xxx.xxx.xxx.xxx
SVR_PORT: 58648
START_TIME: 2022-12-09
ELAPSED_SECONDS: 63
TIME_REMAINING: 0
LAST_UPDATE_TIME: 2022-12-09
MESSAGE: TENANT_ID: 1004, TASK_ID: 7, STATUS: COPY DEPENDENT OBJECTS, CHILD TASK IDS: [ 8 ]
数据补全阶段,主表上索引的补全记录
select * from oceanbase.gv$session_longops\G
输出结果如下:
*************************** 1. row ***************************
SID: -1
TRACE_ID: YE5186458A15C-0005EF60F182F22F-0-0
OPNAME: create index
TARGET: __idx_500030_i1
SVR_IP: xxx.xxx.xxx.xxx
SVR_PORT: 58648
START_TIME: 2022-12-09
ELAPSED_SECONDS: 6
TIME_REMAINING: 0
LAST_UPDATE_TIME: 2022-12-09
MESSAGE: TENANT_ID: 1004, TASK_ID: 8, STATUS: REPLICA BUILD, ROW_SCANNED: 5518389, ROW_SORTED: 0, ROW_INSERTED: 0
同样监测数据补全阶段,发现两条记录,一条是对主表变更的记录,另一条是主表上索引的补全记录。字段含义与建索引时类似。
观测删列
观测下数据补全阶段。
数据补全阶段,记录一
select * from oceanbase.gv$session_longops\G
输出结果如下:
*************************** 1. row ***************************
SID: -1
TRACE_ID: YE5186458A15C-0005EF60F182F240-0-0
OPNAME: drop column
TARGET: t1
SVR_IP: xxx.xxx.xxx.xxx
SVR_PORT: 58648
START_TIME: 2022-12-09
ELAPSED_SECONDS: 26
TIME_REMAINING: 0
LAST_UPDATE_TIME: 2022-12-09
MESSAGE: TENANT_ID: 1004, TASK_ID: 13, STATUS: COPY DEPENDENT OBJECTS, CHILD TASK IDS: [ 14 ]
数据补全阶段,记录二
select * from oceanbase.gv$session_longops\G
输出结果如下:
*************************** 2. row ***************************
SID: -1
TRACE_ID: YE5186458A15C-0005EF60F182F240-0-0
OPNAME: create index
TARGET: __idx_500076_i1
SVR_IP: xxx.xxx.xxx.xxx
SVR_PORT: 58648
START_TIME: 2022-12-09
ELAPSED_SECONDS: 8
TIME_REMAINING: 0
LAST_UPDATE_TIME: 2022-12-09
MESSAGE: TENANT_ID: 1004, TASK_ID: 14, STATUS: REPLICA BUILD, ROW_SCANNED: 10000000, ROW_SORTED: 213098, ROW_INSERTED: 0
删列的数据补全阶段与添加主键类似,但没有排序阶段,因此在 MESSAGE 字段中只会展示 ROW_SCANNED(扫描主表数据) 和 ROW_INSERTED(写入到索引表阶段)。删列操作与中间加列操作(非生成列)类似,不涉及排序阶段。
适用版本
OceanBase 数据库 V4.1.0 及之后版本。