本文介绍在 OceanBase 数据库 V4.0 版本中如何解决 DDL 操作过程中遇到的常见问题。以下以表 t1 为例,说明在进行索引创建或其他 DDL 操作时的问题定位方法。
索引创建卡住
当索引创建操作停滞时,可通过查询 GV$SESSION_LONGOPS 视图确认当前状态,查询 OPNAME、TARGET 和 MESSAGE 字段。
使用以下语句,查询 GV$SESSION_LONGOPS 视图:
SELECT OPNAME, TARGET, MESSAGE FROM oceanbase.GV$SESSION_LONGOPS;
查询结果示例:
===================================================================
| OPNAME | TARGET | MESSAGE
| BUILD INDEX | T1 | status=WAIT_TRANS_END, schema_version=x, waiting_tablet=[tablet1,tablet3]
| BUILD INDEX | T2 | status=BUILD_REPLICA, scanned_rows=1000000, sorted_rows=200000
| REDEFINITION| T3 | status=COPY_CONSTRAINTS, constraints=[i1,constraint1]
根据查询结果可定位 DDL 执行阶段:
等待事务结束阶段:如果状态为
WAIT_TRANS_END,需根据等待的 tablet ID 和事务 ID 定位事务未结束的原因单副本构建阶段:如果状态为
BUILD_REPLICA,检查scanned_rows和sorted_rows是否符合预期。若行数长时间不变,可能是 SQL 执行卡住,建议使用 obstack/pstack 检查对应线程的状态。注意
DDL 单副本构建为 inner SQL,无法通过
__all_virtual_processlist 查看线程 ID,可通过 obstack 检查所有线程。依赖项复制阶段:如果状态为
COPY_CONSTRAINTS,确认具体等待的依赖项,并对该依赖项进行同样的诊断流程
索引创建失败
对于符合预期的错误场景,错误码和错误信息通常能指明具体原因。若出现 -4002/-4016/-5703 等非预期错误,需通过日志定位具体报错模块:
- 首先确定索引创建或 DDL SQL 的 trace ID。您可以通过设置
ob_enable_trace_log参数为true后执行trace查看,或在执行 SQL 的 Observer 服务器上通过检索 SQL 内容找到对应 trace ID - 在接收 SQL 的 Observer 上通过 trace ID 查找日志,确定错误发生在 SQL 解析阶段还是执行阶段(线上问题多发生在执行阶段)
- 如果在执行阶段报错,需使用 trace ID 在 RS 日志中查找错误码。对于 RS 调度流程本身的错误,通常可直接确定问题
- 如果错误发生在 RS 调度过程中的某个具体任务,则需根据任务类型在相应 Observer 上查找日志:
- 执行 RPC 任务:查看 RPC 目标端,在目标端上使用 trace ID 查找日志
- 单副本构建阶段的 inner SQL 执行错误:通过 LS 元数据表查询 LS 主节点所在 Observer,然后在该 Observer 上使用 trace ID 查找日志
索引创建速度不符合预期
通过 trace 命令或 trace 日志查询索引构建的全链路追踪信息,定位耗时较长的阶段,分析该阶段速度慢的原因。参考 OCP 全链路诊断原型图,对于单副本构建阶段,可能需借助 SQL PLAN MONITOR 定位具体算子的性能问题。更多信息,参考 租户全链路追踪配置。