问题现象
应用跑批,偶发性断连,报错 unexpected end of stream,从应用侧报错可以看出,报错执行的语句是形如 batch xx; batch xx;batch xx ... 的 batch update 的方式。
org.springframework.dao.TransientDataAccessResourceException:
### Error updating database. Cause: java.sql.SQLTransientConnectionException: (conn=1852878) unexpected end of stream, read 0 bytes from 4
### The error may exist in URL [jar:file:/srv/www/app/pushpro-adapter-jygpush/pushpro-adapter-jygpush.jar!/BOOT-INF/classes!/mapper/unifypushpro/UnifyMessageDOMapper.xml]
### The error may involve com.ebscn.pushpro.mp.mapper.unifypushpro.UnifyMessageDOMapper.updateBatch-Inline
### The error occurred while setting parameters
### SQL: UPDATE xxxxx_xxxxx SET status = ?, error = ?, xxxxx_time = ? WHERE xxxxx_id = ? ; UPDATE xxxxx_xxxxx SET status = ?, error = ?, xxxxx_time = ? WHERE xxxxx_id = ?
### Cause: java.sql.SQLTransientConnectionException: (conn=1852878) unexpected end of stream, read 0 bytes from 4
; (conn=1852878) unexpected end of stream, read 0 bytes from 4; nested exception is java.sql.SQLTransientConnectionException: (conn=1852878) unexpected end of stream, read 0 bytes from 4
at org.springframework.jdbc.support.SQLExceptionSubclassTranslator.doTranslate(SQLExceptionSubclassTranslator.java:70) ~[spring-jdbc-5.2.15.RELEASE.jar!/:5.2.15.RELEASE]
at org.springframework.jdbc.support.AbstractFallbackSQLExceptionTranslator.translate(AbstractFallbackSQLExceptionTranslator.java:72) ~[spring-jdbc-5.2.15.RELEASE.jar!/:5.2.15.RELEASE]
at org.springframework.jdbc.support.AbstractFallbackSQLExceptionTranslator.translate(AbstractFallbackSQLExceptionTranslator.java:81) ~[spring-jdbc-5.2.15.RELEASE.jar!/:5.2.15.RELEASE]
at org.mybatis.spring.MyBatisExceptionTranslator.translateExceptionIfPossible(MyBatisExceptionTranslator.java:74) ~[mybatis-spring-2.0.2.jar!/:2.0.2]
at org.mybatis.spring.SqlSessionTemplate$SqlSessionInterceptor.invoke(SqlSessionTemplate.java:440) ~[mybatis-spring-2.0.2.jar!/:2.0.2]
at com.sun.proxy.$Proxy158.insert(Unknown Source) ~[na:na]
OBProxy 的日志中可以看到,OBProxy 在一次请求中收到了 OBServer 的(1 个 error 包 + 1 个 ok 包 + 1 个 error 包 + 1 ok 包),预期是(1 个 error 包 + 1 ok 包),这种异常回包按照设计是需要断开连接的。
对应 OBProxy 日志中,可以看到 OBProxy 端收到 server 端的 2 个 ok pkt, 2 个 error pkt。

根据 OBProxy 日志中,session id 获取 OBServer 端的 trace_id,定位到 OBServer 端,返回的状态是 disconnect_state = 4(客户端断连接),但是相同的消息返回 2 条。

关键诊断信息
触发条件
开启 ob_enable_batched_multi_statement 场景下,当 SQL 执行过程中出现 -5727 报错,并且出现 2 次。
事前巡检
检查是否启用了 ob_enable_batched_multi_statement 配置项。
事后诊断
查看 OBProxy 日志,确认是否有 SQL 执行后收到 2 次错误包。
检查抓包文件,确认 OBServer 是否返回了 2 个 error 包。
问题原因
OceanBase 处理 batch 执行回包处理逻辑存在问题,即在 try_batched_multi_stmt_optimization 功能中,当遇到错误时,会错误地返回 2 个 error 包给 OBProxy,而 OBProxy 无法处理这种情况,从而导致连接被断开。
问题的风险及影响
稳定性风险:可能会发生偶现的断链接。
SQL执行失败:batch update 语句执行会报错并断开连接。
影响租户
影响 OceanBase 数据库中的 SYS 租户和 Oracle 租户以及 MySQL 租户。
影响版本
OceanBase 数据库企业版 V4.2.1 GA(oceanbase-4.2.1.0-100000182023092722)及之后版本、V4.2.5 GA(oceanbase-4.2.5.0-100000082024102022)及之后版本、V4.3.5 GA(oceanbase-4.3.5.0-100000122024123020)及之后版本。
解决方法
关闭
ob_enable_batched_multi_statement配置项以规避此问题。ob_enable_batched_multi_statement用于设置是否启用批处理多条语句的功能。开启这个参数同时也意味着:在 batch 执行场景下,当 Client/Server 使用文本协议进行通许时,OceanBase 会对格式一致的多条 update 语句当成一条语句进行解析,并根据对应的参数和数据分布,生成 batch physical plan。关闭后,执行 batch update 性能差。升级至问题已修复版本。目前已修复的版本包括 OceanBase 数据库企业版 V4.2.1 BP11 Hotfix2(oceanbase-4.2.1.11-111020032025051316)版本、V4.2.1 BP11 Hotfix3(oceanbase-4.2.1.11-111030012025051713)版本、V4.2.1 BP11 Hotfix4(oceanbase-4.2.1.11-111040032025061010)版本、V4.2.1 BP11 Hotfix5(oceanbase-4.2.1.11-111050022025071110)版本、V4.2.1 BP11 Hotfix6(oceanbase-4.2.1.11-111060012025071816)版本、V4.2.1 BP11 Hotfix7(oceanbase-4.2.1.11-111070032025081120)版本、V4.2.1 BP11 Hotfix8(oceanbase-4.2.1.11-111080012025082014)版本、V4.2.1 BP11 Hotfix9(oceanbase-4.2.1.11-111090012025091215)版本、V4.2.1 BP11 Hotfix10(oceanbase-4.2.1.11-111100012025092309)版本、V4.2.1 BP11 Hotfix11(oceanbase-4.2.1.11-111110012025101314)版本、V4.2.1 BP11 Hotfix12(oceanbase-4.2.1.11-111120022025110311)版本、V4.2.5 BP4(oceanbase-4.2.5.4-104000082025052817)及之后版本、V4.3.5 BP3(oceanbase-4.3.5.3-103000102025071821)及之后版本。
规避方式
在执行批处理任务前,确保 ob_enable_batched_multi_statement 配置项处于关闭状态。