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.Connection;
import java.sql.DriverManager; import java.sql.DriverManager;
import java.sql.SQLException; import java.sql.SQLException;
import java.sql.Statement;
import java.util.Properties; import java.util.Properties;
import net.sf.briar.api.clock.Clock; 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); super(HASH_TYPE, BINARY_TYPE, COUNTER_TYPE, SECRET_TYPE, clock);
this.config = config; this.config = config;
String path = new File(config.getDatabaseDirectory(), "db").getPath(); String path = new File(config.getDatabaseDirectory(), "db").getPath();
url = "jdbc:h2:split:" + path url = "jdbc:h2:split:" + path + ";CIPHER=AES;MULTI_THREADED=1"
+ ";CIPHER=AES;MULTI_THREADED=1;DB_CLOSE_ON_EXIT=false"; + ";WRITE_DELAY=0;DB_CLOSE_ON_EXIT=false";
} }
public boolean open() throws DbException, IOException { public boolean open() throws DbException, IOException {
@@ -73,7 +74,6 @@ class H2Database extends JdbcDatabase {
} else return f.length(); } else return f.length();
} }
@Override
protected Connection createConnection() throws SQLException { protected Connection createConnection() throws SQLException {
byte[] key = config.getEncryptionKey(); byte[] key = config.getEncryptionKey();
if(key == null) throw new IllegalStateException(); 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; for(int i = 0; i < hex.length; i++) hex[i] = 0;
return combined; 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 private boolean closed = false; // Locking: connections
protected abstract Connection createConnection() throws SQLException; protected abstract Connection createConnection() throws SQLException;
protected abstract void flushBuffersToDisk(Statement s) throws SQLException;
JdbcDatabase(String hashType, String binaryType, String counterType, JdbcDatabase(String hashType, String binaryType, String counterType,
String secretType, Clock clock) { String secretType, Clock clock) {
@@ -509,9 +510,14 @@ abstract class JdbcDatabase implements Database<Connection> {
} }
public void commitTransaction(Connection txn) throws DbException { public void commitTransaction(Connection txn) throws DbException {
Statement s = null;
try { try {
txn.commit(); txn.commit();
s = txn.createStatement();
flushBuffersToDisk(s);
s.close();
} catch(SQLException e) { } catch(SQLException e) {
tryToClose(s);
throw new DbException(e); throw new DbException(e);
} }
synchronized(connections) { synchronized(connections) {