android - 在没有 FileStreams 的 WAL 模式下备份 sqlite db // 通过导出/备份 sql 命令
问题描述
我在这里搜索了很多答案,但都使用FileInputStream
和FileOutputStream
备份数据库。
在您使用具有(预写日志记录)、异步模式等的PRAGMA
语句时,文件复制会失败。journal_mode=WAL
如何备份/导出/快照在 android 上以 WAL 模式运行的 sqlite 数据库?
文件副本不可能是正确的方法。sqlite 中必须有一些可用的备份/导出命令(嗯,它可以通过 sqlite 命令 shell 获得)。
到目前为止,我还没有找到解决方案。非常感谢任何帮助。
解决方案
当您将 PRAGMA 语句与 journal_mode=WAL(预写日志记录)、异步模式等一起使用时,文件复制会失败。
简而言之,您需要备份并恢复所有三个文件,或者您需要确保数据库已完全检查点,备份数据库文件并在恢复时删除-wal和-shm文件。
这是一个更全面的答案。
这是一个在 WAL 模式下检查数据库的方法示例(这用于日志模式可以是 Android 默认值):-
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();
}
- 请注意,上面的数据库名称是通过常量 DBConstants.DATABSENAME 获得(解析)的,这将是一个简单的签名更改以允许传递数据库名称。
推荐阅读
- google-sheets-api - 在工作表名称中转义加号 (+)
- google-cloud-firestore - Firestore GRPC API 如何处理多设备中的恢复令牌?
- java - Java平台微版软件开发包3.0 java.lang.UnsatisfiedLinkError
- c++ - How to convert gps time to utc in c++?
- sql - 基于动物数据集中范围的列 - sql
- python - 如何访问嵌套的字典元素?
- python - 向 tensorflow.python.keras.models.Model 添加一个新层
- laravel - 在 laravel 中通过 axios (VueJS) 发布请求给出 500 错误
- jmeter - Jmeter - 在一小时内以最高定义的并发运行确切数量的请求
- php - 当我发送电子邮件 / swiftmailer 时图像不显示