OB load data Transaction context does not exist

【 使用环境 】测试环境
【 OB or 其他组件 】OB
【 使用版本 】4.2.1.8
【问题描述】
执行以下导入操作,执行到半小时会报错

insert /*+ append direct(false,0,'full') enable_parallel_dml parallel(24) */ into lineitem1 select * from lineitem order by l_orderkey asc  limit 300000000;
Fri Oct 25 17:21:49 CST 2024
ERROR 6002 (HY000) at line 1: Transaction context does not exist

real    29m33.858s
user    0m0.009s
sys     0m0.002s
Fri Oct 25 17:51:23 CST 2024

根据audit 里面查到的trace_id 搜索日志,看到对应时间点内observer.log 的报错

有大佬帮忙看下这个是什么原因不?或者有啥排查方向?感谢大佬们

【备注】基于 LLM 和开源文档 RAG 的论坛小助手已开放测试,在发帖时输入 [@论坛小助手] 即可召唤小助手,欢迎试用!

1 个赞

根据您的描述,您在执行大数据量插入操作时遇到了 “Transaction context does not exist” 错误。这可能是由于事务上下文在执行过程中被意外删除或丢失导致的。为了更好地诊断和解决问题,建议您使用 obdiag 工具进行日志采集和根因分析。

根因分析场景: 事务其他错误

根因分析命令: obdiag rca run --scene=transaction_other_error

日志采集场景: 事务执行出错

日志采集命令: obdiag gather scene run --scene=observer.sql_err --env “{db_connect=’-h127.0.0.1 -P2881 -utest@test -p****** -Dtest’, trace_id=‘Yxx’}”

请您按照以下步骤操作:

  1. 根因分析

    obdiag rca run --scene=transaction_other_error
    

    这个命令会帮助我们分析事务上下文不存在的具体原因。

  2. 日志采集

    obdiag gather scene run --scene=observer.sql_err --env "{db_connect='-h127.0.0.1 -P2881 -utest@test -p****** -Dtest', trace_id='Yxx'}"
    

    这个命令会收集与 SQL 执行错误相关的日志,以便我们进一步分析问题。

请提供以下信息以便我们更好地帮助您:

  1. 您能否提供具体的错误日志或错误消息?
  2. 您执行的大数据量插入操作的具体 SQL 语句是什么?
  3. 您的 OceanBase 集群当前的配置情况如何?特别是与事务和日志相关的配置。
  4. 在执行插入操作之前,是否有其他操作或事件发生,例如系统重启、配置变更等?
  5. 您是否尝试过重新执行相同的插入操作?如果有,结果如何?

感谢您的配合,我们将尽快为您解决问题。

详情请参考:

  1. 4000 ~ 4499
  2. 0001 ~ 3999
  3. 在您开始前

附上敏捷诊断工具 obdiag 使用帮助链接

1 个赞

使用日志里冲突的事务id先去audit看看事务里的sql,看看为啥锁冲突

1 个赞

你这个时间段的observer.log日志发一下 具体分析一下

1、–根据时间和执行语句查询诊断信息
select query_sql,svr_ip,TRACE_ID,client_ip,TENANT_NAME,user_name,DB_NAME,ELAPSED_TIME,RET_CODE,FROM_UNIXTIME(ROUND(REQUEST_TIME/1000/1000),’%Y-%m-%d %H:%i:%S’) from GV$OB_SQL_AUDIT
WHERE tenant_id=1002 and REQUEST_TIME>=‘2024-04-05 14:34:00’ and lower(query_sql) like ‘%insert /*+ append direct(false,0,‘full’) enable_parallel_dml parallel(24) */ into lineitem1 select * from lineitem order by l_orderkey asc limit 300000000%’ order by elapsed_time desc
limit 10;
2、应该是有行锁冲突 可以用obdiag诊断锁冲突

obdiag 一键诊断锁冲突

https://www.oceanbase.com/docs/obdiag-cn

根据您提供的 GV$OB_SQL_AUDIT 视图查询结果,可以看到执行插入操作时确实出现了错误。具体错误码为 -5019-5001。这些错误码通常与事务处理和资源限制有关。以下是这些错误码的解释和可能的解决方案:

错误码解释

  1. 错误码 -5019

    • 错误原因:事务上下文不存在。
    • 可能的原因:事务在执行过程中被意外中断或超时。
  2. 错误码 -5001

    • 错误原因:事务超时。
    • 可能的原因:事务执行时间超过了配置的超时时间。

