diff options
-rw-r--r-- | core/java/android/database/sqlite/SQLiteConnection.java | 52 | ||||
-rw-r--r-- | core/java/android/database/sqlite/SQLiteDatabase.java | 26 | ||||
-rw-r--r-- | core/java/android/database/sqlite/SQLiteDatabaseConfiguration.java | 9 | ||||
-rw-r--r-- | core/java/android/database/sqlite/SQLiteGlobal.java | 41 | ||||
-rw-r--r-- | core/jni/android_database_SQLiteConnection.cpp | 9 | ||||
-rwxr-xr-x | core/res/res/values/config.xml | 22 | ||||
-rw-r--r-- | core/res/res/values/public.xml | 4 |
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" /> |