我正在用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();
}
}
答案 0 :(得分:1)
增加最大数据库大小的方法是增加页面大小。
对于大型数据库,使页面大小尽可能大是一种改进,因为您减少了每页开销。
即使对于普通数据库,页面大小也应至少与文件系统使用的块大小一样大,现在为4 KB。 (最近的SQLite版本会自动执行此操作,但您的数据库的页面大小为512字节。)
您应该在创建数据库之前通过执行PRAGMA page_size来设置页面大小。对于现有数据库,您之后必须运行VACUUM,这不是您想要对大量数据执行的操作。
请注意,REPLACE会删除旧行(如果存在);如果大多数这些实际上没有改变行,你可以通过两个语句来避免很多I / O.