SQLite“数据库磁盘映像格式错误”

Posted

技术标签:

【中文标题】SQLite“数据库磁盘映像格式错误”【英文标题】:SQLite "database disk image is malformed" 【发布时间】:2014-05-02 15:55:19 【问题描述】:

我在使用 SQLite 数据库损坏的应用时遇到问题。以前有这种奇怪的情况,但在 ios 7.1 发布后似乎变得更加普遍。

我正在使用 Matteo Bertozzi 的 SQLite 包装器,您可以在此处找到:https://github.com/ConnorD/simple-sqlite

数据库损坏并吐出错误database disk image is malformed,可以运行一些查询但现有数据被弄乱了。

我已经搜索了高和低,但找不到解决方案,我希望这里的人有一些想法,因为这在 iOS 更新后成为一个更常见的问题。

我试过这些修复命令:

[sqlite executeNonQuery:@"pragma integrity_check"];
[sqlite executeNonQuery:@"reindex nodes"];
[sqlite executeNonQuery:@"reindex pristine"];

输出是:

SQLite Step Failed: database disk image is malformed
SQLite Prepare Failed: unable to identify the object to be reindexed
 - Query: reindex nodes
SQLite Prepare Failed: unable to identify the object to be reindexed
 - Query: reindex pristine`

经过进一步挖掘,我发现了这个问题:Core Data and iOS 7: Different behavior of persistent store,其中提到了 iOS7 之后的 SQLite 问题。

虽然我不知道如何使用NSPersistentStore,所以我尝试运行[sqlite executeNonQuery:@"pragma journal_mode = DELETE"];,它只是说SQLite Step Failed: unknown error

有没有其他人遇到过这种情况,或者指出我正确的方向?

与此同时,我觉得 NSPersistentStore 是我可能应该做的事情.. 必须对此进行调查。

编辑:

据我发现,您只在数据库不更新时才使用NSPersistentStore,而我的数据库是定期更新的。

这是我打开数据库的方法:

sqlite = [[Sqlite alloc] init];

NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *writableDBPath = [documentsDirectory stringByAppendingPathComponent:@"HomeOpenDatabase8.sql"];

if (![sqlite open:writableDBPath]) 
    NSLog(@"DB Not Writable");
    return;
 else 
    NSLog(@"All good");

所以我假设我需要找到一种方法来设置pragma journal_mode = DELETE 这种方式..?

编辑 2:

我不相信这与 journal_mode 有关,因为我没有使用 Core Data - 回到绘图板。

对我来说最大的问题是这个错误在 iOs 7.1 发布后不久就出现了,这肯定不是巧合。我会继续尝试在我的设备上复制这个问题。

【问题讨论】:

您是否可以执行某些步骤来可靠地重现损坏? 我自己无法复制它,这是一个巨大的痛苦,但我会继续尝试。我不再相信它是journal_mode,因为我没有使用Core Data,所以它又回到了原点。 你为什么要搞乱编译指示? 我猜你不小心开始以多线程模式访问数据库。即使在“线程安全”的情况下,SQLite 实际上也无法处理完整的多线程——您至少必须提供外部同步以确保两个线程不会同时在数据库上运行。据我所知,所有“线程安全”所做的都是启用检查,如果您尝试同时访问,通常会抛出错误。 你是对的。我为我的数据库服务添加了锁定,以仅通过一个线程访问 SQLite DB,它现在可以工作了。 【参考方案1】:

我在使用 FMDB 的 iOS 7.0.6 上也遇到了这个问题。我通过复制到 Mac 并使用以下命令对其进行了修复:

http://www.dosomethinghere.com/2013/02/20/fixing-the-sqlite-error-the-database-disk-image-is-malformed/

我的数据库转储相当大,有 200MB,所以我使用 Hexfiend 来切断事务和回滚命令。

【讨论】:

你是如何将 DB 文件从 iPhone 复制到 Mac 的? @de_la_vega_66 你可以通过 iTunes 或者如果你有 XCode,然后搜索“管理设备上的容器”:developer.apple.com/library/ios/recipes/…【参考方案2】:

sqlite: database disk image is malformed

在您的情况下,您可以考虑检查您的完整性检查结果。这就是我解决问题的方法。

【讨论】:

以上是关于SQLite“数据库磁盘映像格式错误”的主要内容,如果未能解决你的问题,请参考以下文章

为啥我不断获取数据库磁盘映像在 android studio 上格式错误

NSInternalInconsistencyException:数据库磁盘映像格式错误

(私人收藏)SQLite 全面手册以及教程

玩转SQLite系列SQLite数据库应用案例实现历史搜索记录

玩转SQLite系列通过sql语句操作SQLite数据库

玩转SQLite系列SQLite数据库应用案例实现历史搜索记录