Android 使用export/Backup sql命令在WAL模式下备份sqlite数据库,不使用FileStreams//

Android 使用export/Backup sql命令在WAL模式下备份sqlite数据库,不使用FileStreams//,android,sqlite,Android,Sqlite,我在这里搜索了很多答案,但都使用FileInputStream和FileOutputStream来备份数据库 当您将PRAGMA语句与journal\u mode=WAL(预写日志记录)、异步模式等一起使用时,文件复制失败 如何备份/导出/快照android上以WAL模式运行的sqlite数据库 文件副本不可能是正确的方法。sqlite中必须有一些备份/导出命令可用(通过sqlite命令shell可以使用它) 到目前为止,我还没有找到解决办法。非常感谢您的帮助 在使用PRAGMA语句时,文件复制

我在这里搜索了很多答案,但都使用
FileInputStream
FileOutputStream
来备份数据库

当您将
PRAGMA
语句与
journal\u mode=WAL
(预写日志记录)、异步模式等一起使用时,文件复制失败

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

文件副本不可能是正确的方法。sqlite中必须有一些备份/导出命令可用(通过sqlite命令shell可以使用它)

到目前为止,我还没有找到解决办法。非常感谢您的帮助

在使用PRAGMA语句时,文件复制失败 日志模式=WAL(预写日志记录)、异步模式等

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

给你

这是一个在WAL模式下检查数据库的方法示例(在日志模式可以是Android默认模式的情况下使用):-

  • 注意:在上面的示例中,数据库名称是通过常量DBConstants.DATABSENAME获得(解析)的,这将是一个简单的签名更改,以允许传递数据库名称

我认为Android绑定不支持sqlite的备份API,这很不幸。(大多数语言的sqlite绑定似乎只支持原生C API中可用功能的一小部分)。最新版本支持将
真空导入
作为备份的另一种方式,但sqlite库的Android版本可能也不够新。Android上最好的方法可能是将日志模式改回
DELETE
,执行
beginimmediate
,以获得数据库的独占锁,这样在复制过程中就不会有任何更改,然后复制文件。
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();
}