diff options
| author | Makoto Onuki <omakoto@google.com> | 2018-09-25 15:12:15 +0000 |
|---|---|---|
| committer | Android (Google) Code Review <android-gerrit@google.com> | 2018-09-25 15:12:15 +0000 |
| commit | 0f88f865bdce7cb15dc9872a2728cd593d5ac66e (patch) | |
| tree | 17fb4348f68a2355e238f7b0e994fd651c5ed9e7 /core/java | |
| parent | 45fda272111f43fe570540e9cf75772efa5c6cff (diff) | |
| parent | 0939c5a2b313d7fc32ca5e1a6c161b0089e141e9 (diff) | |
Merge "Truncate(*1) it if WAL file is too big when opening DB" into pi-dev
Diffstat (limited to 'core/java')
4 files changed, 69 insertions, 0 deletions
diff --git a/core/java/android/database/sqlite/SQLiteCompatibilityWalFlags.java b/core/java/android/database/sqlite/SQLiteCompatibilityWalFlags.java index 5bf3a7c43640..06c069c583b5 100644 --- a/core/java/android/database/sqlite/SQLiteCompatibilityWalFlags.java +++ b/core/java/android/database/sqlite/SQLiteCompatibilityWalFlags.java @@ -41,6 +41,7 @@ public class SQLiteCompatibilityWalFlags { private static volatile boolean sFlagsSet; private static volatile boolean sCompatibilityWalSupported; private static volatile String sWALSyncMode; + private static volatile long sTruncateSize = -1; // This flag is used to avoid recursive initialization due to circular dependency on Settings private static volatile boolean sCallingGlobalSettings; @@ -71,6 +72,19 @@ public class SQLiteCompatibilityWalFlags { return sWALSyncMode; } + /** + * Override {@link com.android.internal.R.integer#db_wal_truncate_size}. + * + * @return the value set in the global setting, or -1 if a value is not set. + * + * @hide + */ + @VisibleForTesting + public static long getTruncateSize() { + initIfNeeded(); + return sTruncateSize; + } + private static void initIfNeeded() { if (sInitialized || sCallingGlobalSettings) { return; @@ -115,6 +129,7 @@ public class SQLiteCompatibilityWalFlags { sCompatibilityWalSupported = parser.getBoolean("compatibility_wal_supported", SQLiteGlobal.isCompatibilityWalSupported()); sWALSyncMode = parser.getString("wal_syncmode", SQLiteGlobal.getWALSyncMode()); + sTruncateSize = parser.getInt("truncate_size", -1); Log.i(TAG, "Read compatibility WAL flags: compatibility_wal_supported=" + sCompatibilityWalSupported + ", wal_syncmode=" + sWALSyncMode); sFlagsSet = true; diff --git a/core/java/android/database/sqlite/SQLiteConnection.java b/core/java/android/database/sqlite/SQLiteConnection.java index 101fb821f4ce..9c639a5a9867 100644 --- a/core/java/android/database/sqlite/SQLiteConnection.java +++ b/core/java/android/database/sqlite/SQLiteConnection.java @@ -32,6 +32,7 @@ import android.util.Printer; import dalvik.system.BlockGuard; import dalvik.system.CloseGuard; +import java.io.File; import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.Date; @@ -303,6 +304,7 @@ public final class SQLiteConnection implements CancellationSignal.OnCancelListen } else { setSyncMode(SQLiteGlobal.getWALSyncMode()); } + maybeTruncateWalFile(); } else { setJournalMode(mConfiguration.journalMode == null ? SQLiteGlobal.getDefaultJournalMode() : mConfiguration.journalMode); @@ -312,6 +314,40 @@ public final class SQLiteConnection implements CancellationSignal.OnCancelListen } } + /** + * If the WAL file exists and larger than a threshold, truncate it by executing + * PRAGMA wal_checkpoint. + */ + private void maybeTruncateWalFile() { + final long threshold = SQLiteGlobal.getWALTruncateSize(); + if (DEBUG) { + Log.d(TAG, "Truncate threshold=" + threshold); + } + if (threshold == 0) { + return; + } + + final File walFile = new File(mConfiguration.path + "-wal"); + if (!walFile.isFile()) { + return; + } + final long size = walFile.length(); + if (size < threshold) { + if (DEBUG) { + Log.d(TAG, walFile.getAbsolutePath() + " " + size + " bytes: No need to truncate"); + } + return; + } + + Log.i(TAG, walFile.getAbsolutePath() + " " + size + " bytes: Bigger than " + + threshold + "; truncating"); + try { + executeForString("PRAGMA wal_checkpoint(TRUNCATE)", null, null); + } catch (SQLiteException e) { + Log.w(TAG, "Failed to truncate the -wal file", e); + } + } + private void setSyncMode(String newValue) { String value = executeForString("PRAGMA synchronous", null, null); if (!canonicalizeSyncMode(value).equalsIgnoreCase( diff --git a/core/java/android/database/sqlite/SQLiteGlobal.java b/core/java/android/database/sqlite/SQLiteGlobal.java index e6b6acf7b8ee..67e5f65d5a1f 100644 --- a/core/java/android/database/sqlite/SQLiteGlobal.java +++ b/core/java/android/database/sqlite/SQLiteGlobal.java @@ -164,4 +164,21 @@ public final class SQLiteGlobal { com.android.internal.R.integer.db_default_idle_connection_timeout)); } + /** + * When opening a database, if the WAL file is larger than this size, we'll truncate it. + * + * (If it's 0, we do not truncate.) + * + * @hide + */ + public static long getWALTruncateSize() { + final long setting = SQLiteCompatibilityWalFlags.getTruncateSize(); + if (setting >= 0) { + return setting; + } + return SystemProperties.getInt("debug.sqlite.wal.truncatesize", + Resources.getSystem().getInteger( + com.android.internal.R.integer.db_wal_truncate_size)); + } + } diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java index fbe6f3ee7dff..e00ff205c082 100644 --- a/core/java/android/provider/Settings.java +++ b/core/java/android/provider/Settings.java @@ -12777,6 +12777,7 @@ public final class Settings { * Supported keys: * compatibility_wal_supported (boolean) * wal_syncmode (String) + * truncate_size (int) * * @hide */ |
