我正在尝试创建sqlite数据库的备份,我想首先刷新数据库中WAL文件的内容。
这是我的SQLiteOpenHelper:
public class MyDBHelper extends SQLiteOpenHelper {
private Context mContext;
private static MyDBHelper mInstance = null;
private MyDBHelper(final Context context, String databaseName) {
super(new MYDB(context), databaseName, null, DATABASE_VERSION);
this.mContext = context;
}
@Override
public void onCreate(SQLiteDatabase db) {
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
}
public static MyDBHelper getInstance(Context context) {
if (mInstance == null) {
mInstance = new MyDBHelper(context, DATABASE_NAME);
}
return mInstance;
}
private void closeDataBase(Context context) {
getInstance(context).close();
}
}
现在,我的理解是,在检查点完成后,mydb.db-wal文件应该是空的。这是正确的吗?
以下是我迄今为止所做的尝试:1.
public Completable flushWalInDB() {
return Completable.fromAction(new Action() {
@Override
public void run() throws Exception {
getInstance(mContext).getReadableDatabase().rawQuery("pragma wal_checkpoint;", null);
}
});
}
这不会引发错误,但似乎没有任何作用。运行此程序后,我对mydb.db-wal文件进行了物理检查,结果大小相同。我还检查了设备上的数据库,数据库中没有添加任何内容
经过一番挖掘,我发现了这个[https://stackoverflow.com/a/30278485/2610933][1]并尝试了这个:
2.
public Completable flushWalInDB() {
return Completable.fromAction(new Action() {
@Override
public void run() throws Exception {
getInstance(mContext).getReadableDatabase().execSQL("pragma wal_checkpoint;");
}
});
}
当运行此程序时,它会抛出一个错误:
unknown error (code 0): Queries can be performed using SQLiteDatabase query or rawQuery methods only.
基于这个答案[https://stackoverflow.com/a/19574341/2610933][1] ,我也尝试过真空DB,但似乎什么都没发生。
public Completable vacuumDb() {
return Completable.fromAction(new Action() {
@Override
public void run() throws Exception {
getInstance(mContext).getReadableDatabase().execSQL("VACUUM");
}
});
}
}
在创建备份之前,在数据库中刷新WAL文件的正确方法是什么?
谢谢。
PRAGMA wal_checkpoint(2)
确实将WAL中的所有数据复制到实际的数据库文件中,但它不会删除-wal
文件,并且任何并发连接都可以在之后进行新的更改。
如果您想真正确保没有WAL干扰您的备份,请运行PRAGMA journal_mode=DELETE。(之后你可以切换回来。(
要手动添加检查点,请使用PRAGMA wal_checkpoint,搜索2小时后,以下代码对我有效-:
SQLiteDatabase db = this.getWritableDatabase();
String query = "PRAGMA wal_checkpoint(full)";
Cursor cursor = db.rawQuery(query, null);
if (cursor != null && cursor.moveToFirst()) {
int a = cursor.getInt(0);
int b = cursor.getInt(1);
int c = cursor.getInt(2);
}
if (cursor != null) {
cursor.close();
}