gpt4 book ai didi

android - 将数据库日志模式从 DELETE 迁移到 WAL

转载 作者:行者123 更新时间:2023-11-29 23:03:23 26 4
gpt4 key购买 nike

我在我的应用程序中提供了一些导出/导入功能,现在我明白了,如果将旧的导出导入到较新的 android 版本中,这会产生问题,因为在许多运行 android 9 或更高版本的手机上,SQLite 数据库确实使用 journal_mode WAL 而不是他们在旧手机上使用的 DELETE

信息/观察:

  • 我没有在我的应用程序中设置手动日志模式(例如在 SQLiteOpenHelper 中)
  • 并非所有 android 9 手机都启用了此功能(我运行 PIE 的 S9 仍然使用 DELETE 模式),因此在我的手机上恢复旧备份非常好
  • 在不使用 DELETE 模式的手机上,恢复备份会使我的应用程序崩溃,因为数据库对我的应用程序来说似乎是空的——我没有注意这一点。 f 当然,注意空数据库并不能解决问题,因为我需要导入的数据...

问题:

以上引出以下 3 个问题:

  • 如何知道当前手机默认使用WAL还是DELETE
  • 如何找出给定 *.db 文件的模式?
  • 如何为给定的 *.db 文件更改此模式?

我不想要的

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

最佳答案

how can I find out if the current phone uses WAL or DELETE by default?

如果设备使用 Android 9+,那么如果正确实现,它应该默认为 WAL 模式。但是,设备供应商可以提供自定义/遗留实现。因此,您需要按照下面显示/回答的方式进行检查(实际上使用下面的方法不需要检查)。

崩溃的原因可能是您没有备份 WAL 模式处于 Activity 状态时存在的附加 -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 文件,因为没有需要提交的未完成交易。它适用于任何一种模式。

how can I find out the mode of a given *.db file?

csr = db.rawQuery("PRAGMA journal_mode",null); 是查询日志模式的行,还有 SQLiteDatabase 方法 isWriteAheadLoggingEnabled返回 true 或 false。

关于:-

how can I change this mode for a given *.db file?

如果使用 Android SDK,则可以使用 SQLiteDatabase 方法 enableWriteAheadLoggingdisableWriteAheadLogging或者您可以通过 journal_mode pragma 设置它, 但要注意何时可以进行的限制。 Write-Ahead Logging

关于android - 将数据库日志模式从 DELETE 迁移到 WAL,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56786476/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com