Merge branch 'compact-db-at-shutdown' into 'master'

Always compact the DB at shutdown

See merge request briar/briar!1609
This commit is contained in:
Torsten Grote
2022-03-30 16:29:29 +00:00
6 changed files with 13 additions and 91 deletions

View File

@@ -2,8 +2,6 @@ package org.briarproject.bramble.db;
import org.briarproject.bramble.api.settings.Settings;
import static java.util.concurrent.TimeUnit.DAYS;
interface DatabaseConstants {
/**
@@ -25,19 +23,6 @@ interface DatabaseConstants {
*/
String SCHEMA_VERSION_KEY = "schemaVersion";
/**
* The {@link Settings} key under which the time of the last database
* compaction is stored.
*/
String LAST_COMPACTED_KEY = "lastCompacted";
/**
* The maximum time between database compactions in milliseconds. When the
* database is opened it will be compacted if more than this amount of time
* has passed since the last compaction.
*/
long MAX_COMPACTION_INTERVAL_MS = DAYS.toMillis(30);
/**
* The {@link Settings} key under which the flag is stored indicating
* whether the database is marked as dirty.

View File

@@ -85,12 +85,17 @@ class H2Database extends JdbcDatabase {
public void close() throws DbException {
// H2 will close the database when the last connection closes
Connection c = null;
Statement s = null;
try {
c = createConnection();
super.closeAllConnections();
closeAllConnections();
setDirty(c, false);
s = c.createStatement();
s.execute("SHUTDOWN COMPACT");
s.close();
c.close();
} catch (SQLException e) {
tryToClose(s, LOG, WARNING);
tryToClose(c, LOG, WARNING);
throw new DbException(e);
}

View File

@@ -79,11 +79,11 @@ class HyperSqlDatabase extends JdbcDatabase {
Connection c = null;
Statement s = null;
try {
super.closeAllConnections();
closeAllConnections();
c = createConnection();
setDirty(c, false);
s = c.createStatement();
s.executeQuery("SHUTDOWN");
s.executeQuery("SHUTDOWN COMPACT");
s.close();
c.close();
} catch (SQLException e) {
@@ -106,7 +106,7 @@ class HyperSqlDatabase extends JdbcDatabase {
Connection c = null;
Statement s = null;
try {
super.closeAllConnections();
closeAllConnections();
c = createConnection();
s = c.createStatement();
s.executeQuery("SHUTDOWN COMPACT");

View File

@@ -85,8 +85,6 @@ import static org.briarproject.bramble.api.sync.validation.MessageState.PENDING;
import static org.briarproject.bramble.api.sync.validation.MessageState.UNKNOWN;
import static org.briarproject.bramble.db.DatabaseConstants.DB_SETTINGS_NAMESPACE;
import static org.briarproject.bramble.db.DatabaseConstants.DIRTY_KEY;
import static org.briarproject.bramble.db.DatabaseConstants.LAST_COMPACTED_KEY;
import static org.briarproject.bramble.db.DatabaseConstants.MAX_COMPACTION_INTERVAL_MS;
import static org.briarproject.bramble.db.DatabaseConstants.SCHEMA_VERSION_KEY;
import static org.briarproject.bramble.db.ExponentialBackoff.calculateExpiry;
import static org.briarproject.bramble.db.JdbcUtils.tryToClose;
@@ -378,8 +376,7 @@ abstract class JdbcDatabase implements Database<Connection> {
throws DbException, SQLException;
// Used exclusively during open to compact the database after schema
// migrations or after DatabaseConstants#MAX_COMPACTION_INTERVAL_MS has
// elapsed
// migrations or if the database was not shut down cleanly
protected abstract void compactAndClose() throws DbException;
JdbcDatabase(DatabaseTypes databaseTypes, MessageFactory messageFactory,
@@ -405,7 +402,8 @@ abstract class JdbcDatabase implements Database<Connection> {
if (reopen) {
Settings s = getSettings(txn, DB_SETTINGS_NAMESPACE);
wasDirtyOnInitialisation = isDirty(s);
compact = migrateSchema(txn, s, listener) || isCompactionDue(s);
boolean migrated = migrateSchema(txn, s, listener);
compact = wasDirtyOnInitialisation || migrated;
} else {
wasDirtyOnInitialisation = false;
createTables(txn);
@@ -435,14 +433,6 @@ abstract class JdbcDatabase implements Database<Connection> {
} finally {
connectionsLock.unlock();
}
txn = startTransaction();
try {
storeLastCompacted(txn);
commitTransaction(txn);
} catch (DbException e) {
abortTransaction(txn);
throw e;
}
}
}
@@ -507,14 +497,6 @@ abstract class JdbcDatabase implements Database<Connection> {
);
}
private boolean isCompactionDue(Settings s) {
long lastCompacted = s.getLong(LAST_COMPACTED_KEY, 0);
long elapsed = clock.currentTimeMillis() - lastCompacted;
if (LOG.isLoggable(INFO))
LOG.info(elapsed + " ms since last compaction");
return elapsed > MAX_COMPACTION_INTERVAL_MS;
}
private void storeSchemaVersion(Connection txn, int version)
throws DbException {
Settings s = new Settings();
@@ -522,12 +504,6 @@ abstract class JdbcDatabase implements Database<Connection> {
mergeSettings(txn, s, DB_SETTINGS_NAMESPACE);
}
private void storeLastCompacted(Connection txn) throws DbException {
Settings s = new Settings();
s.putLong(LAST_COMPACTED_KEY, clock.currentTimeMillis());
mergeSettings(txn, s, DB_SETTINGS_NAMESPACE);
}
private boolean isDirty(Settings s) {
return s.getBoolean(DIRTY_KEY, false);
}
@@ -541,7 +517,6 @@ abstract class JdbcDatabase implements Database<Connection> {
private void initialiseSettings(Connection txn) throws DbException {
Settings s = new Settings();
s.putInt(SCHEMA_VERSION_KEY, CODE_SCHEMA_VERSION);
s.putLong(LAST_COMPACTED_KEY, clock.currentTimeMillis());
mergeSettings(txn, s, DB_SETTINGS_NAMESPACE);
}

View File

@@ -72,9 +72,6 @@ import static org.briarproject.bramble.api.sync.validation.MessageState.DELIVERE
import static org.briarproject.bramble.api.sync.validation.MessageState.INVALID;
import static org.briarproject.bramble.api.sync.validation.MessageState.PENDING;
import static org.briarproject.bramble.api.sync.validation.MessageState.UNKNOWN;
import static org.briarproject.bramble.db.DatabaseConstants.DB_SETTINGS_NAMESPACE;
import static org.briarproject.bramble.db.DatabaseConstants.LAST_COMPACTED_KEY;
import static org.briarproject.bramble.db.DatabaseConstants.MAX_COMPACTION_INTERVAL_MS;
import static org.briarproject.bramble.test.TestUtils.deleteTestDirectory;
import static org.briarproject.bramble.test.TestUtils.getAgreementPrivateKey;
import static org.briarproject.bramble.test.TestUtils.getAgreementPublicKey;
@@ -2240,46 +2237,6 @@ public abstract class JdbcDatabaseTest extends BrambleTestCase {
db.close();
}
@Test
public void testCompactionTime() throws Exception {
MessageFactory messageFactory = new TestMessageFactory();
long now = System.currentTimeMillis();
AtomicLong time = new AtomicLong(now);
Clock clock = new SettableClock(time);
// Time: now
// The last compaction time should be initialised to the current time
Database<Connection> db = open(false, messageFactory, clock);
Connection txn = db.startTransaction();
Settings s = db.getSettings(txn, DB_SETTINGS_NAMESPACE);
assertEquals(now, s.getLong(LAST_COMPACTED_KEY, 0));
db.commitTransaction(txn);
db.close();
// Time: now + MAX_COMPACTION_INTERVAL_MS
// The DB should not be compacted, so the last compaction time should
// not be updated
time.set(now + MAX_COMPACTION_INTERVAL_MS);
db = open(true, messageFactory, clock);
txn = db.startTransaction();
s = db.getSettings(txn, DB_SETTINGS_NAMESPACE);
assertEquals(now, s.getLong(LAST_COMPACTED_KEY, 0));
db.commitTransaction(txn);
db.close();
// Time: now + MAX_COMPACTION_INTERVAL_MS + 1
// The DB should be compacted, so the last compaction time should be
// updated
time.set(now + MAX_COMPACTION_INTERVAL_MS + 1);
db = open(true, messageFactory, clock);
txn = db.startTransaction();
s = db.getSettings(txn, DB_SETTINGS_NAMESPACE);
assertEquals(now + MAX_COMPACTION_INTERVAL_MS + 1,
s.getLong(LAST_COMPACTED_KEY, 0));
db.commitTransaction(txn);
db.close();
}
@Test
public void testPendingContacts() throws Exception {
Database<Connection> db = open(false);

View File

@@ -17,7 +17,7 @@
app:layout_constraintVertical_bias="0.5"
app:layout_constraintVertical_chainStyle="packed"
app:srcCompat="@drawable/startup_lock"
app:tint="@color/briar_primary"
app:tint="@color/briar_accent"
tools:ignore="ContentDescription" />
<ProgressBar