已合并
Fix unbounded stream parameter buffering #433
Fix unbounded stream parameter buffering #433
已合并
liyangx创建于 7月28日
liyangx成员
7月28日

【标题】(请简要描述下实现的内容)
Fix unbounded stream parameter buffering
【实现内容】:
修复 PgPreparedStatement 无长度流参数绑定时可能将输入流完整缓存到堆内存,导致大对象/恶意流触发堆内存耗尽的问题。

【根因分析】:
报告指出,部分无长度流参数绑定路径会在执行前将 InputStream/Reader 数据读入内存缓存。对于未声明长度或超大长度的流,调用方可传入任意大小数据,驱动侧缺少明确上限或流式绑定路径,存在堆内存耗尽风险。

【实现方案】:

  1. 对 setBinaryStream(int, InputStream) 不再通过 ByteArrayOutputStream 全量拷贝输入流。

    • blobMode=OFF 时,直接通过 ParameterList 绑定 InputStream,走 bytea 流式参数路径。
    • blobMode=ON 时,直接通过 ParameterList 绑定 InputStream,走 BLOB 参数流绑定路径,不再创建 LargeObject OID,避免类型不匹配和 auto-commit 下 LargeObject 使用问题。
  2. 对字符流/CLOB 绑定路径做差异化处理。

    • 扩展查询模式下,使用 ReaderInputStream/FixedLengthReader 传递给参数列表,避免无意义堆内缓存。
    • 简单查询模式由于协议拼接 SQL 文本需要物化字符串,因此保留必要缓存,但增加最大缓存字符数限制。
  3. 增加可配置上限。

    • 新增连接参数 maxBufferedStreamParameterChars。
    • 默认值为 16MB,避免过大字符缓存带来的过大堆内存压力。
    • 参数值必须大于等于 0,非法配置在连接初始化阶段报错。
    • 同步为 BaseDataSource 增加 getter/setter,保证 DataSource 方式也可以配置该参数。
  4. 补充回归测试。

    • 覆盖无长度 binary stream 绑定。
    • 覆盖 blobMode=OFF 下 16MB 无长度 binary stream 绑定。
    • 覆盖 character stream / CLOB 的正常写入路径。
    • 覆盖 simple query mode 下超过配置上限时拒绝缓存的异常路径。

【关联需求或issue】:
https://gitcode.com/opengauss/openGauss-connector-jdbc/issues/680

【开发自验报告】:
已补充以下 JDBC 回归测试用例,覆盖本次修复场景:

  • 验证无长度二进制流参数可以正常写入 BLOB,并且读取内容一致。
  • 验证关闭 blobMode 时,16MB 无长度二进制流可以正常写入并读取一致。
  • 验证 2MB 无长度字符流可以正常写入并读取一致。
  • 验证无长度 CLOB 绑定 null 时行为保持正常。
  • 验证 2KB、200KB、2MB 无长度 CLOB 可以正常写入并读取一致。
  • 验证 2MB 有长度 CLOB 可以正常写入并读取一致。
  • 验证 simple query mode 下,无长度字符流超过 maxBufferedStreamParameterChars 配置上限时会被拒绝。
  • 验证 simple query mode 下,无长度 CLOB 超过 maxBufferedStreamParameterChars 配置上限时会被拒绝。
  • 验证 simple query mode 下,有长度 CLOB 超过 maxBufferedStreamParameterChars 配置上限时会被拒绝。
  1. 请附上自验结果(内容或者截图)
    见【开发自验报告】
  2. 是否可以添加fastcheck测试用例,如是,请补充fastcheck用例
    已补充测试用例
  3. 是否涉及资料修改,如是,在docs仓库补充资料
    不涉及
  4. 是否考虑升级场景(系统表修改、日志持久化以及修改执行态数据格式)
    不涉及
  5. 是否考虑在线扩容等扩展场景
    不涉及
  6. 是否考虑异常场景/并发场景/前向兼容/性能场景
    已考虑。
  • 异常场景:配置值小于 0 时连接初始化报错;simple query mode 超过配置上限时拒绝缓存。
  • 并发场景:新增配置为连接级配置,不引入共享可变状态。
  • 前向兼容:默认上限设置为 16MB,并支持用户通过 maxBufferedStreamParameterChars 按业务需要调大。
  • 性能场景:避免 unknown-length stream 被完整拷贝到堆内存,降低大流参数绑定的内存压力;测试仅保留一个 16MB 代表性大流用例,避免门禁耗时过长。
  1. 是否对其他模块产生影响
    不涉及
  2. 是否需要回合补丁版本(5.0、6.0),涉及(结果错误|coredump|性能劣化|内存泄露|集群异常)相关修复请排查回合补丁分支
    需考虑
  3. 针对Plugin仓dolphin插件,新增/修改的代码是否已使用 DOLPHIN 宏进行控制,方便后续回合openGauss-server仓代码
    不涉及

