批量插入报错,出现“ArrayIndexOutOfBoundException”异常

【 使用环境 】测试环境
【 OB or 其他组件 】Oceanbase 4.2.5 bp3
【 使用版本 】Oceanbase 4.2.5 bp3
【问题描述】
批量插入时,出现java.lang.ArrayIndexOutOfBoundException的异常,

截图如下:

【复现路径】问题出现前后相关操作
【附件及日志】推荐使用OceanBase敏捷诊断工具obdiag收集诊断信息,详情参见链接(右键跳转查看):

【SOP系列 22 】——故障诊断第一步(自助诊断和诊断信息收集)

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

1 个赞

用户问题总结:在 OceanBase 4.2.5 bp3 版本中进行批量插入时,出现 java.lang.ArrayIndexOutOfBoundsException 异常。

推荐使用 obdiag 工具进行日志采集,并将采集到的日志提供给我们以便确认问题所在。

根因分析场景: SQL 执行出错
根因分析命令: obdiag rca run --scene=sql_execution_error --env “{db_connect=’-h127.0.0.1 -P2881 -utest@test -p****** -Dtest’, trace_id=‘Yxx’}” (需要您补充具体的数据库连接信息和 trace_id)

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

为了更好地帮助您解决问题,请您按照上述命令采集日志并上传日志压缩包。同时,请您提供以下信息:

  1. 批量插入的 SQL 语句是什么?是否可以提供一个最小可复现的案例?
  2. 出现异常时的具体错误堆栈信息能否提供完整内容?
  3. 当前集群的配置参数中,与批量插入相关的参数(如 ob_sql_batched_multi_statements)是否有特殊设置?
  4. 是否可以确认该问题是否在特定的数据量或特定的表结构下更容易复现?
  5. 您提到的是 Java 异常,是否可以确认这是客户端代码抛出的异常还是 OceanBase 数据库返回的错误?如果是客户端代码问题,请检查绑定参数的数量是否正确。

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

1 个赞

obclient客户端连接 执行报错么?

1 个赞

老师,客户端执行没问题 ~

1 个赞

根据您提供的信息,客户端执行批量插入操作时没有问题,但在某些情况下仍然出现了 java.lang.ArrayIndexOutOfBoundsException 异常。以下是针对该问题的详细分析和可能的解决方案:


已知信息总结

  1. 异常来源:从堆栈信息来看,异常发生在 MyBatis 框架中 (org.mybatis.spring.MyBatisExceptionTranslator),具体是设置参数时抛出的 ArrayIndexOutOfBoundsException
  2. SQL 语句:您提供了批量插入的 SQL 语句,目标表为 dolphinscheduler.degp_flink_heartbeat_rd,插入了多行数据。
  3. 客户端行为:直接通过客户端(如 obclient)执行 SQL 语句时正常,但通过 Java 程序调用时出现问题。
  4. OceanBase 版本:OceanBase 4.2.5 bp3。

问题分析

1. 异常原因

ArrayIndexOutOfBoundsException 通常表示数组越界,可能是以下原因之一:

  • 绑定参数数量不匹配:MyBatis 在设置 SQL 参数时,传入的参数数量与 SQL 中定义的占位符数量不一致。
  • 批量插入逻辑问题:如果使用了 MyBatis 的 <foreach> 标签进行批量插入,可能存在参数绑定错误或数据结构问题。
  • 驱动版本兼容性问题:OceanBase JDBC 驱动版本与 MyBatis 或其他依赖库版本不兼容,导致参数解析异常。

2. 客户端与 Java 程序差异

  • 直接通过客户端执行 SQL 语句时,SQL 是以完整字符串形式发送到数据库的,因此不会涉及参数绑定问题。
  • 而在 Java 程序中,SQL 通常是预编译的(PreparedStatement),需要将参数逐一绑定到 SQL 占位符中。如果绑定逻辑有问题,则可能导致异常。

解决方案

1. 检查 MyBatis 配置

  • 确认 SQL 语句中的占位符数量:确保 SQL 中的 ? 数量与实际传入的参数数量一致。
  • 检查 <foreach> 标签的使用:如果您使用了 MyBatis 的 <foreach> 标签,请确保集合数据结构正确,并且每个元素都能正确映射到 SQL 占位符中。

