summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Fyodor Kupolov <fkupolov@google.com> 2017-10-25 16:09:35 -0700
committer Fyodor Kupolov <fkupolov@google.com> 2017-10-26 11:21:19 -0700
commit5bd43ad2e7e4e1ee2c31d920ba4b148bbdf74d11 (patch)
tree5e89bd4ae207a4564f5df8f2d67eeba5fb555b0d
parent75dcc4f040199f410e680fc5938aeae53c501d7a (diff)
Initial version of compatibility WAL
In this mode, only database journal mode will be changed, connection pool size will still be limited to a single connection. If enabled, compatibility WAL mode will be used if an app hasn't explicitly requested journal mode, by calling disable/enableWriteAheadLogging. Compatibility WAL mode is controlled by debug.sqlite.use_compatibility_wal property and db_use_compatibility_wal config resource. Impact on write performance: On ext4, with WAL, there is approx 300% increase in speed of update operations On f2fs, with WAL, there is approx 5% increase in speed of update operations Impact on number of writes: On ext4, switching to WAL reduces the number of writes by approx 50%. On f2fs, switching to WAL increases the number of writes by approx 15%. Test: CtsDatabaseTestCases Test: manual, running device Bug: 33044236 Change-Id: Iaffb5651df39d8c9f710d7dbbe174f9c0d8a3186
-rw-r--r--core/java/android/database/sqlite/SQLiteConnection.java4
-rw-r--r--core/java/android/database/sqlite/SQLiteDatabase.java11
-rw-r--r--core/java/android/database/sqlite/SQLiteDatabaseConfiguration.java10
-rw-r--r--core/java/android/database/sqlite/SQLiteGlobal.java11
-rw-r--r--core/res/res/values/config.xml5
-rw-r--r--core/res/res/values/symbols.xml1
6 files changed, 39 insertions, 3 deletions
diff --git a/core/java/android/database/sqlite/SQLiteConnection.java b/core/java/android/database/sqlite/SQLiteConnection.java
index c28583ea867a..361b81b77f1d 100644
--- a/core/java/android/database/sqlite/SQLiteConnection.java
+++ b/core/java/android/database/sqlite/SQLiteConnection.java
@@ -289,7 +289,9 @@ public final class SQLiteConnection implements CancellationSignal.OnCancelListen
private void setWalModeFromConfiguration() {
if (!mConfiguration.isInMemoryDb() && !mIsReadOnlyConnection) {
- if ((mConfiguration.openFlags & SQLiteDatabase.ENABLE_WRITE_AHEAD_LOGGING) != 0) {
+ boolean walEnabled =
+ (mConfiguration.openFlags & SQLiteDatabase.ENABLE_WRITE_AHEAD_LOGGING) != 0;
+ if (walEnabled || mConfiguration.useCompatibilityWal) {
setJournalMode("WAL");
setSyncMode(SQLiteGlobal.getWALSyncMode());
} else {
diff --git a/core/java/android/database/sqlite/SQLiteDatabase.java b/core/java/android/database/sqlite/SQLiteDatabase.java
index df0e262b712f..83b8dc76bfc3 100644
--- a/core/java/android/database/sqlite/SQLiteDatabase.java
+++ b/core/java/android/database/sqlite/SQLiteDatabase.java
@@ -285,6 +285,7 @@ public final class SQLiteDatabase extends SQLiteClosable {
}
}
mConfigurationLocked.idleConnectionTimeoutMs = effectiveTimeoutMs;
+ mConfigurationLocked.useCompatibilityWal = SQLiteGlobal.isCompatibilityWalSupported();
}
@Override
@@ -2070,15 +2071,21 @@ public final class SQLiteDatabase extends SQLiteClosable {
synchronized (mLock) {
throwIfNotOpenLocked();
- if ((mConfigurationLocked.openFlags & ENABLE_WRITE_AHEAD_LOGGING) == 0) {
+ final boolean oldUseCompatibilityWal = mConfigurationLocked.useCompatibilityWal;
+ final int oldFlags = mConfigurationLocked.openFlags;
+ if (!oldUseCompatibilityWal && (oldFlags & ENABLE_WRITE_AHEAD_LOGGING) == 0) {
return;
}
mConfigurationLocked.openFlags &= ~ENABLE_WRITE_AHEAD_LOGGING;
+ // If an app explicitly disables WAL, do not even use compatibility mode
+ mConfigurationLocked.useCompatibilityWal = false;
+
try {
mConnectionPoolLocked.reconfigure(mConfigurationLocked);
} catch (RuntimeException ex) {
- mConfigurationLocked.openFlags |= ENABLE_WRITE_AHEAD_LOGGING;
+ mConfigurationLocked.openFlags = oldFlags;
+ mConfigurationLocked.useCompatibilityWal = oldUseCompatibilityWal;
throw ex;
}
}
diff --git a/core/java/android/database/sqlite/SQLiteDatabaseConfiguration.java b/core/java/android/database/sqlite/SQLiteDatabaseConfiguration.java
index 34c9b3395d1a..905da7247308 100644
--- a/core/java/android/database/sqlite/SQLiteDatabaseConfiguration.java
+++ b/core/java/android/database/sqlite/SQLiteDatabaseConfiguration.java
@@ -111,6 +111,15 @@ public final class SQLiteDatabaseConfiguration {
public long idleConnectionTimeoutMs = Long.MAX_VALUE;
/**
+ * Enables compatibility WAL mode. Applications cannot explicitly choose compatibility WAL mode,
+ * therefore it is not exposed as a flag.
+ *
+ * <p>In this mode, only database journal mode will be changed, connection pool
+ * size will still be limited to a single connection.
+ */
+ public boolean useCompatibilityWal;
+
+ /**
* Creates a database configuration with the required parameters for opening a
* database and default values for all other parameters.
*
@@ -170,6 +179,7 @@ public final class SQLiteDatabaseConfiguration {
lookasideSlotSize = other.lookasideSlotSize;
lookasideSlotCount = other.lookasideSlotCount;
idleConnectionTimeoutMs = other.idleConnectionTimeoutMs;
+ useCompatibilityWal = other.useCompatibilityWal;
}
/**
diff --git a/core/java/android/database/sqlite/SQLiteGlobal.java b/core/java/android/database/sqlite/SQLiteGlobal.java
index 94d5555c4c24..bb2a51706767 100644
--- a/core/java/android/database/sqlite/SQLiteGlobal.java
+++ b/core/java/android/database/sqlite/SQLiteGlobal.java
@@ -81,6 +81,17 @@ public final class SQLiteGlobal {
}
/**
+ * Returns true if compatibility WAL mode is supported. In this mode, only
+ * database journal mode is changed. Connection pool will use at most one connection.
+ * @hide
+ */
+ public static boolean isCompatibilityWalSupported() {
+ return SystemProperties.getBoolean("debug.sqlite.compatibility_wal_supported",
+ Resources.getSystem().getBoolean(
+ com.android.internal.R.bool.db_compatibility_wal_supported));
+ }
+
+ /**
* Gets the journal size limit in bytes.
*/
public static int getJournalSizeLimit() {
diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml
index 571aad9bdafa..f727dd5e543e 100644
--- a/core/res/res/values/config.xml
+++ b/core/res/res/values/config.xml
@@ -1686,6 +1686,11 @@
a transaction, so it interacts poorly with SECURE_DELETE. -->
<string name="db_default_journal_mode" translatable="false">TRUNCATE</string>
+ <!-- Enables compatibility WAL mode.
+ In this mode, only database journal mode will be changed, connection pool
+ size will still be limited to a single connection. -->
+ <bool name="db_compatibility_wal_supported">true</bool>
+
<!-- Maximum size of the persistent journal file in bytes.
If the journal file grows to be larger than this amount then SQLite will
truncate it after committing the transaction. -->
diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml
index 896de53cbc4e..8899f28c4a49 100644
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -666,6 +666,7 @@
<java-symbol type="string" name="date_time" />
<java-symbol type="string" name="date_time_set" />
<java-symbol type="string" name="date_time_done" />
+ <java-symbol type="bool" name="db_compatibility_wal_supported" />
<java-symbol type="string" name="db_default_journal_mode" />
<java-symbol type="string" name="db_default_sync_mode" />
<java-symbol type="string" name="db_wal_sync_mode" />