我在这里搜索了很多答案,但都使用FileInputStream和FileOutputStream备份数据库。
当您将PRAGMA语句与journal_mode=WAL (写前日志)、异步模式等一起使用时,文件副本就会失败。
如何备份/导出/快照运行在android上WAL模式下的sqlite数据库?
文件副本不可能是正确的方法。在sqlite中必须有一些可用的备份/导出命令(好吧,是通过sqlite提供的)。
到目前为止,我还没有找到解决办法。任何帮助都非常感谢。
发布于 2019-03-29 20:03:27
当您将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();
}https://stackoverflow.com/questions/55415132
复制相似问题