Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 5bd43ad2 authored by Fyodor Kupolov's avatar Fyodor Kupolov
Browse files

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
parent 75dcc4f0
Loading
Loading
Loading
Loading
+3 −1
Original line number Diff line number Diff line
@@ -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 {
+9 −2
Original line number Diff line number Diff line
@@ -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;
            }
        }
+10 −0
Original line number Diff line number Diff line
@@ -110,6 +110,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;
    }

    /**
+11 −0
Original line number Diff line number Diff line
@@ -80,6 +80,17 @@ public final class SQLiteGlobal {
                com.android.internal.R.string.db_default_journal_mode));
    }

    /**
     * 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.
     */
+5 −0
Original line number Diff line number Diff line
@@ -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. -->
Loading