在 iOS 中使用 SQLite PRAGMA synchronous = OFF 和 journal_mode = MEMORY 进行更新的最坏情况行为

Worst case behavior for updates using SQLite PRAGMA synchronous = OFF and journal_mode = MEMORY in iOS

通过同时使用 synchronous=OFF 和 journal_mode=MEMORY 选项,我能够将更新速度从 15 毫秒降低到大约 2 毫秒,这是一个重大的性能改进。这些更新一次发生一个,因此许多其他优化(比如使用关于一堆更新的事务)不适用。

根据 SQLite 文档,如果出现某种类型的断电,在最坏的情况下,数据库可能会 'corrupt'。然而,可能发生的最糟糕的事情并不是数据丢失,或者可能是交易的一部分丢失(我猜这是一种损坏形式)。这些选项中的任何一个真的有可能发生任意腐败吗?如果是,为什么?

我没有使用任何事务,所以从事务中部分写入的数据不是问题,而且我可以处理丢失的数据。但是,如果 'corruption' 意味着数据库中的所有数据都可以以不可预测的方式随机更改,那将是不使用这些选项的有力理由。

有谁知道 iOS 上真正最坏的情况是什么?

表以 rowid 为键组织为 B 树。 如果在 SQLite 更新树结构时一些写入丢失,整个 table 可能变得不可读。 (索引也可能发生同样的情况,但可以简单地删除并重新创建。)

数据按页面组织(通常为 1 KB 或 4 KB)。如果在重组某些树时丢失了某些页面更新,则这些页面中的所有数据(即 table 中具有附近 rowid 值的一些随机行)可能会损坏。

如果 SQLite 需要分配一个新页面,并且该页面包含合理的数据(例如,从同一 table 中删除的数据),并且该页面的写入丢失,那么您的数据不正确table,无法检测到它。