JDBC fastload - 经过20万次addBatch()操作后的OutOfMemory

时间:2011-10-07 08:54:34

标签: jdbc teradata out-of-memory

我正在使用Teradata jdbc驱动程序13.00.00.10,并尝试将包含1亿行的平面文件上传到teradata。

我从干净的桌子开始。

首先我尝试遍历整个文件,为每一行做addBatch(),最后只做一个executeBatch():

        while ((s = reader.readLine())!=null ){
            String[] columns = StringUtils.split(s, separator);
            for (int j=0; j <columns.length; j++){
                st.setString(j+1,columns[j]);
            }
            st.addBatch();
            i++;
            if (i % 10000 ==0 ){
                ULogger.info(this, "imported " + i + " lines.");
            }

        }
        st.executeBatch();

这会快速消耗我的应用程序的所有内存。

我设置了9GB的XMX,并在大约4000万的addBatch()之后得到了OutOfMemory。

然后我尝试定期执行executeBatch() - 迭代throgh文件,每2000万个addBatch()执行一次executeBatch()。

       while ((s = reader.readLine())!=null ){
            String[] columns = StringUtils.split(s, separator);
            for (int j=0; j <columns.length; j++){
                st.setString(j+1,columns[j]);
            }
            st.addBatch();
            i++;
            if (i % 20000000 ==0 ){
                   st.executeBatch();

                   st.clearWarnings();
            }

        }
        st.executeBatch();

在这种情况下,第一个executeBatch()成功。

但是,第二个executeBatch()失败,“启动数据库表XXX的FastLoad时出现错误”。

任何人都可以解释我应该如何加载1亿行?

是否有我缺少的配置(例如告诉驱动程序定期推送一些更新而不是将它们保存在内存中)?

谢谢,

一个。

1 个答案:

答案 0 :(得分:2)

在Teradata用户论坛上找到答案,该论坛引导我访问常见问题解答 - (http://developer.teradata.com/connectivity/faq),其中说正确的工作方式是定期调用executeBatch() ; 但是,为了做到这一点,你需要先关闭连接上的自动提交, 并确保最终提交。

所以我的代码现在看起来像这样:

        **con.setAutoCommit(false);**
        while ((s = reader.readLine())!=null ){
            String[] columns = StringUtils.split(s, separator);
            for (int j=0; j <columns.length; j++){
                st.setString(j+1,columns[j]);
            }
            st.addBatch();
            i++;
            if (i % 20000000 ==0 ){
                   st.executeBatch();

                   st.clearWarnings();
            }

        }
        st.executeBatch();
        **con.commit();**

就像一个魅力。

唯一不能从常见问题解答中100%清楚的是块大小应该是什么。 它说“像你的JVM堆可以维持的那么大”这样的东西令人困惑,而且“将来我们会建议把它设置为50K-100K。这两个似乎相互矛盾,我把它设置为1000万,它是找工作。

此外 - Teradata JDBC中显然有一个CSV快速加载器功能 - 请参阅http://developer.teradata.com/doc/connectivity/jdbc/ reference / current / jdbcug_chapter_2.html#BABFGFA2 - 这可能会提供更好的性能。