SQLite "database disk image is malformed"

Batnom picture Batnom · Mar 25, 2014 · Viewed 35.1k times · Source

I am having trouble with an app where the SQLite database is getting corrupted. There was the odd case of this previously, but it seems to have become a lot more common after the release of iOS 7.1.

I'm using the SQLite wrapper by Matteo Bertozzi that you can find here: https://github.com/ConnorD/simple-sqlite

The database gets corrupted and spits out the error database disk image is malformed, some queries can be run but the existing data gets messed up.

I have searched high and low and can't find a solution, I'm hoping someone here has some ideas since this is becoming a more common issue after the iOS update.

I've tried these repair commands:

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

And the output was:

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`

With some further digging I found this problem: Core Data and iOS 7: Different behavior of persistent store which mentions issues with SQLite after iOS7.

Though I have no idea how to use NSPersistentStore, so I tried running [sqlite executeNonQuery:@"pragma journal_mode = DELETE"]; and it just said SQLite Step Failed: unknown error.

Is anyone else experiencing this, or point me in the right direction?

In the meantime I feel like this NSPersistentStore is something I potentially should be doing.. will have to look into that.

edit:

From what I've found you only use NSPersistentStore when the database isn't going to be updated, which mine is regularly.

Here is how I open the database:

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");
}

So I assume I need to find a way to set pragma journal_mode = DELETE this way..?

edit 2:

I'm not convinced it's to do with the journal_mode as I'm not using Core Data - back to the drawing board.

The biggest flag to me is this error popping up so soon after iOs 7.1 was released, surely it can't be a coincidence.. I'll continue trying to replicate the issue on my device.

Answer

malhal picture malhal · May 28, 2014

I had this problem too on iOS 7.0.6 using FMDB. I repaired it by copying to the Mac and using these commands:

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

My database dump was rather large at 200MB so I used Hexfiend to cut the transaction and rollback commands.