如何将SQLite数据库的大小限制增加到140TB?

时间:2017-09-02 05:37:33

标签: database performance sqlite resize

我正在用Java编写SQLite数据库。一切都进行了好几天,然后突然一切都崩溃了,我得到了以下的堆栈跟踪:

org.sqlite.SQLiteException: [SQLITE_FULL]  Insertion failed because database is full (database or disk is full)
        at org.sqlite.core.DB.newSQLException(DB.java:909)
        at org.sqlite.core.DB.newSQLException(DB.java:921)
        at org.sqlite.core.DB.throwex(DB.java:886)
        at org.sqlite.core.DB.executeBatch(DB.java:774)
        at org.sqlite.core.CorePreparedStatement.executeBatch(CorePreparedStatement.java:79)
        at co.happy.GroupByWriteFile.run(GroupByWriteFile.java:51)
        at java.lang.Thread.run(Thread.java:748)

磁盘未满。这是df -h的输出:

root@host:/output# df -h
Filesystem      Size  Used Avail Use% Mounted on
udev             32G     0   32G   0% /dev
tmpfs           6.3G  8.7M  6.3G   1% /run
/dev/xvda1      7.7G  1.9G  5.9G  24% /
tmpfs            32G     0   32G   0% /dev/shm
tmpfs           5.0M     0  5.0M   0% /run/lock
tmpfs            32G     0   32G   0% /sys/fs/cgroup
tmpfs           6.3G     0  6.3G   0% /run/user/1000
/dev/xvdb1      2.0T  572G  1.3T  31% /input
/dev/xvdc1      2.9T  1.1T  1.8T  37% /output

这里是/ output的内容(包含db):

root@host:/output# ls -lrth
total 1.1T
drwx------ 2 root root  16K Aug 31 23:39 lost+found
-rw-r--r-- 1 root root 1.0T Sep  2 05:12 groupby.db

我尝试在多台服务器上运行代码,并且我一直在做同样的事情。数据库中的一个表中可能大约有10亿行,而另一个表中大约有2亿行。根据{{​​3}},"表中理论上的最大行数是2 ^ 64,"我不在,最大数据库大小是,#34;数据库文件的最大大小是2147483646页。在最大页面大小为65536字节时,这意味着最大数据库大小约为1.4e + 14字节(140太字节......)",我也不在附近。

阅读上述内容,我的解释是,如果我将page_size增加到65536,那么我将能够达到140TB的最大值。但是,我也读到这会对性能造成严重影响。这是实现140TB的正确方法吗?如果没有,将尺寸限制增加到140TB的步骤是什么?如果这一切如何影响性能呢?

修改

添加查询:

    PreparedStatement ps = null;
    PreparedStatement ps2 = null;
    int i = 0;
    try {
        ps = conn.prepareStatement("REPLACE INTO groupByKeys VALUES (?, ?)");
        ps2 = conn.prepareStatement("INSERT INTO groupByVals VALUES (?, ?)");

    } catch (SQLException e) {
        e.printStackTrace();
    }
    while (true) {
        try {
            DedupeInstruction d = writeQueue.take();
            ps.setString(1, d.getOutFile());
            if (d.isHasCustom()) {
                ps.setInt(2, 1);
            } else {
                ps.setInt(2, 0);
            }
            ps2.setString(1, d.getOutFile());
            ps2.setString(2, d.getLine());
            ps.addBatch();
            ps2.addBatch();
            if (i % 1000 == 0) {
                ps.executeBatch();
                ps2.executeBatch();
            }
        } catch (InterruptedException e) {
            e.printStackTrace();
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }

1 个答案:

答案 0 :(得分:1)

增加最大数据库大小的方法是增加页面大小。

对于大型数据库,使页面大小尽可能大是一种改进,因为您减少了每页开销。

即使对于普通数据库,页面大小也应至少与文件系统使用的块大小一样大,现在为4 KB。 (最近的SQLite版本会自动执行此操作,但您的数据库的页面大小为512字节。)

您应该在创建数据库之前通过执行PRAGMA page_size来设置页面大小。对于现有数据库,您之后必须运行VACUUM,这不是您想要对大量数据执行的操作。

请注意,REPLACE会删除旧行(如果存在);如果大多数这些实际上没有改变行,你可以通过两个语句来避免很多I / O.