【问题标题】:How to manually perform checkpoint in SQLite android?如何在 SQLite android 中手动执行检查点?
【发布时间】:2018-07-26 09:13:41
【问题描述】:

我正在尝试创建我的 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] ,我还尝试 VACUUM 数据库,但似乎没有任何反应。

 public Completable vacuumDb() {
    return Completable.fromAction(new Action() {
        @Override
        public void run() throws Exception {
            getInstance(mContext).getReadableDatabase().execSQL("VACUUM");
        }
    });
} 
}

在创建备份之前刷新数据库中的 WAL 文件的正确方法是什么?

谢谢。

【问题讨论】:

  • 关于您第一次尝试使用 rawQuery,您需要执行 Cursor.moveToNext() 之类的操作才能使其真正运行。

标签: android sqlite mobile checkpoint


【解决方案1】:

PRAGMA wal_checkpoint(2) 确实将所有数据从 WAL 复制到实际的数据库文件中,但它不会删除 -wal 文件,并且任何并发连接都可以在之后立即进行新的更改。

如果您想确定没有 WAL 干扰您的备份,请运行 PRAGMA journal_mode = DELETE。 (之后可以切换回来。)

【讨论】:

    猜你喜欢
    • 2011-08-28
    • 2010-11-17
    • 2023-03-22
    • 1970-01-01
    • 2013-06-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多