【问题标题】:Android Room - How to perform VACUUM after performing massive table migration?Android Room - 执行海量表迁移后如何执行 VACUUM?
【发布时间】:2020-12-02 06:10:15
【问题描述】:

我们执行了大规模的数据库表迁移。

public class Migration_22_23 extends Migration {
    public Migration_22_23() {
        super(22, 23);
    }

    // (1) Change `type` INTEGER to `type` INTEGER NOT NULL
    // (2) Change `reminder_type` INTEGER to `reminder_type` INTEGER NOT NULL
    // (3) Change `reminder_repeat` INTEGER to `reminder_repeat` INTEGER NOT NULL
    // (4) Change `reminder_day_of_week_bitwise` INTEGER to `reminder_day_of_week_bitwise` INTEGER NOT NULL
    // (5) Change `uuid` TEXT to `uuid` TEXT NOT NULL
    // (6) Change CREATE INDEX `index_plain_note_uuid` ON `plain_note` (`uuid`) to CREATE UNIQUE INDEX `index_plain_note_uuid` ON `plain_note` (`uuid`)
    // (7) Drop column `theme`
    // (8) Drop column `key`
    @Override
    public void migrate(@NonNull SupportSQLiteDatabase database) {
        ...

        // Reclaim disk space.
        database.execSQL("VACUUM");
    }
}

在迁移结束时,我们希望执行一次VACUUM 以回收磁盘空间。

但是,我们会收到以下运行时错误。

Cannot vacuum from within a transaction

您知道我们有什么安全的方法来清理数据库,以便我们可以回收磁盘空间吗?

【问题讨论】:

    标签: android sqlite android-room


    【解决方案1】:

    这是可能的方法之一。

    public abstract class MyRoomDatabase extends RoomDatabase {
        public static MyRoomDatabase instance() {
            if (INSTANCE == null) {
                synchronized (MyRoomDatabase.class) {
                    if (INSTANCE == null) {
                        INSTANCE = Room.databaseBuilder(
                            MyApplication.instance(),
                            MyRoomDatabase.class,
                            NAME
                        )
                            .addMigrations(new Migration_1_2())
                            ...
                            .addCallback(getCallback())
                            .build();
                    }
                }
            }
    
            return INSTANCE;
        }
    
        private static RoomDatabase.Callback getCallback() {
            return new RoomDatabase.Callback() {
                @Override
                public void onOpen(@NonNull SupportSQLiteDatabase db) {
                    super.onOpen(db);
    
                    if (shouldVacuum()) {
                        try {
                            db.execSQL("VACUUM");
                        } catch (Exception e) {
                            Log.e(TAG, "", e);
                        }
    
                        resetShouldVacuum();
                    }
                }
            };
        }
    }
    

    shouldVacuumresetShouldVacuum指的是全局静态变量,在Migration_1_2中开启

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2018-11-15
      • 1970-01-01
      • 2013-02-15
      • 2018-04-09
      • 2015-01-26
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多