【发布时间】:2017-09-02 05:37:33
【问题描述】:
我正在用 Java 写一个 SQLite DB。几天一切顺利,然后突然一切都崩溃了,我得到了以下堆栈跟踪:
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 亿行。根据SQLite's Limit page,“一个表中的理论最大行数是2^64”,我还差得很远,最大数据库大小是,“一个数据库文件的最大大小是2147483646页。在最大页面大小为 65536 字节,这相当于最大数据库大小约为 1.4e+14 字节(140 TB...)”,而我也远不及。
阅读以上内容,我的解释是,如果我将 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();
}
}
【问题讨论】:
-
您正在运行的查询是什么产生了这个异常?您可能会遇到 SQLite 在查询执行期间必须生成临时表的问题,这涉及在磁盘上生成临时文件。如果您的查询足够大,它很可能会生成一个足够大的文件,从而导致空间不足的问题。
-
我检查了一下,我运行它的最后一台服务器有一个 2TB 系统驱动器,几乎所有驱动器都是免费的,但仍然是同样的问题,立即。我已经更新了问题并添加了查询。
标签: database performance sqlite resize