【问题标题】:Backing up .sqlite (Core Data)备份 .sqlite(核心数据)
【发布时间】:2014-05-30 05:10:57
【问题描述】:

我有一个基于核心数据的应用程序,它使用 Dropbox 来备份和恢复数据。我备份的方式非常简单。我将 .sqlite 文件复制到用户的保管箱中。

现在我的备份和恢复功能运行良好。问题在于 .sqlite 文件本身。 .sqlite 文件似乎不完整

我在我的应用程序中输入了大约 125 个条目并进行了备份。备份出现在我的保管箱中,但是当我使用 .sqlite 资源管理器工具查看内容时,我只能看到第 117 个条目的记录。

我尝试更新第一个条目,然后再次观察 .sqlite 文件但没有再次更改。

更奇怪的是,该应用似乎记录了所有更改。当我添加新条目或更新现有条目并重新启动应用程序时,新添加的数据似乎仍然存在。 但是这个新添加的数据并没有出现在我的 .sqlite 文件中。

我正在使用此代码进行备份:

AppDelegate *appDelegate = [[UIApplication sharedApplication] delegate];
NSString *filePath = [[[appDelegate applicationDocumentsDirectory] path] stringByAppendingPathComponent:@"MyApp.sqlite"];


if (account) {
    if ([filesystem isShutDown]) {
        filesystem = [[DBFilesystem alloc] initWithAccount:account];
        [DBFilesystem setSharedFilesystem:filesystem];
    }

    DBPath *newPath = [[DBPath root] childPath:[NSString stringWithFormat:@"Backup - %@.sqlite", [NSDate date]]];
    DBFile *file = [[DBFilesystem sharedFilesystem] createFile:newPath error:nil];
    [file writeContentsOfFile:filePath shouldSteal:NO error:nil];
    [filesystem shutDown];

}

我还从模拟器的文件夹中复制了 .sqlite 文件,并尝试在 .sqlite 浏览器中查看它。它仍然表现出相同的行为。为什么一定会发生这种情况?

【问题讨论】:

    标签: ios objective-c database sqlite core-data


    【解决方案1】:

    从 iOS 7 / OS X 10.9 开始,Core Data 默认使用“Write-Ahead Logging”(WAL) 底层 SQLite 存储文件的日志模式。这在

    中有解释

    Technical Q&A QA1809: New default journaling mode for Core Data SQLite stores in iOS 7 and OS X Mavericks

    使用 WAL 模式,Core Data 保持主存储文件不变,并且 将事务附加到同一位置的 -wal 文件。之后 Core Data 上下文被保存,-wal 文件没有被删除,数据 在该文件中也不会合并到存储文件中。因此,简单地 复制存储文件可能会导致数据丢失和 不一致。

    这应该可以解释为什么您的 .sqlite 文件本身是不完整的。 作为解决方案,您可以(也在该技术说明中解释):

    • 通过设置为 SQLite 存储禁用 WAL 模式(并使用“旧”回滚日志模式)

      @{NSSQLitePragmasOption:@{@"journal_mode":@"DELETE"}};
      

      添加持久存储时的选项,或

    • 使用

      - (NSPersistentStore *)migratePersistentStore:(NSPersistentStore *)store toURL:(NSURL *)URL options:(NSDictionary *)options withType:(NSString *)storeType error:(NSError **)error
      

      制作 Core Data 存储备份副本的方法。

    【讨论】:

    • 那么你会推荐什么? Apple 推荐您的第二种方法,但我不明白如何将它与 Dropbox 一起使用(它看起来是为 iCloud 量身定制的)。如果我现在禁用 WAL 模式,我会丢失已经输入的数据吗?您如何看待使用 .sqlite 文件和 wal 文件创建一个 zip 文件并将其保存为备份(并进行反向恢复)?
    • @GauravWadhwani:在这个答案stackoverflow.com/a/21002923/1187415 中指出,使用 journal_mode=DELETE 打开商店不会破坏您的数据,但我自己没有测试过。使用第二种方法,您可能必须先备份到单独的(单文件)存储,然后您可以将其移动到保管箱(但我不熟悉保管箱功能)。 - 对不起,我不能给你推荐。也许会出现另一个答案并提供更多帮助。
    • 感谢您的回答。帮我解决了我的问题:)
    • @GauravWadhwani - 请您发布解决方案。我在使用 migratePersistentStore 时遇到了重大问题:
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-03-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-04-21
    • 2014-09-18
    • 1970-01-01
    相关资源
    最近更新 更多