示例:

<insert id="batchInsert" parameterType="java.util.List">
    INSERT INTO dolphinscheduler.degp_flink_heartbeat_rd (
        project_name_, yarn_name_, job_name_, app_id_, job_id_, submit_type_, status_, extra_, update_date_
    ) VALUES
    <foreach collection="list" item="item" separator=",">
        (#{item.projectName}, #{item.yarnName}, #{item.jobName}, #{item.appId}, #{item.jobId}, 
         #{item.submitType}, #{item.status}, #{item.extra}, #{item.updateDate})
    </foreach>
</insert>
  • 验证传入参数:确保传入的 list 数据结构正确,例如每个对象都包含 projectName, yarnName 等字段。

2. 检查 OceanBase JDBC 驱动版本

  • 确保使用的 OceanBase JDBC 驱动版本与 OceanBase 数据库版本兼容。您可以参考 OceanBase 官方文档 获取兼容性信息。
  • 如果不确定驱动版本是否兼容,可以尝试升级到最新版本的 OceanBase JDBC 驱动。

3. 启用 SQL Trace 功能

为了进一步定位问题,建议启用 SQL Trace 功能,查看具体的 SQL 执行链路和参数绑定情况。

步骤如下:

SET ob_enable_show_trace = 1;
SHOW TRACE;

通过 SHOW TRACE 查看 SQL 执行过程中各阶段的耗时和参数绑定情况。

4. 日志采集与分析

如果问题仍然无法解决,建议使用 obdiag 工具采集日志并上传。具体命令如下:

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

请将采集到的日志压缩包上传,并提供完整的错误堆栈信息。


可能的内在知识解答

如果上述方法仍无法解决问题,可能是以下原因之一:

  1. 批量插入限制:OceanBase 社区版对单条 SQL 的插入行数有一定限制(默认为 16384 行)。如果插入行数过多,可能会导致异常。
    • 解决方案:分批插入数据,每批次不超过 1000 行。
  2. 参数绑定逻辑问题:如果 MyBatis 的参数绑定逻辑存在问题,可能会导致数组越界。
    • 解决方案:打印出实际生成的 SQL 和绑定参数,确保二者一致。

下一步建议

  1. 检查 MyBatis 配置文件和代码逻辑,确保参数绑定正确。
  2. 升级 OceanBase JDBC 驱动至最新版本。
  3. 启用 SQL Trace 功能,查看具体执行链路。
  4. 使用 obdiag 工具采集日志并上传,以便进一步分析。

如果仍有疑问,请提供更多上下文信息(如 MyBatis 配置文件、Java 代码片段等),我们将尽力为您解决!

更多信息请查看:

  1. 全链路追踪展示
  2. GV$ACTIVE_SESSION_HISTORY

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

2 个赞

java程序使用的驱动 是哪个版本的

1 个赞

老师,你好。

MySQL 8.0.27~

插入的数据 能提供几条么?

mysql 8.0的驱动,建议使用8.0.26以下的版本,建议使用8.0.25,如果非要使用8.0.26以上的版本需要增加 JDBC url 参数 trackSessionState=true,这个报错是因为 8.0.26mysql驱动的行为发生了改变,导致这个错误的产生

1 个赞

MySQL 8.x 驱动报错 ArrayIndexOutOfBoundsException

https://www.oceanbase.com/knowledge-base/oceanbase-connector-j-1000000000254504?back=kb

1 个赞

trackSessionState=true,研发说配置了。唉。

另外,我看到一些类似的案例,说要升级为:8.2.0 +

项目从mysql 改成OceanBase后出现在的问题 - 社区问答- OceanBase社区-分布式数据库

尝试一下8.0.25的驱动呢,这个版本的驱动肯定是没问题的,也是建议使用的8.0的版本的驱动

1 个赞

如果上面的没法解决 可以按照这个帖子说的 试一下

跟驱动版本关系不大,很多案例,啥版本的MySQL驱动都有遇到过这种报错,先关闭PS试试,useServerPrepStmts=false

大多数使用案例表明, 8.0.25确实好些