我试图使用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驱动程序读取的行数超出了我允许的范围。
感谢(postgreqsl 42.5.1, Java 17.0.5, hikaricp 5.0.1 with Max connections of 1)
自适应缓冲区,如setFetchSize,只有在自动提交关闭时才有效。如果自动提交是开启的,那么它们将被静默地忽略。我不知道是否有一种方法可以通过jdbc连接字符串关闭自动提交,我还没有找到一个。