name: obdiag-rca description: OceanBase 集群所有根因分析场景的统一 SOP。覆盖事务超时/回滚/断连、内存不足、合并卡住、日志盘满、DDL 失败、Schema 泄漏、GC 异常、弱一致性读、OMS 等。始终先执行 rca_run,如 RCA 脚本无法给出结论再按本 skill 降级到手动日志采集分析。
OceanBase RCA 根因分析统一 SOP
使用原则
- rca_run 优先:每个场景必须先尝试
rca_run(scene=xxx),不得直接跳到手动步骤。 - 结果判断:rca_run 输出含明确
suggest或root cause→ 直接向用户汇报,结束;输出为"无法定位"或空 → 进入降级手动分析。 - 降级:按本 skill 中对应场景的手动步骤执行,逐步推进,不要一次性调用大量工具。
- 场景参数:部分 scene 需要
--env参数(见各场景说明中"必填 env 参数"列)。注意:agent 工具rca_run不支持传 env,需要 env 参数的场景直接调用rca_run(scene="xxx")即可——obdiag 底层会自动读取上下文;若 rca_run 因缺少 env 参数而失败,直接进入手动降级分析步骤。
场景速查表
| 用户描述症状 | scene 名 | 必填 env 参数 | 降级标签 |
|---|---|---|---|
| 语句超时、ob_query_timeout | transaction_execute_timeout |
err_type="statement is timeout", tenant_id |
[语句超时] |
| 事务超时 | transaction_execute_timeout |
err_type="transaction is timeout" |
[事务超时] |
| 事务不结束、长事务 | transaction_not_ending |
tx_id(可选) |
[长事务] |
| 锁等待超时 | transaction_wait_timeout |
— | [锁等待] |
| 锁冲突、行锁 | lock_conflict |
error_msg(可选) |
[锁冲突] |
| 事务回滚 | transaction_rollback |
— | [事务回滚] |
| 事务其他错误 | transaction_other_error |
— | [事务其他] |
| 事务中断连 | transaction_disconnection |
— | [事务断连] |
| 断连、OBProxy 连接断开 | disconnection |
— | [断连] |
| 挂起事务 | suspend_transaction |
— | [挂起事务] |
| 内存不足、OOM | memory_full |
— | [内存不足] |
| SQL 执行内存高、work area 内存 | execute_memory_high |
— | [执行内存高] |
| 合并卡住、major compaction hold | major_hold |
— | [合并卡住] |
| 转储异常、freeze/dump | freeze_dump |
— | [转储异常] |
| Replay 卡住 | replay_hold |
— | [Replay卡住] |
| 日志盘满、clog 磁盘满 | clog_disk_full |
tenant_id(可选),ls_id(可选) |
[日志盘满] |
| DDL 失败 | ddl_failure |
— | [DDL失败] |
| DDL 磁盘满 | ddl_disk_full |
— | [DDL盘满] |
| 索引 DDL 报错 | index_ddl_error |
— | [索引DDL] |
| Schema 泄漏 | schema_leak |
— | [Schema泄漏] |
| 删除 observer 节点报错 | delete_server_error |
— | [删节点] |
| 分区自动分裂调度错误 | split_schedule_error |
— | [分裂调度] |
| Unit GC 问题 | unit_gc |
— | [Unit GC] |
| GC 异常 | gc_troubleshooting |
— | [GC异常] |
| 日志报错 / 错误码 | log_error |
— | [日志报错] |
| 弱一致性读问题 | weak_read_troubleshooting |
— | [弱读] |
| OMS 全量事务 | oms_full_trans |
— | [OMS全量] |
| OMS OBCDC 问题 | oms_obcdc |
— | [OMS OBCDC] |
标准执行流程
Step 1:收集必要参数后执行 rca_run
rca_list() # 可选:确认 scene 名及所需参数
rca_run(scene="<scene_name>") # agent 工具只接受 scene 和 cluster_config_path,无 env 参数
若 rca_run 成功给出根因建议 → 向用户汇报,结束本 skill。
Step 2:rca_run 不足时,按降级路径手动分析
降级手动分析
[语句超时]
常见原因:ob_query_timeout 设置过小;队列积压;location cache 频繁重试;锁冲突;全表扫描。
-- 1. 确认超时设置(单位:微秒,默认 10,000,000 = 10s)
SELECT * FROM oceanbase.CDB_OB_SYS_VARIABLES WHERE tenant_id=<tenant_id> AND NAME='ob_query_timeout';
SHOW PARAMETERS LIKE 'syslog_level';
-- 2. 检查队列积压(日志关键词)
-- gather_log grep: "dump tenant"
-- 解读:req_queue:total_size=<N>,N != 0 说明请求积压
-- 3. 若有 trace_id,采集日志
gather_log(since="30m", grep=["<trace_id>", "timeout_timestamp", "dump tenant"])
timeout_timestamp - cur_query_start_time >= ob_query_timeout→ 超时属正常行为,调大参数即可timeout_timestamp - cur_query_start_time < ob_query_timeout→ 非预期提前超时,需进一步排查
重试错误码排查(频繁出现说明 location cache 失效导致重试堆积超时):
gather_log(since="30m", grep=["ret=-4038", "ret=-4225", "ret=-4653", "ret=-6005"])
[事务超时]
-- 1. 确认事务超时参数
SHOW PARAMETERS LIKE 'ob_trx_timeout';
SHOW PARAMETERS LIKE 'ob_trx_idle_timeout';
-- 2. 检查队列积压
gather_log(since="1h", grep=["dump tenant", "req_queue"])
-- 3. 检查锁冲突
gather_log(since="30m", grep=["mvcc_write conflict"])
[长事务] / [挂起事务]
rca_run 需要 tx_id 参数;如用户未提供,先从系统视图找到活跃长事务。
-- 1. 找长事务
SELECT TX_ID, TENANT_ID, STATE, CTX_CREATE_TIME, TX_EXPIRED_TIME, SESSION_ID
FROM oceanbase.GV$OB_TRANSACTION_PARTICIPANTS
WHERE STATE='ACTIVE'
ORDER BY CTX_CREATE_TIME ASC LIMIT 20;
-- 2. 查指定事务详情
SELECT * FROM oceanbase.GV$OB_TRANSACTION_PARTICIPANTS WHERE TX_ID='<tx_id>';
-- 3. 查 session 信息
SELECT * FROM oceanbase.GV$OB_PROCESSLIST WHERE time > 60 ORDER BY time DESC LIMIT 20;
- STATE='ACTIVE' + SESSION_ID 非空 → 仍有活跃 SQL,告知用户该 session 的 SQL
- STATE 非 ACTIVE(commit 阶段)→ 事务卡在提交阶段,检查副本日志同步
CTX_CREATE_TIME = TX_EXPIRED_TIME→ 事务已到期
-- 4. follower 落后排查(事务卡 replay 时)
SELECT * FROM oceanbase.__all_virtual_log_stat WHERE tenant_id=<tid> AND ls_id=<ls_id>;
-- 关注 end_lsn 是否明显落后
[锁等待] / [锁冲突]
error_msg 含 "Shared lock conflict":
gather_log(since="30m", grep=["lock_for_read need retry"])
-- 从日志中提取 data_trans_id → 再 gather_log grep data_trans_id
-- 说明:读锁被提交阶段的事务占用,建议用 transaction_not_ending scene 继续分析
error_msg 含 "Lock wait timeout exceeded":
gather_log(since="30m", grep=["mvcc_write conflict"])
-- 从日志中提取 conflict_tx_id → 再 gather_log grep conflict_tx_id
-- 说明:行锁被另一事务持有,可等待或 kill 阻塞 session
前提:syslog_level 需含 WDIAG(读锁)/ INFO(行锁),否则日志会缺失。
-- OB 4.2+ 可直接查锁等待
SELECT * FROM oceanbase.GV$OB_LOCKS LIMIT 20;
SELECT * FROM oceanbase.CDB_OB_DEADLOCK_HISTORY ORDER BY create_time DESC LIMIT 10;
[事务回滚] / [事务断连] / [事务其他]
gather_log(since="30m", grep=["rollback", "disconnect", "ERROR"])
analyze_log(log_path="<gather output path>")
[断连]
此 scene 依赖 OBProxy 节点,需配置文件中有
obproxy_nodes。
-- 1. 采集 OBProxy diagnosis 日志
gather_obproxy_log(since="30m", grep=["CONNECTION](trace_type", "disconnect", "error"])
-- 2. 检查 OBProxy 参数
SHOW PROXYCONFIG LIKE 'request_buffer_length';
-- 过小时需调大(参考 issue #575)
[内存不足]
-- 1. 内存配置
SHOW PARAMETERS LIKE 'memory_limit%';
SHOW PARAMETERS LIKE 'memstore_limit_percentage';
-- 2. memtable freeze 状态(关键)
SELECT * FROM oceanbase.__all_virtual_minor_freeze_info;
-- state 非正常时,进一步看 memstore_info
-- 3. memstore 详情(找 is_active='NO' 的行)
SELECT * FROM oceanbase.__all_virtual_memstore_info
WHERE is_active='NO' ORDER BY start_scn LIMIT 10;
解读 freeze_state:
NOT_READY_FOR_FLUSH:unsubmitted_count == unsynced_count != 0→ 可能是多源数据问题unsubmitted_count=0, write_ref_count!=0, unsynced_count!=0→ 日志回调未完成- 三者均为 0 → replay/callback 未推过 memtable 右边界,检查 ReplayService
READY_FOR_FLUSH:flush 条件满足但未执行,检查 compaction diagnose 和 DAG 积压RELEASED:refcount 未清零,通常需 OceanBase 支持
-- 4. compaction 诊断
SELECT * FROM oceanbase.__all_virtual_compaction_diagnose_info;
SELECT * FROM oceanbase.__all_virtual_dag LIMIT 20;
[转储异常]
-- 1. 转储进度
SELECT * FROM oceanbase.GV$OB_TABLET_COMPACTION_PROGRESS
WHERE TYPE='MINI_MERGE' ORDER BY START_TIME ASC LIMIT 20;
-- 2. DAG 调度器积压
SELECT * FROM oceanbase.__all_virtual_dag_scheduler
WHERE svr_ip='<ip>' AND svr_port=<port> AND tenant_id=<tid>;
-- 3. Compaction 建议
SELECT * FROM oceanbase.GV$OB_COMPACTION_SUGGESTIONS LIMIT 20;
gather_log(since="1h", grep=["freeze", "minor_freeze", "FAILED", "dag_ret"])
- minor freeze FAILED:在日志中匹配
dag_ret和tablet_id/ls_id - 长时间运行的 minor freeze:检查 memstore 压力、DAG 队列、磁盘/CPU
[合并卡住]
-- 1. 合并整体状态
SELECT * FROM oceanbase.DBA_OB_MAJOR_COMPACTION;
-- IS_ERROR='YES' → 合并出错;SUSPEND_SCN 非空 → 合并被挂起
-- 2. checksum 错误
SELECT * FROM oceanbase.CDB_OB_TABLET_CHECKSUM_ERROR_INFO LIMIT 10;
-- 3. compaction 诊断详情
SELECT * FROM oceanbase.__all_virtual_compaction_diagnose_info;
-- 4. DDL 任务(DDL 未完成可阻塞合并)
SELECT * FROM oceanbase.DBA_OB_DDL_TASK_PROGRESS LIMIT 20;
-- 5. 重复索引名排查(Issue #607)
SELECT TABLE_NAME, INDEX_NAME, COUNT(*) AS cnt
FROM oceanbase.CDB_INDEXES
GROUP BY INDEX_NAME HAVING cnt > 1 LIMIT 10;
gather_log(since="2h", grep=["weak_read_timestamp", "log disk space is almost full",
"generate_weak_read_timestamp_", "major_hold", "compaction"])
[Replay卡住]
SELECT * FROM oceanbase.__all_virtual_log_stat WHERE tenant_id=<tid>;
-- 对比各副本 end_lsn,落后较多的副本即为瓶颈
gather_log(since="1h", grep=["replay", "replay_hold", "apply_log", "ObLogReplayService"])
analyze_log(log_path="<gather output path>")
[日志盘满] / [DDL盘满]
-- 1. 日志盘阈值配置
SHOW PARAMETERS LIKE 'log_disk_utilization_threshold';
SHOW PARAMETERS LIKE 'log_disk_utilization_limit_threshold';
-- 2. 找卡住的 checkpoint(clog checkpoint 未推进)
-- gather_log grep: "clog checkpoint no change", "ObLSTxService::get_rec_scn"
-- 3. 各 LS 状态
SELECT * FROM oceanbase.GV$OB_LOG_STAT WHERE tenant_id=<tid> LIMIT 20;
gather_sysstat() -- 确认实际磁盘使用率
gather_log(since="1h", grep=["clog checkpoint no change", "disk full", "no space left"])
[DDL失败] / [索引DDL]
-- 1. DDL 任务进度
SELECT * FROM oceanbase.DBA_OB_DDL_TASK_PROGRESS LIMIT 20;
-- 2. RS 事件历史
SELECT * FROM oceanbase.DBA_OB_ROOTSERVICE_EVENT_HISTORY
WHERE event LIKE '%ddl%' ORDER BY timestamp DESC LIMIT 30;
-- 3. DDL 错误信息
SELECT * FROM oceanbase.DBA_OB_DDL_TASK_PROGRESS WHERE status='FAILED' LIMIT 10;
gather_log(since="1h", grep=["ddl", "INDEX", "OB_ERR", "ERROR"])
[Schema泄漏]
-- 1. 内存占用
SELECT * FROM oceanbase.GV$OB_MEMORY
WHERE context LIKE '%schema%' ORDER BY hold DESC LIMIT 20;
-- 2. 活跃连接数 vs 连接池配置
SELECT COUNT(*) FROM oceanbase.GV$OB_PROCESSLIST;
-- 3. schema 版本刷新
SELECT svr_ip, svr_port, tenant_id, refreshed_schema_version, received_schema_version
FROM oceanbase.GV$OB_SERVER_SCHEMA_INFO LIMIT 20;
若连接数正常但内存不释放,检查应用连接池是否正确关闭连接。
[删节点] / [Unit GC] / [GC异常] / [分裂调度]
-- RS 事件历史(最近 30 条)
SELECT * FROM oceanbase.DBA_OB_ROOTSERVICE_EVENT_HISTORY
ORDER BY timestamp DESC LIMIT 30;
-- Unit 状态
SELECT * FROM oceanbase.DBA_OB_UNITS WHERE status != 'NORMAL' LIMIT 20;
-- LS 状态
SELECT * FROM oceanbase.GV$OB_LOG_STAT LIMIT 20;
gather_log(since="1h", grep=["gc", "unit_gc", "server_manager", "split", "ERROR"])
[日志报错]
-- 1. 用错误码或关键词过滤
gather_log(since="1h", grep=["ret=-<错误码>", "ERROR"])
analyze_log(log_path="<gather output path>")
常见错误码参考:-4012(超时)、-5024(主键冲突)、-4016(内部错误)、-6213(事务超时)。
[弱读]
-- 配置
SHOW PARAMETERS LIKE 'weak_read_version_refresh_interval';
SELECT * FROM oceanbase.GV$OB_WEAK_READ_SERVICE LIMIT 20;
gather_log(since="30m", grep=["weak_read", "generate_weak_read_timestamp", "replica_readable"])
[OMS全量] / [OMS OBCDC]
gather_oms_log(since="1h")
analyze_log(log_path="<gather output path>")
对于 OBCDC 类问题,重点查 gather_oms_log 输出中的 component 日志(Ghana / CDC),用 file_list + file_read 逐层查看。
降级后的汇报原则
- 说明
rca_run的局限(如:脚本未覆盖当前版本、依赖数据不完整、缺少必要 env 参数等)。 - 手动分析结论必须基于工具返回数据,不得凭推测下结论。
- 若手动步骤仍无法定位,明确列出还需要哪些信息(OB 版本、发生时间点、业务变更、syslog_level 设置等)。
- 可引导用户将采集包上传至 OceanBase 社区论坛或提 issue 进行深度分析。