【问题标题】:Postgres JDBC driver adaptive fetching running out of memoryPostgres JDBC 驱动程序自适应提取内存不足
【发布时间】:2023-01-22 07:51:06
【问题描述】:

我正在尝试使用 Postgres JDBC 驱动程序从表中查询数据,其中每行最多可达 50MB。不幸的是,在没有任何内存限制的情况下,Postgres 驱动程序可能会使用过多的内存和大小写 OOM(即使使用非常健康的 Xmx),因为它在本地缓冲了如此多的数据。

我试图限制驱动程序使用更少的内存,例如 1GB,并告诉它也减少缓冲。由于没有一行大于 50MB,这应该可以正常工作,但不幸的是,我现在收到 Postgres 驱动程序本身抛出的异常。例外是因为它试图分配比我配置的更多的内存。

如果我使用这个配置:

"jdbc:postgresql://localhost/dbname?maxResultBuffer=1G&adaptiveFetch=true&adaptiveFetchMaximum=2&defaultRowFetchSize=1"

我会在PGStream 中抛出异常

      if (resultBufferByteCount > maxResultBuffer) {
        throw new PSQLException(GT.tr(
          "Result set exceeded maxResultBuffer limit. Received:  {0}; Current limit: {1}",
          String.valueOf(resultBufferByteCount), String.valueOf(maxResultBuffer)),PSQLState.COMMUNICATION_ERROR);
      }

如果我在那里设置断点,我可以看到:

value = 41155480
resultBufferByteCount = 1021091718
maxResultBuffer = 1000000000

这表明它正在很好地获取配置。我还检查了它以确保它获得了获取大小配置并且确实如此。

我还缺少其他配置吗?很明显,Postgres 驱动程序正在读取比我允许的更多的行。

谢谢

(postgresql 42.5.1、java 17.0.5、hikaricp 5.0.1,最大连接数为 1)

【问题讨论】:

  • 使用Getting results based on a cursor怎么样,这是引入“自适应缓冲”之前的解决方案
  • @a_horse_with_no_name 如果我使用adaptiveFetch=false&defaultRowFetchSize=1,它仍然失败。我无权访问 Statements 以直接调用 setFetchSize。我需要在连接字符串上配置选项。

标签: postgresql jdbc


【解决方案1】:

自适应缓冲区,如 setFetchSize,仅在自动提交关闭时才有效。如果自动提交打开,那么它们将被默默地忽略。我不知道是否有办法通过 jdbc 连接字符串关闭自动提交,我还没有找到。

【讨论】:

    猜你喜欢
    • 2013-04-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-08-17
    • 2016-08-09
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多