18

在 WWDC 2013 会议 '207: What's New in Core Data' 中,他们提到您可以通过在添加持久存储时传递选项字典来启用 SQLite WAL:

@{ NSSQLitePragmasOption: @"journal_mode = WAL" }

(在 iOS4+ 上可用,并将成为未来 iOS 版本的默认设置)。

我想知道在我的应用程序中为早期 iOS 版本启用这通常是否是一件好事。

我已经查阅了关于预写日志记录的 SQLite 页面以及他们提到的缺点,其中大多数似乎不适用于 iOS,除了:

  • 在主要进行读取而很少写入的应用程序中,WAL 可能比传统的回滚日志方法慢得多(可能慢 1% 或 2%)。

几乎所有的优势听起来都像是对 iOS 的好处:

  • 在大多数情况下,WAL 明显更快。
  • WAL 提供了更多的并发性,因为读取器不会阻塞写入器,写入器不会阻塞读取器。读和写可以同时进行。
  • 使用 WAL 的磁盘 I/O 操作往往更具顺序性。
  • WAL 使用更少的 fsync() 操作,因此在 fsync() 系统调用被破坏的系统上不易受到问题的影响。

我假设(可能需要对我的应用程序进行一些检查以确保它不会减慢速度)这将是一件好事,但是我应该注意什么缺点或任何已知问题?

4

2 回答 2

18

http://pablin.org/2013/05/24/problems-with-core-data-migration-manager-and-journal-mode-wal/表明它们可能是迁移的问题,特别是:

当您使用迁移管理器时,Core Data 将为您创建一个新数据库,并开始将实体从旧数据库一一复制到新数据库。

当我们使用 journal_mode = WAL 时,除了 DB.sqlite 之外,还有一个名为 DB.sqlite-wal 的附加文件。

据我所知,问题似乎是Core Data创建了一个临时数据库,在那里插入所有内容,当它重命名为原始名称时,-wal文件作为旧版本的剩余文件保留。问题是你最终得到一个不一致的数据库。

(在https://github.com/magicalpanda/MagicalRecord/issues/490上也提到过- 这表明如果您使用魔法记录,那么它已经默认为 WAL )

于 2013-07-05T11:02:26.337 回答
2

关于涉及子类化 NSMigrationManager 的非轻量级迁移发生的错误,我已将其作为错误 16038419 重新报告给 Apple。

我还提出了一种不同的、方法混乱的解决方法,它在您总是想使用旧的删除/回滚日志的情况下修补错误。据我了解,Pablin 的修复适用于您想要使用 WAL 的情况,但在迁移期间除外。此外,您可以在此视频中看到该错误。

于 2014-02-11T19:12:19.520 回答