【缺陷反馈】obloader 批量导入经 obproxy 时响应流错乱:request Id mismatch / 无限等待 / 断连;直连 observer 100% 稳定

【使用环境】测试环境
【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 行几乎必现。

三种失败形态:

  1. java.sql.SQLNonTransientConnectionException: request Id mismatch, currRequestId=null, but received requestId=<数百万元级> —— 收到的 requestId 属于其他会话的响应包(服务端长连接会话序号为百万级,本连接自身序号仅数百);
  2. 客户端线程无限阻塞在 socketRead0(obloader 的 session.config.json socketTimeout=30 分钟,超时后才退出)——挂起期间服务端 GV$OB_PROCESSLIST 中该用户全部会话均为 SLEEP 空闲、INFO=NULL,无任何在执行请求,即响应在链路上丢失/错位;
  3. unexpected end of stream, socket was closed by server(大 batch 时)。

【复现路径】

  1. 准备一张 Oracle 租户表(有无 LOB 列均可,已分别验证),数据文件 3000 行 INSERT(SQL 格式)或 CSV;
  2. 走 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=<数据目录>
  1. 对照组:仅改连接入口为直连 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、--batch 100/1000/3000、--external-data 有无
    • 目标表含/不含 LOB 列、数据含/不含 LOB 值(均失败)
    • obproxy 重启;enable_compression_protocol True/False;client_session_id_version 1/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 验证,仍失败)

【关键取证摘要】

  1. 挂起时客户端 jstack:writer 线程阻塞于 com.oceanbase.jdbc.internal.protocol.AbstractQueryProtocol.readPacket → socketRead0;
  2. 挂起时服务端(sys 租户)GV$OB_PROCESSLIST:该用户全部 7 条会话 COMMAND=Sleep, STATE=SLEEP, INFO=NULL,无在执行请求;
  3. request Id mismatch 收到的 requestId(如 4820952)与 observer TRACE 日志中长生命周期会话的 request_id(5,820,270 / 15,965,488 量级)同量级,而本连接自身请求序号仅数百——客户端收到了其他会话的响应包,指向中间转发层的会话/流路由错乱;
  4. 挂起 JVM 的 socket 对账(/proc//fd ↔ /proc/net/tcp):全部 8 条连接对端均为 obproxy:2883。

【期望】
请官方协助定位 obproxy(或 observer 4.2.5.7 代理模式)在 obloader 批量写入负载下响应流错乱的根因,并提供修复版本或规避配置。如需要,我们可以配合提供:抓包文件(tcpdump ob20 协议流)、完整 obloader 日志、observer/obproxy 日志、可复现数据集。

你好,你提的这个技术问题牵涉到OceanBase企业版范围内的功能细节;针对此类问题,建议你通过以下方式寻求帮助:

  1. 如你所在的企业客户已签署OceanBase企业版销售合同,请你联系客户经理;

  2. 如你所在的企业客户尚未签署OceanBase企业版销售合同,你可通过OceanBase官网商务咨询页面留下你的联系方式,OceanBase企业版的业务顾问会在一个工作日内与你联系。

另外,我们欢迎你使用社区版,并在论坛/社群中分享你对社区版本的想法、经验和问题,与其他社区成员共同交流。