迁移数据库期刊模式从删除到WAL



我在我的应用程序中提供了一些导出/导入功能,现在我看到,如果在较新的Android版本中导入旧导出,这会导致问题,因为在许多运行Android 9或运行的手机上更高的是,SQLite数据库确实使用journal_mode WAL代替DELETE,它们在旧电话上使用。

Infos/Obersvations:

  • 我没有在我的应用程序内设置手动日记帐模式(例如SQLiteOpenHelper内部(
  • 并非所有的Android 9手机都启用了此功能(我的S9运行派仍然使用DELETE模式(,因此在我的手机上还原旧备份非常好
  • 在不使用DELETE模式的电话上,恢复的备份会崩溃我的应用程序,因为数据库似乎是我的应用程序空的 - 我不小心。f课程,关注空数据库并不能解决问题,因为我需要导入的数据...

问题:

上面导致以下3个问题:

  • 默认情况下,我如何找出当前手机是否使用WALDELETE
  • 如何找出给定的*.db文件的模式?
  • 如何为给定的*.db文件更改此模式?

我不想要

我不想完全禁用我的应用程序中的WAL,我确实更喜欢一些基于迁移的解决方案

如何默认情况下查找当前电话使用WAL还是删除?

如果设备使用Android 9 ,则应(如果正确实现(默认为WAL模式。但是,设备提供商可以提供自定义/旧版实现。因此,您需要按照下面显示的检查/回答(实际使用下面的方法,无需检查(。

崩溃的原因可能是您没有备份WAL模式处于活动状态时存在的附加-WAL和-SHM文件。

我在实际进行备份之前使用以下代码

  • 显然 dbconstants.dbname 是数据库名称
  • 数据库存储在默认位置( data/data/the_package/databases/((
  • (

: -

private void checkpointIfWALEnabled(Context context) {
    final String TAG = "WALCHKPNT";
    Cursor csr;
    int wal_busy = -99, wal_log = -99, wal_checkpointed = -99;
    SQLiteDatabase db = SQLiteDatabase.openDatabase(context.getDatabasePath(DBConstants.DATABASE_NAME).getPath(),null,SQLiteDatabase.OPEN_READWRITE);
    csr = db.rawQuery("PRAGMA journal_mode",null);
    if (csr.moveToFirst()) {
        String mode = csr.getString(0);
        //Log.d(TAG, "Mode is " + mode);
        if (mode.toLowerCase().equals("wal")) {
            csr = db.rawQuery("PRAGMA wal_checkpoint",null);
            if (csr.moveToFirst()) {
                wal_busy = csr.getInt(0);
                wal_log = csr.getInt(1);
                wal_checkpointed = csr.getInt(2);
            }
            //Log.d(TAG,"Checkpoint pre checkpointing Busy = " + String.valueOf(wal_busy) + " LOG = " + String.valueOf(wal_log) + " CHECKPOINTED = " + String.valueOf(wal_checkpointed) );
            csr = db.rawQuery("PRAGMA wal_checkpoint(TRUNCATE)",null);
            csr.getCount();
            csr = db.rawQuery("PRAGMA wal_checkpoint",null);
            if (csr.moveToFirst()) {
                wal_busy = csr.getInt(0);
                wal_log = csr.getInt(1);
                wal_checkpointed = csr.getInt(2);
            }
            //Log.d(TAG,"Checkpoint post checkpointing Busy = " + String.valueOf(wal_busy) + " LOG = " + String.valueOf(wal_log) + " CHECKPOINTED = " + String.valueOf(wal_checkpointed) );
        }
    }
    csr.close();
    db.close();
}

这在任何一种情况下都可以使用,因为它可以通过检查数据库来有效地使用 -WAL > -SHM 文件(将它们清空(。因此,无需复制 -WAL -SHM 文件,没有需要投入的出色交易。它适用于两种模式。

如何找出给定 *.db文件的模式?

csr = db.rawQuery("PRAGMA journal_mode",null);是询问日记模式的行,还有sqlitedatabase方法iswriteaheadeaheadloggingEnabled返回true或false。

关于: -

如何为给定的 *.db文件更改此模式?

如果使用Android SDK,则可以使用sqlitedatabase方法enableWriteAheadLogging或disableWriteAheadLogging,也可以通过使用 Journal_mode pragma设置它,但请注意何时可以进行限制。写入记录

最新更新