objectbox-java icon indicating copy to clipboard operation
objectbox-java copied to clipboard

FileCorruptException: Corrupt DB, min key size violated: 0

Open Elih96 opened this issue 3 years ago • 3 comments

Describe the bug We sporadically receive complaints from users, upon checking logs, queries on specific boxes seem to be throwing a "FileCorruptException: Corrupt DB, min key size violated: 0". While all other queries work fine, I just need to understand under what circumstance this exception gets thrown and how best to go about dealing with the issue as I couldn't find any documentation about this specific exception and couldn't find a replication scenario.

Basic info (please complete the following information):

  • ObjectBox version (are you using the latest version?): 3.2.0
  • Reproducibility: occasionally without visible pattern
  • Device: No specific device, observed on multiple different devices through app logs
  • OS: same as above

Code No specific area where this happens, but one of the examples is as follows:

private fun fillFromDb(store: BoxStore, toFind: Collection<String>) {
  store.boxFor(StoredSong::class.java)
    .query()
    .inValues(StoredSong_.id, toFind.toTypedArray(), QueryBuilder.StringOrder.CASE_INSENSITIVE)
    .build()
    .find()

Logs, stack traces

at io.objectbox.BoxStore.v(BoxStore.java:17)
	at io.objectbox.BoxStore.A(BoxStore.java:1)
	at io.objectbox.query.Query.B(Query.java:2)
	at io.objectbox.query.Query.k0(Query.java:1)
	at com.anghami.ghost.local.StoredSongLookupKt.fillFromDb(StoredSongLookup.kt:8)
	at com.anghami.ghost.local.StoredSongLookupKt.lookupSongs$lambda-4(StoredSongLookup.kt:1)
	at com.anghami.ghost.local.StoredSongLookupKt.a(Unknown Source:0)
	at com.anghami.ghost.local.g.call(Unknown Source:2)
	at com.anghami.ghost.objectbox.BoxAccess$3$1.call(BoxAccess.java:1)
	at io.objectbox.BoxStore.v(BoxStore.java:16)
	... 24 more
Caused by: io.objectbox.exception.FileCorruptException: Corrupt DB, min key size violated: 0
	at io.objectbox.query.Query.nativeFind(Native Method)
	at io.objectbox.query.Query.F0(Query.java:1)
	at io.objectbox.query.Query.n(Unknown Source:0)
	at io.objectbox.query.g.call(Unknown Source:2)
	at io.objectbox.BoxStore.v(BoxStore.java:16)

Elih96 avatar Aug 10 '22 09:08 Elih96

Thanks for reporting! I guess this is on Android devices only?

Anyhow, it may be possible to detect issues and salvage the database file using some BoxStoreBuilder APIs: https://github.com/objectbox/objectbox-examples/blob/b3d5e3e8bfb8c9b2f48dde14e2965a328b4a45bb/android-app/src/main/java/io/objectbox/example/ObjectBox.java#L17-L28

If that won't work the last resort is to delete the database file.

The exception will happen on the first read/write access, e.g. put or get call or query find. Edit: it seems only on the affected box, not any box. See below.

greenrobot-team avatar Aug 16 '22 10:08 greenrobot-team

Thanks for the reply! Yeah, we're only observing this on Android.

The way we're handling database corruptions now is that upon building the default store, we're catching DbExceptions and trying to recover from that like so:

try {
    return storeBuilder.buildDefault();
} catch (DbException dbException) {
    // deleting and recreating the db
}

This works fine for corruption issues on initialization. Now if I understand correctly, adding the extra validations on open linked above should also help us catch the corruption issues happening on specific boxes.

If these issues are not detected on startup with the extra validations, then we should be handling this exception on the first read/write access where this happens (query x -> exception -> close the store -> delete/try to use a previous snapshot -> rebuild the store)

Elih96 avatar Aug 16 '22 11:08 Elih96

If these issues are not detected on startup with the extra validations

As you can see in the API docs validateOnOpen can be restricted to only check parts of the database (for performance reasons, e.g. checking a large database may take some time). In that case, it can make sense to guard any read/write access. Also, I have to correct myself. I'm not sure if the above error happens definitely on the first read/write access or only when accessing an affected box. @greenrobot

greenrobot-team avatar Aug 17 '22 08:08 greenrobot-team

Hello @greenrobot-team and @greenrobot !

I want to let you know that I have the same issue here for one of our user's database: When accessing a specific BoxStore this exception is thrown:

 io.objectbox.exception.FileCorruptException: Corrupt DB, min key size violated: 0
        at io.objectbox.query.Query.nativeFind(Native Method)

I added the call .validateOnOpen(ValidateOnOpenMode.Full) to the builder like suggested above, but it does not throw any exceptions. I can still open the database and query all other boxes, but for the one specific BoxStore it will always crash. I already tried boxStore.boxFor(Article::class.java).panicModeRemoveAll() but to no avail:

     Caused by: io.objectbox.exception.FileCorruptException: Corrupt DB, min key size violated: 0
        at io.objectbox.BoxStore.nativePanicModeRemoveAllObjects(Native Method)
        at io.objectbox.BoxStore.panicModeRemoveAllObjects(BoxStore.java:1241)
        at io.objectbox.Box.panicModeRemoveAll(Box.java:566)

Now I wonder if not all BoxStores are checked by validateOnOpen()? Can I customize what should be checked?

However usePreviousCommit() did not help in our case. So the user had to delete the database / reinstall the app.

How can the error be avoided for future users?

Is there any other way to fix the issue apart from deleting the database file?

I still have a copy of the database, so I can test any solutions you provide. (For privacy reasons I unfortunately can not share the file...)

sarn0ld avatar Mar 15 '23 14:03 sarn0ld

@sarn0ld Do you know which ObjectBox version created the DB file? May we assume that the current ObjectBox version fails with the same error on this file?

It's a pity that we cannot access the file. Would some NDA or the likes help?

greenrobot avatar Mar 16 '23 09:03 greenrobot

I don't know which version created the file in the beginning, but the error occured at the clientside with '3.2.1'. I did reproduce it with the same version.

I will ask the customer whether a NDA is ok and get back to you when i got an answer.

sarn0ld avatar Mar 17 '23 06:03 sarn0ld

@greenrobot I'm happy to inform you that the customer is okay with an NDA (if I'm deleting all personal content from the working box stores). I prepared a NDA. How can I reach you?

