【使用环境】测试环境
【OB or 其他组件】OBProxy + ob-loader-dumper
【使用版本】
- OBServer:4.2.5.7(Oracle 租户,单机)
- OBProxy:4.3.1.17(复现);obproxy-ce 4.3.6.1(官方合规版本,同样复现)
- ob-loader-dumper:4.3.7(复现)、4.2.8.2(复现);内置 oceanbase-client 2.4.7.1 / 2.4.18 / 换 2.4.19 均复现
- JDK:OpenJDK 1.8.0_412 / 1.8.0_211 两个环境均复现
【问题描述】
obloader 以"多连接 + 批量提交"模式导入 Oracle 租户数据,连接入口走 obproxy(2883)时响应流错乱,三种失败形态随机出现;同一份数据、同一组参数改为直连 observer(2881)后 100% 稳定成功(累计 21/21)。失败概率随数据量(批量往返次数)上升:约 ≤500 行稳定成功,1000 行约五成失败,3000 行几乎必现。
三种失败形态:
-
java.sql.SQLNonTransientConnectionException: request Id mismatch, currRequestId=null, but received requestId=<数百万元级>—— 收到的 requestId 属于其他会话的响应包(服务端长连接会话序号为百万级,本连接自身序号仅数百); - 客户端线程无限阻塞在
socketRead0(obloader 的 session.config.json socketTimeout=30 分钟,超时后才退出)——挂起期间服务端GV$OB_PROCESSLIST中该用户全部会话均为 SLEEP 空闲、INFO=NULL,无任何在执行请求,即响应在链路上丢失/错位; -
unexpected end of stream, socket was closed by server(大 batch 时)。
【复现路径】
- 准备一张 Oracle 租户表(有无 LOB 列均可,已分别验证),数据文件 3000 行 INSERT(SQL 格式)或 CSV;
- 走 obproxy 导入(重复运行观察随机失败):
obloader -h <obproxy_ip> -P 2883 -u test -p *** -t oboracle -c <cluster> \
--sys-user=test --sys-password=*** -D TEST2 \
--ddl --sql --all --batch 100 --max-errors 0 --file-encoding=UTF-8 \
--external-data --thread 4 --file-path=<数据目录>
- 对照组:仅改连接入口为直连 observer,用户名不带 #集群、不传 -c:
obloader -h <observer_ip> -P 2881 -u test -p *** -t oboracle \
--sys-user=test --sys-password=*** -D TEST2 \
(其余参数同上)
【问题现象及影响】
- 走 obproxy:0% 成功(统计 0/8、8/8 失败、11/11 失败三组;失败时落表行数随机 0~400 行)
- 直连 observer:100% 成功(21/21,每次 7~9 秒完成)
- 已排除并逐项验证无效的变量:
- obloader 版本(4.2.8.2 / 4.3.7)、oceanbase-client 驱动(2.4.7.1 / 2.4.18 / 2.4.19)
-
--exclude-data-types勾/不勾、CSV/SQL 格式、--thread 1/4、--batch100/1000/3000、--external-data有无 - 目标表含/不含 LOB 列、数据含/不含 LOB 值(均失败)
- obproxy 重启;
enable_compression_protocolTrue/False;client_session_id_version1/2 - obloader 连接参数
useCompression、useServerPrepStmts、cachePrepStmts逐项关闭 - obproxy 版本升级至官方合规版本(注:官方文档要求 OBServer 4.2.5 BP2+ 搭配 ODP 4.3.3+,我们已从 4.3.1.17 升级至 obproxy-ce 4.3.6.1 验证,仍失败)
【关键取证摘要】
- 挂起时客户端 jstack:writer 线程阻塞于
com.oceanbase.jdbc.internal.protocol.AbstractQueryProtocol.readPacket → socketRead0; - 挂起时服务端(sys 租户)
GV$OB_PROCESSLIST:该用户全部 7 条会话COMMAND=Sleep, STATE=SLEEP, INFO=NULL,无在执行请求; -
request Id mismatch收到的 requestId(如 4820952)与 observer TRACE 日志中长生命周期会话的request_id(5,820,270 / 15,965,488 量级)同量级,而本连接自身请求序号仅数百——客户端收到了其他会话的响应包,指向中间转发层的会话/流路由错乱; - 挂起 JVM 的 socket 对账(/proc//fd ↔ /proc/net/tcp):全部 8 条连接对端均为 obproxy:2883。
【期望】
请官方协助定位 obproxy(或 observer 4.2.5.7 代理模式)在 obloader 批量写入负载下响应流错乱的根因,并提供修复版本或规避配置。如需要,我们可以配合提供:抓包文件(tcpdump ob20 协议流)、完整 obloader 日志、observer/obproxy 日志、可复现数据集。