Set H2's write delay to 0 and flush data to disk after every commit.

This should improve durability in the case of a crash (see
http://www.h2database.com/html/advanced.html#durability_problems). The
performance penalty for H2DatabaseTest is roughly 10%.
This commit is contained in:
akwizgran
2013-05-31 15:31:15 +01:00
parent cb2d8b50d2
commit 90c323e82b
2 changed files with 13 additions and 3 deletions

View File

@@ -5,6 +5,7 @@ import java.io.IOException;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.Properties;
import net.sf.briar.api.clock.Clock;
@@ -31,8 +32,8 @@ class H2Database extends JdbcDatabase {
super(HASH_TYPE, BINARY_TYPE, COUNTER_TYPE, SECRET_TYPE, clock);
this.config = config;
String path = new File(config.getDatabaseDirectory(), "db").getPath();
url = "jdbc:h2:split:" + path
+ ";CIPHER=AES;MULTI_THREADED=1;DB_CLOSE_ON_EXIT=false";
url = "jdbc:h2:split:" + path + ";CIPHER=AES;MULTI_THREADED=1"
+ ";WRITE_DELAY=0;DB_CLOSE_ON_EXIT=false";
}
public boolean open() throws DbException, IOException {
@@ -73,7 +74,6 @@ class H2Database extends JdbcDatabase {
} else return f.length();
}
@Override
protected Connection createConnection() throws SQLException {
byte[] key = config.getEncryptionKey();
if(key == null) throw new IllegalStateException();
@@ -101,4 +101,8 @@ class H2Database extends JdbcDatabase {
for(int i = 0; i < hex.length; i++) hex[i] = 0;
return combined;
}
protected void flushBuffersToDisk(Statement s) throws SQLException {
s.execute("CHECKPOINT SYNC");
}
}

View File

@@ -371,6 +371,7 @@ abstract class JdbcDatabase implements Database<Connection> {
private boolean closed = false; // Locking: connections
protected abstract Connection createConnection() throws SQLException;
protected abstract void flushBuffersToDisk(Statement s) throws SQLException;
JdbcDatabase(String hashType, String binaryType, String counterType,
String secretType, Clock clock) {
@@ -509,9 +510,14 @@ abstract class JdbcDatabase implements Database<Connection> {
}
public void commitTransaction(Connection txn) throws DbException {
Statement s = null;
try {
txn.commit();
s = txn.createStatement();
flushBuffersToDisk(s);
s.close();
} catch(SQLException e) {
tryToClose(s);
throw new DbException(e);
}
synchronized(connections) {