为什么我的Postgres游标内存不足?

时间:2015-07-24 17:28:14

标签: java postgresql out-of-memory database-cursor

我有一个巨大的表,我正在尝试流式传输到文件。然而,似乎无论我尝试什么,Postgres都试图立即拉出所有数据并耗尽内存。我在这里和其他地方读过很多帖子,我觉得我这样做是对的,所以为什么我的内存不足?

这是我的代码:

        Connection conn = DriverManager.getConnection(dbUrl, dbUser, dbPassword);

        conn.setAutoCommit(false);
        conn.setReadOnly(true);

        Statement ps = conn.createStatement(
                ResultSet.TYPE_FORWARD_ONLY, 
                ResultSet.CONCUR_READ_ONLY, 
                ResultSet.HOLD_CURSORS_OVER_COMMIT);

        ps.setFetchSize(10);

        String sql = "SELECT * FROM BIGTABLE "
             + "WHERE '20150401' BETWEEN startdate AND enddate";

        ResultSet rs = ps.executeQuery(sql);

        writeResultSet(os, rs);

在内存不足之前,代码永远不会超过查询执行。

如果重要,则在流式传输到打开的ZipOutputStream时会发生在单独的线程中。此时,一个项目已经流出,我从未达到可以流出此表的程度。

我正在使用Postgres 9.3.5,目前将VM限制为128MB进行测试。虽然我可以增加堆大小,但我仍然认为我不应该遇到这个问题。

[jsyk,为了清楚起见,我已经删除了try / catch块等。]

1 个答案:

答案 0 :(得分:1)

ResultSet.HOLD_CURSORS_OVER_COMMIT

此设置要求保留游标,该游标在Postgresql的客户端实现。 Postgresql本身不支持JDBC使用的协议(前端/后端协议)上的本机可保持游标。相关文章:

Apple's documentation

另请注意,即使本机可保持游标也有O(n)空间要求,但它将在磁盘上分配。

但是,通过查看代码,我发现没有理由需要一个可保持的游标。