在WAL模式下,无需FileStreams即可备份sqlite db //通过export / backup sql命令

时间:2019-03-29 10:15:38

标签: android sqlite

我在这里搜索了很多答案,但是所有人都使用FileInputStreamFileOutputStream来备份数据库。

在将PRAGMA语句与journal_mode=WAL(预写日志),异步模式等一起使用时,文件复制失败。

如何备份/导出/快照在Android上以WAL模式运行的sqlite数据库?

文件复制不是正确的方法。在sqlite中必须有一些备份/导出命令(嗯,通过sqlite命令外壳可以使用 )。

到目前为止,我还没有找到解决方案。任何帮助表示赞赏。

1 个答案:

答案 0 :(得分:0)

  

当您将PRAGMA语句与   journal_mode = WAL(预写日志),异步模式,等等。

简而言之,您需要备份并还原所有三个文件,或者需要确保数据库已完全检查点,备份数据库文件并删除 -wal -shm 还原文件。

这里是a more comprehensive answer

这是在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获取(解析的),这是一个简单的签名更改,允许传递数据库名称。