【问题标题】:When create backup of sqlite database created old file in android pie?什么时候创建sqlite数据库的备份在android pie中创建了旧文件?
【发布时间】:2019-09-11 02:46:41
【问题描述】:

我有用于备份创建本地 sqlite 文件的代码。较低的 API 28 可以正常工作,但高于 >= 28 会导致创建备份文件的问题。当我创建备份文件时,它创建的是旧数据文件而不是更新数据,而是在应用程序中显示更新的数据。

public void writeBackupOnSD() {
    try {
        File newFolder = new File(Environment.getExternalStorageDirectory(), "Account_Manager");
        if (!newFolder.exists()) {
            boolean isCreated = newFolder.mkdir();
            Log.d("File", "status" + isCreated);
        }
        File file = new File(newFolder, backupFileName);//custom file name save on sd


        String outFileName = file.getPath();
        String inputFileName = getApplicationContext().getFilesDir().getPath()+ "/" + AppConstant.DATABASE_NAME;

        if(checkDatabase(inputFileName)) {
            FileInputStream myInput = new FileInputStream(new File(inputFileName));
            FileOutputStream myOutput = new FileOutputStream(outFileName);

            FileChannel src = myInput.getChannel();
            FileChannel dst = myOutput.getChannel();
            dst.transferFrom(src, 0, src.size());
            src.close();
            dst.close();

            showMessage("Backup successfully!");
        }
    } catch (Exception e) {
        e.printStackTrace();
        showMessage("Failed to backup!");
    }
}

【问题讨论】:

  • 你不能随意复制一个打开的、正在使用的 sqlite 数据库文件而不会有数据丢失甚至损坏的风险。不幸的是,Android 没有导出应该用于以编程方式进行备份的官方备份 api。
  • 我已经在 getFileDir() 中创建了本地文件,并且对该文件进行了所有操作并进行备份,只是复制了该文件,但仍显示最新内容,但是当复制该文件时,该复制文件与旧数据。跨度>
  • 最好的办法是先优雅地关闭到数据库文件的所有连接。如果你不能这样做,sqlite.org/…sqlite.org/backup.html 提到一些其他选项。

标签: android sqlite android-studio android-sqlite


【解决方案1】:

对于 Android Pie 及更高版本,默认日志记录模式已从日志模式更改为 WAL(预写日志记录)。 在日志模式下,事务被提交并写入磁盘上的 db 文件,并且它们的记录保存在日志中,允许事务回滚。

使用 WAL,事务被写入一个单独的文件(以 -wal 为后缀的 db 文件),wal 文件只是偶尔写入磁盘(检查点),但就像它是数据库文件的一部分一样可用。不需要回滚,因为基本上 -wal 文件都可以删除。

如果你不检查点数据库(关闭数据库应该检查点它)并且你不备份(和恢复)一个没有检查点的数据库以及 –wal 文件(以及正确的 –shm 文件)然后您丢失了事务,基本上在尝试打开数据库时可能会出现问题。 SQLitedatabase 打开方法然后尝试提供一个可用的数据库,它是空的。

有各种修复:-

使用disableWriteAheadLogging 强制使用日志模式(不推荐,因为您失去了WAL 提供的优势)。

备份和恢复 -wal 和 -shm 文件以及数据库文件。

在备份之前完全检查数据库,因此不需要备份 -wal 和 -shm 文件。 - 注意关闭数据库应该完全检查数据库。 - 这里的答案显示了如何以编程方式检查点Backup sqlite db in WAL mode without FileStreams // by export/backup sql commands

【讨论】:

  • 谢谢,disableWriteAheadLogging() 正是我所需要的。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-04-03
  • 1970-01-01
  • 2010-09-22
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多