sarn0ld avatar Mar 21 '23 08:03 sarn0ld

Hi, this is Markus. You can reach me at "my first name" at objectbox. IO

greenrobot avatar Mar 27 '23 08:03 greenrobot

@sarn0ld I think I did not receive anything. Can you still share it?

greenrobot avatar Jun 02 '23 18:06 greenrobot

Without additional information, we are unfortunately not sure how to resolve this issue. Therefore this issue has been automatically closed. Feel free to comment with additional details and we can re-open this issue.

github-actions[bot] avatar Jun 27 '23 01:06 github-actions[bot]

To also mention this here, we have released 3.7.0 which has improvements to help diagnose this issue. See https://github.com/objectbox/objectbox-java/issues/1143#issuecomment-1689633405 for details.

greenrobot-team avatar Aug 23 '23 09:08 greenrobot-team

I have the same problem and I put the version 3.7.0 with validateOnOpen(ValidateOnOpenMode.Full) and it says: Caused by: io.objectbox.exception.FileCorruptException: Validating pages failed (corrupted) (error code -30796) at io.objectbox.BoxStore.nativeCreateWithFlatOptions(Native Method) at io.objectbox.BoxStore.(BoxStore.java:270) at io.objectbox.BoxStoreBuilder.build(BoxStoreBuilder.java:591) any idea to repair it? Thanks.

aespelt avatar Oct 09 '23 09:10 aespelt

@aespelt See the discussion in #1143. We propose a repair mode. Currently, the only available solution to fix corruption is to delete the database files.

greenrobot-team avatar Oct 09 '23 10:10 greenrobot-team