首页 > 解决方案 > 删除临时房间 sqlite 文件?

问题描述

我的 android 应用程序中有一个数据库,但每次我尝试更新它(写入它)时,都会创建两个额外的文件shmwal. wal即使我将相同的数据插入数据库,该文件也变得越来越大,当我尝试获取最后修改时间时,它也让我感到困扰,数据只写入wal文件而不是实际的数据库。

我的问题是如何强制它将数据写入数据库并在每次更新后删除临时文件?

标签: androidsqliteandroid-sqliteandroid-room

解决方案


我的问题是如何强制它将数据写入数据库并在每次更新后删除临时文件?

是的,您可以强制/启动检查点。

关闭数据库/连接应该检查它,但在资源方面可能代价高昂(因为您必须重新打开它)。

或者,您可以使用:-

PRAGMA wal_checkpoint(TRUNCATE)

但是,您应该考虑使用

PRAGMA wal_checkpoint 

在截断之前和之后查看 WAL 是否忙/检查点完成所有操作(如果您采用它,您可能希望修改下面的示例以检查值 wal_busy 等(示例来自数据库备份并且数据库已关闭)反正))。

wal_checkpoint pragma 返回包含三个整数列的单行。第一列通常为 0,但如果 R​​ESTART、FULL 或 TRUNCATE 检查点被阻止完成,则为 1

我建议阅读预写日志PRAGMA 语句 - PRAGMA schema.wal_checkpoint;

当我尝试获取最后修改时间时,数据仅写入 wal 文件而不是实际数据库。

-wal 文件被视为数据库,并像数据库一样被读取/更新,因此如果更改在 -wal 文件中,则从 -wal 文件中提取任何更改。SQLite 非常安全/坚固。

例子

以下是检查点的示例:-

public static int checkpointDB(SupportSQLiteDatabase db) {

    String TAG = "CHECKPOINTDB";
    int wal_busy = 99, wal_log = 99, wal_checkpointed =99;

    Cursor csr = db.query("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.query("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.query("PRAGMA wal_checkpoint(TRUNCATE)", null);
            csr.getCount();
            csr = db.query("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();
    return wal_busy;
}

它可以被调用,(其中mPDB是构建的PersonDatabase对象,上面是在PersonDatabase (@Database) 类中),使用类似的东西:-

PersonDatabase.checkpointDB(mPDB.getOpenHelper().getWritableDatabase());

示例用法导致:-

2019-07-13 08:15:54.997 18556-18556/s.e.s56720641roomwithmanytomany D/CHECKPOINTDB: Mode is wal
2019-07-13 08:15:54.997 18556-18556/s.e.s56720641roomwithmanytomany D/CHECKPOINTDB: Checkpoint pre checkpointing Busy = 0 LOG = 0 CHECKPOINTED = 0
2019-07-13 08:15:55.000 18556-18556/s.e.s56720641roomwithmanytomany D/CHECKPOINTDB: Checkpoint post checkpointing Busy = 0 LOG = 0 CHECKPOINTED = 0

导致 :-

在此处输入图像描述


推荐阅读