【当前PR是否有AI参与】:
[x] 否
[] 是
__1. AI Agent 平台:
__2. AI 模型:
__3. Prompt上下文 :

【其他说明】:
考虑历史兼容性和默认安全边界,本次未简单禁止无长度流参数绑定,而是优先将可流式处理的 binary stream、extended query mode character/CLOB 路径改为流式绑定;仅对 simple query mode 下协议层必须缓存为字符串的场景增加可配置上限。
默认值设置为 16MB。原因是该限制单位为字符数,Java 字符为 16-bit,simple query mode 下还会产生 StringBuilder、String、SQL 拼接等额外对象;若默认设置为 64MB,实际堆内存压力可能明显放大,不适合作为默认值。对于确实需要更大 simple-mode 字符流/CLOB 的业务,可以通过 maxBufferedStreamParameterChars 显式调大。

该上限为连接级可配置参数,默认 16MB。用户如需兼容更大的 simple query mode 字符流/CLOB 绑定场景,可在创建连接时通过 JDBC URL、Properties 或 DataSource 的 setMaxBufferedStreamParameterChars 方法显式调大,例如设置为 67108864 表示 64MB。
①JDBC URL:

jdbc:opengauss://host:port/db?maxBufferedStreamParameterChars=67108864

②Properties:

Properties props = new Properties();
props.setProperty("maxBufferedStreamParameterChars", "67108864");
Connection conn = DriverManager.getConnection(url, props);

③DataSource:

PGSimpleDataSource ds = new PGSimpleDataSource();
ds.setMaxBufferedStreamParameterChars(67108864);
Connection conn = ds.getConnection();
likedislike
Pull Request已成功合入, 合并人@opengauss_bot
(感谢 liyangx 的贡献)
Lliyangx成员
7月28日 创建了 pull request,commit 94292583
opengauss_botopengauss_bot成员
7月28日 添加了label:sig/Connectors
opengauss_bot
opengauss_bot成员
7月28日 评论:

Welcome To openGauss Community

Hey @liyangx , thanks for your contribution to the community.

Bot Usage Manual

I'm the Bot here serving you. You can find the instructions on how to interact with me at Here . That means you can comment below every pull request or issue to trigger Bot Commands.

Contact Guide

If you have any questions, please contact the SIG: Connectors ,
and any of the maintainers: @CarrotGo, @chendong76, @chenxiaobin19, @congzhou2603, @dodders, @hwworkholic, @jemappellehc, @muyulinzhong, @quemingjian, @shenzheng4, @shirley_zhengx, @superlchf, @totaj, @wlff234, @wofanzheng, @ywzq1161327784 ,
and any of the committers: @hw_hbj, @libiao2024, @zhangxubo .

likedislike
opengauss_botopengauss_bot成员
7月28日 添加了label:ci-pipeline-running
opengauss_botopengauss_bot成员
7月28日 添加了label:codecheck-running
此处折叠了352条消息 查看更多
opengauss_botopengauss_bot成员
8月4日 添加了label:codecheck-running
opengauss_bot
opengauss_bot成员
8月4日 评论:

开源片段扫描

Check Name Build Details Check Result Check Detail
sca #39863 ✅ 通过 >>>
likedislike
opengauss_bot
opengauss_bot成员
8月4日 评论:

静态检查

Check Name Build Details Check Result Check Detail
CodeCheck #79074 ✅ 通过 >>>
likedislike
opengauss_botopengauss_bot成员
8月4日 添加了label:codecheck-success
opengauss_botopengauss_bot成员
8月4日 删除了label:codecheck-running