解决方案

  1. 增加事务超时时间

    • 您可以尝试增加事务超时时间,以允许更长时间的事务执行。可以通过修改 ob_trx_timeoutob_trx_idle_timeout 参数来实现。
    -- 查看当前的事务超时时间
    SHOW VARIABLES LIKE 'ob_trx_timeout';
    SHOW VARIABLES LIKE 'ob_trx_idle_timeout';
    
    -- 修改事务超时时间
    SET GLOBAL ob_trx_timeout = 1800000000; -- 30分钟
    SET GLOBAL ob_trx_idle_timeout = 1800000000; -- 30分钟
    
  2. 优化 SQL 语句

    • 检查 SQL 语句的性能,确保没有不必要的复杂操作。可以使用 EXPLAIN 命令来分析 SQL 语句的执行计划。
    EXPLAIN SELECT * FROM lineitem ORDER BY l_orderkey ASC LIMIT 300000000;
    
  3. 分批插入数据

    • 如果数据量非常大,可以考虑分批插入数据,以减少单个事务的执行时间。
    -- 分批插入数据
    INSERT /*+ append direct(false,0,'full') enable_parallel_dml parallel(24) */ INTO lineitem1 SELECT * FROM lineitem WHERE l_orderkey BETWEEN 1 AND 100000000;
    INSERT /*+ append direct(false,0,'full') enable_parallel_dml parallel(24) */ INTO lineitem1 SELECT * FROM lineitem WHERE l_orderkey BETWEEN 100000001 AND 200000000;
    INSERT /*+ append direct(false,0,'full') enable_parallel_dml parallel(24) */ INTO lineitem1 SELECT * FROM lineitem WHERE l_orderkey BETWEEN 200000001 AND 300000000;
    
  4. 检查系统资源

    • 确保系统资源(如 CPU、内存、磁盘 I/O)充足,避免因资源不足导致事务超时。
    • 使用 topiostat 等命令监控系统资源使用情况。
  5. 日志分析

    • 继续使用 obdiag 工具进行日志分析,以获取更多详细的错误信息。
    obdiag rca run --scene=transaction_other_error
    obdiag gather scene run --scene=observer.sql_err --env "{db_connect='-h127.0.0.1 -P2881 -utest@test -p****** -Dtest', trace_id='YB420A0AA020-0006255A3FFD4350-0-0'}"
    

总结

通过增加事务超时时间、优化 SQL 语句、分批插入数据以及检查系统资源,可以有效解决事务上下文不存在和事务超时的问题。同时,使用 obdiag 工具进行日志分析可以帮助您更深入地了解问题的根因。

希望以上建议对您有所帮助。如果问题仍然存在,请提供更多详细信息,我们将继续为您提供支持。

具体信息可参考以下文档:

  1. GV$OB_SQL_AUDIT
  2. 查找特定 SQL 请求的日志
  3. 查询排名 TOP N 的 SQL

(小助手的答复已结束,如未能解决您的问题,请继续提问并等待其他同学的回复,谢谢!)

日志有点大,传不上来,你们有啥可以收的方式吗?刚才搜了下audit 已经被清理了,找不到之前的记录了,日志我保留下来了


截取了一部分的错误信息,帮忙看下,感谢大佬

日志压缩一下 可以上传50M的日志 日志尽量发全一点 可以分析一下 具体的问题


根据trace_id查询的 日志 画红线的地方 看着日志不全

observer.tar.gz (24.5 MB)
这个是新跑的一个日志,和之前的一样现象

检索对应observer 日志,可以发现有6005错误,failed to lock write_memtable 相关信息,可确定为行级锁冲突导致的sql变慢。
1、根据trace_id=YB420A0AA020-000625996C1DA4FF-0-0 查询一下 看看这个语句执行的时间
select query_sql,svr_ip,TRACE_ID,client_ip,TENANT_NAME,user_name,DB_NAME,ELAPSED_TIME,RET_CODE,FROM_UNIXTIME(ROUND(REQUEST_TIME/1000/1000),’%Y-%m-%d %H:%i:%S’) from GV$OB_SQL_AUDIT
WHERE tenant_id=1002 and REQUEST_TIME>=‘2024-10-29 00:00:00’ and TRACE_ID=‘YB420A0AA020-000625996C1DA4FF-0-0’ order by elapsed_time desc
limit 10;