summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--core/java/android/database/sqlite/SQLiteConnection.java52
-rw-r--r--core/java/android/database/sqlite/SQLiteDatabase.java26
-rw-r--r--core/java/android/database/sqlite/SQLiteDatabaseConfiguration.java9
-rw-r--r--core/java/android/database/sqlite/SQLiteGlobal.java41
-rw-r--r--core/jni/android_database_SQLiteConnection.cpp9
-rwxr-xr-xcore/res/res/values/config.xml22
-rw-r--r--core/res/res/values/public.xml4
7 files changed, 129 insertions, 34 deletions
diff --git a/core/java/android/database/sqlite/SQLiteConnection.java b/core/java/android/database/sqlite/SQLiteConnection.java
index b5cef81..1900301 100644
--- a/core/java/android/database/sqlite/SQLiteConnection.java
+++ b/core/java/android/database/sqlite/SQLiteConnection.java
@@ -208,6 +208,11 @@ public final class SQLiteConnection implements CancellationSignal.OnCancelListen
mConfiguration.label,
SQLiteDebug.DEBUG_SQL_STATEMENTS, SQLiteDebug.DEBUG_SQL_TIME);
+ setSyncMode();
+ setPageSize();
+ setAutoCheckpointInterval();
+ setJournalSizeLimit();
+ setJournalModeFromConfiguration();
setLocaleFromConfiguration();
}
@@ -231,6 +236,44 @@ public final class SQLiteConnection implements CancellationSignal.OnCancelListen
}
}
+ private void setSyncMode() {
+ if (!mConfiguration.isInMemoryDb()) {
+ execute("PRAGMA synchronous=" + SQLiteGlobal.getSyncMode(), null, null);
+ }
+ }
+
+ private void setPageSize() {
+ if (!mConfiguration.isInMemoryDb()) {
+ execute("PRAGMA page_size=" + SQLiteGlobal.getDefaultPageSize(), null, null);
+ }
+ }
+
+ private void setAutoCheckpointInterval() {
+ if (!mConfiguration.isInMemoryDb()) {
+ executeForLong("PRAGMA wal_autocheckpoint=" + SQLiteGlobal.getWALAutoCheckpoint(),
+ null, null);
+ }
+ }
+
+ private void setJournalSizeLimit() {
+ if (!mConfiguration.isInMemoryDb()) {
+ executeForLong("PRAGMA journal_size_limit=" + SQLiteGlobal.getJournalSizeLimit(),
+ null, null);
+ }
+ }
+
+ private void setJournalModeFromConfiguration() {
+ if (!mConfiguration.isInMemoryDb()) {
+ String result = executeForString("PRAGMA journal_mode=" + mConfiguration.journalMode,
+ null, null);
+ if (!result.equalsIgnoreCase(mConfiguration.journalMode)) {
+ Log.e(TAG, "setting journal_mode to " + mConfiguration.journalMode
+ + " failed for db: " + mConfiguration.label
+ + " (on pragma set journal_mode, sqlite returned:" + result);
+ }
+ }
+ }
+
private void setLocaleFromConfiguration() {
nativeSetLocale(mConnectionPtr, mConfiguration.locale.toString());
}
@@ -246,7 +289,9 @@ public final class SQLiteConnection implements CancellationSignal.OnCancelListen
}
}
- // Remember whether locale has changed.
+ // Remember what changed.
+ boolean journalModeChanged = !configuration.journalMode.equalsIgnoreCase(
+ mConfiguration.journalMode);
boolean localeChanged = !configuration.locale.equals(mConfiguration.locale);
// Update configuration parameters.
@@ -255,6 +300,11 @@ public final class SQLiteConnection implements CancellationSignal.OnCancelListen
// Update prepared statement cache size.
mPreparedStatementCache.resize(configuration.maxSqlCacheSize);
+ // Update journal mode.
+ if (journalModeChanged) {
+ setJournalModeFromConfiguration();
+ }
+
// Update locale.
if (localeChanged) {
setLocaleFromConfiguration();
diff --git a/core/java/android/database/sqlite/SQLiteDatabase.java b/core/java/android/database/sqlite/SQLiteDatabase.java
index 36f678d..515658f 100644
--- a/core/java/android/database/sqlite/SQLiteDatabase.java
+++ b/core/java/android/database/sqlite/SQLiteDatabase.java
@@ -717,9 +717,6 @@ public class SQLiteDatabase extends SQLiteClosable {
onCorruption();
openInner();
}
-
- // Disable WAL if it was previously enabled.
- setJournalMode("TRUNCATE");
} catch (SQLiteException ex) {
Log.e(TAG, "Failed to open database '" + getLabel() + "'.", ex);
close();
@@ -739,19 +736,6 @@ public class SQLiteDatabase extends SQLiteClosable {
}
}
- private void setJournalMode(String mode) {
- // Journal mode can be set only for non-memory databases
- // AND can't be set for readonly databases
- if (isInMemoryDatabase() || isReadOnly()) {
- return;
- }
- String s = DatabaseUtils.stringForQuery(this, "PRAGMA journal_mode=" + mode, null);
- if (!s.equalsIgnoreCase(mode)) {
- Log.e(TAG, "setting journal_mode to " + mode + " failed for db: " + getLabel()
- + " (on pragma set journal_mode, sqlite returned:" + s);
- }
- }
-
/**
* Create a memory backed SQLite database. Its contents will be destroyed
* when the database is closed.
@@ -1761,13 +1745,10 @@ public class SQLiteDatabase extends SQLiteClosable {
}
mIsWALEnabledLocked = true;
- mConfigurationLocked.maxConnectionPoolSize = Math.max(2,
- Resources.getSystem().getInteger(
- com.android.internal.R.integer.db_connection_pool_size));
+ mConfigurationLocked.maxConnectionPoolSize = SQLiteGlobal.getWALConnectionPoolSize();
+ mConfigurationLocked.journalMode = "WAL";
mConnectionPoolLocked.reconfigure(mConfigurationLocked);
}
-
- setJournalMode("WAL");
return true;
}
@@ -1785,10 +1766,9 @@ public class SQLiteDatabase extends SQLiteClosable {
mIsWALEnabledLocked = false;
mConfigurationLocked.maxConnectionPoolSize = 1;
+ mConfigurationLocked.journalMode = SQLiteGlobal.getDefaultJournalMode();
mConnectionPoolLocked.reconfigure(mConfigurationLocked);
}
-
- setJournalMode("TRUNCATE");
}
/**
diff --git a/core/java/android/database/sqlite/SQLiteDatabaseConfiguration.java b/core/java/android/database/sqlite/SQLiteDatabaseConfiguration.java
index 02ef671..32a1bcb 100644
--- a/core/java/android/database/sqlite/SQLiteDatabaseConfiguration.java
+++ b/core/java/android/database/sqlite/SQLiteDatabaseConfiguration.java
@@ -85,6 +85,13 @@ public final class SQLiteDatabaseConfiguration {
public Locale locale;
/**
+ * The database journal mode.
+ *
+ * Default is {@link SQLiteGlobal#getDefaultJournalMode()}.
+ */
+ public String journalMode;
+
+ /**
* The custom functions to register.
*/
public final ArrayList<SQLiteCustomFunction> customFunctions =
@@ -110,6 +117,7 @@ public final class SQLiteDatabaseConfiguration {
maxConnectionPoolSize = 1;
maxSqlCacheSize = 25;
locale = Locale.getDefault();
+ journalMode = SQLiteGlobal.getDefaultJournalMode();
}
/**
@@ -146,6 +154,7 @@ public final class SQLiteDatabaseConfiguration {
maxConnectionPoolSize = other.maxConnectionPoolSize;
maxSqlCacheSize = other.maxSqlCacheSize;
locale = other.locale;
+ journalMode = other.journalMode;
customFunctions.clear();
customFunctions.addAll(other.customFunctions);
}
diff --git a/core/java/android/database/sqlite/SQLiteGlobal.java b/core/java/android/database/sqlite/SQLiteGlobal.java
index dbefd63..af0cf45 100644
--- a/core/java/android/database/sqlite/SQLiteGlobal.java
+++ b/core/java/android/database/sqlite/SQLiteGlobal.java
@@ -16,6 +16,7 @@
package android.database.sqlite;
+import android.content.res.Resources;
import android.os.StatFs;
/**
@@ -64,4 +65,44 @@ public final class SQLiteGlobal {
return sDefaultPageSize;
}
}
+
+ /**
+ * Gets the default journal mode when WAL is not in use.
+ */
+ public static String getDefaultJournalMode() {
+ return Resources.getSystem().getString(
+ com.android.internal.R.string.db_default_journal_mode);
+ }
+
+ /**
+ * Gets the journal size limit in bytes.
+ */
+ public static int getJournalSizeLimit() {
+ return Resources.getSystem().getInteger(
+ com.android.internal.R.integer.db_journal_size_limit);
+ }
+
+ /**
+ * Gets the database synchronization mode.
+ */
+ public static String getSyncMode() {
+ return Resources.getSystem().getString(
+ com.android.internal.R.string.db_sync_mode);
+ }
+
+ /**
+ * Gets the WAL auto-checkpoint integer in database pages.
+ */
+ public static int getWALAutoCheckpoint() {
+ return Math.max(1, Resources.getSystem().getInteger(
+ com.android.internal.R.integer.db_wal_autocheckpoint));
+ }
+
+ /**
+ * Gets the default connection pool size when in WAL mode.
+ */
+ public static int getWALConnectionPoolSize() {
+ return Math.max(2, Resources.getSystem().getInteger(
+ com.android.internal.R.integer.db_connection_pool_size));
+ }
}
diff --git a/core/jni/android_database_SQLiteConnection.cpp b/core/jni/android_database_SQLiteConnection.cpp
index f47dc8a..c8f911f 100644
--- a/core/jni/android_database_SQLiteConnection.cpp
+++ b/core/jni/android_database_SQLiteConnection.cpp
@@ -128,15 +128,6 @@ static jint nativeOpen(JNIEnv* env, jclass clazz, jstring pathStr, jint openFlag
return 0;
}
- // Enable WAL auto-checkpointing after a commit whenever at least one frame is in the log.
- // This ensures that a checkpoint will occur after each transaction if needed.
- err = sqlite3_wal_autocheckpoint(db, 1);
- if (err) {
- throw_sqlite3_exception(env, db, "Could not enable auto-checkpointing.");
- sqlite3_close(db);
- return 0;
- }
-
// Register custom Android functions.
err = register_android_functions(db, UTF16_STORAGE);
if (err) {
diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml
index 806406d..8e5b509 100755
--- a/core/res/res/values/config.xml
+++ b/core/res/res/values/config.xml
@@ -646,9 +646,29 @@
<bool translatable="false" name="skip_restoring_network_selection">false</bool>
<!-- Maximum number of database connections opened and managed by framework layer
- to handle queries on each database. -->
+ to handle queries on each database when using Write-Ahead Logging. -->
<integer name="db_connection_pool_size">4</integer>
+ <!-- The default journal mode to use use when Write-Ahead Logging is not active.
+ Choices are: OFF, DELETE, TRUNCATE, PERSIST and MEMORY.
+ PERSIST may improve performance by reducing how often journal blocks are
+ reallocated (compared to truncation) resulting in better data block locality
+ and less churn of the storage media. -->
+ <string name="db_default_journal_mode">TRUNCATE</string>
+
+ <!-- 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. -->
+ <integer name="db_journal_size_limit">524288</integer>
+
+ <!-- The database synchronization mode.
+ Choices are: FULL, NORMAL, OFF. -->
+ <string name="db_sync_mode">FULL</string>
+
+ <!-- The Write-Ahead Log auto-checkpoint interval in database pages.
+ The log is checkpointed automatically whenever it exceeds this many pages. -->
+ <integer name="db_wal_autocheckpoint">1</integer>
+
<!-- Max space (in MB) allocated to DownloadManager to store the downloaded
files if they are to be stored in DownloadManager's data dir,
which typically is /data/data/com.android.providers.downloads/files -->
diff --git a/core/res/res/values/public.xml b/core/res/res/values/public.xml
index 94a671d..15499fe 100644
--- a/core/res/res/values/public.xml
+++ b/core/res/res/values/public.xml
@@ -250,6 +250,8 @@
<java-symbol type="integer" name="config_wifi_framework_scan_interval" />
<java-symbol type="integer" name="config_wifi_supplicant_scan_interval" />
<java-symbol type="integer" name="db_connection_pool_size" />
+ <java-symbol type="integer" name="db_journal_size_limit" />
+ <java-symbol type="integer" name="db_wal_autocheckpoint" />
<java-symbol type="integer" name="max_action_buttons" />
<java-symbol type="color" name="tab_indicator_text_v4" />
@@ -438,6 +440,8 @@
<java-symbol type="string" name="day_of_week_shortest_thursday" />
<java-symbol type="string" name="day_of_week_shortest_tuesday" />
<java-symbol type="string" name="day_of_week_shortest_wednesday" />
+ <java-symbol type="string" name="db_default_journal_mode" />
+ <java-symbol type="string" name="db_sync_mode" />
<java-symbol type="string" name="decline" />
<java-symbol type="string" name="default_permission_group" />
<java-symbol type="string" name="default_text_encoding" />