objectbox / objectbox-java

Android Database - first and fast, lightweight on-device vector database
https://objectbox.io
Apache License 2.0
4.39k stars 302 forks source link

Could not open database environment(error code 11) #991

Open 15915763299 opened 3 years ago

15915763299 commented 3 years ago

How could I fix this crash? When I build many of BoxStore, about 60 or more, it always crash

Caused by: io.objectbox.exception.DbException: Could not open database environment; please check options and file system (11: Try again) (error code 11) at io.objectbox.BoxStore.nativeCreateWithFlatOptions(Native Method) at io.objectbox.BoxStore.(BoxStore.java:264) at io.objectbox.BoxStoreBuilder.build(BoxStoreBuilder.java:498)

greenrobot commented 3 years ago

You are opening BoxStore all at the same time or one at a time? Either way, that's not a typical usage pattern. What are you trying to achieve? I guess this is Android?

15915763299 commented 3 years ago

You are opening BoxStore all at the same time or one at a time? Either way, that's not a typical usage pattern. What are you trying to achieve? I guess this is Android?

Yes, it's android. I want to split table for faster query, because one user may have huge data of messages ( Our app is chat app ). But ObjectBox can't split table, so i split database. I put messages in 50 databases, I use multi-thread to create them, but I also use "lock" wrap the create logic.

15915763299 commented 3 years ago

Here is stack info: io.objectbox.BoxStore.nativeCreateWithFlatOptions(Native Method) io.objectbox.BoxStore.(BoxStore.java:17) l.b.d.b(BoxStoreBuilder.java:5)

There are 4 thread with name of "ObjectBox",here is their names

ObjectBox-86-Thread-1(10430)

ObjectBox-29-Thread-46(10539)

ObjectBox-44-Thread-3(10545)

ObjectBox-49-Thread-4(10549)

And they have same stack info: java.lang.Object.wait(Native Method) java.lang.Thread.parkFor$(Thread.java:2127) sun.misc.Unsafe.park(Unsafe.java:325) java.util.concurrent.locks.LockSupport.parkNanos(LockSupport.java:201) java.util.concurrent.SynchronousQueue$TransferStack.awaitFulfill(SynchronousQueue.java:432) java.util.concurrent.SynchronousQueue$TransferStack.transfer(SynchronousQueue.java:333) java.util.concurrent.SynchronousQueue.poll(SynchronousQueue.java:908) java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:1057) java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1118) java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:607) java.lang.Thread.run(Thread.java:761)

greenrobot commented 3 years ago

It would not be surprising if you run into some Android system limits with that many DBs. I would suggest to try alternative solutions.

I want to split table for faster query

Can you tell us about the query? Does is use indexed properties?

PS.: the stack trace shows an idle thread waiting for work.

15915763299 commented 3 years ago

It would not be surprising if you run into some Android system limits with that many DBs. I would suggest to try alternative solutions.

I want to split table for faster query

Can you tell us about the query? Does is use indexed properties?

PS.: the stack trace shows an idle thread waiting for work.

Yes, there are two properties use "@index". The query just like this:

fun conversation(conversationKey: String) = objectBox.boxFor(ConversationEntity::class) .query() .equal(ConversationEntity_.conversationKey, conversationKey) .build() .findFirst()

greenrobot commented 3 years ago

.equal(ConversationEntity_.conversationKey, conversationKey)

If you check the docs for string equality condition, you will see a note on case. If it's possible for your use case, use this instead: equal(prop, "example", StringOrder.CASE_SENSITIVE). The default without StringOrder.CASE_SENSITIVE cannot use the index (default will be changed in V3).