[Date Prev][Date Next] [Chronological] [Thread] [Top]

[lmdb] MDB_BAD_DBI error upon mdb_txn_commit (newbie question)



Dear list,

I am new to lmdb and my apologies if this is on something obvious.

I encountered the MDB_BAD_DBI error in a simple single process, multi-threaded program using lmdb. The scenario is :

* One thread doing a relatively long write transaction
mdb_txn_begin -> mdb_dbi_open on several database -> (write) -> mdb_txn_commit

* Another thread (or other threads) of the same process doing short read-only transactions mdb_txn_begin -> mdb_dbi_open on some of the database above -> (read) -> mdb_txn_commit

As per the advice in the document I do not close the database directly. Also the environment created / opened is shared by all threads, being in the same process.

All is fine when these threads execute separately, but if the read transaction thread(s) open the database and commit within the time span of the write transaction in another thread, the above error occurs upon attempt to commit the write transaction.

I have done a search on the MDB_BAD_DBI error and noticed the commit below.

https://gitorious.org/mdb/mdb/commit/0401f2deed75a83d2de790b8a1313e1792e5a04f

Upon a brief look into this and the source of lmdb, my understanding is that the error is due to the increment of lmdb's internal sequence numbers of the database kept by the environment (by the read thread when the read transaction commits). When the write thread subsequently tries to commit, the database sequence number kept privately by the write transaction (copied from the environment when the transaction began) does not match that of the environment, causing the error.

To avoid this in a single process multi-threaded environment, it seems that no read transactions could commit on databases while they are involved in a write transaction, i.e. I need to complete all read transactions before a write transaction on the same database could begin. Alternatively, to have concurrent read transactions with a write transaction, the read transactions have to take place in a separate process (such that they would not share the same environment and caught by the above error).

Grateful if anyone could kindly enlighten me on whether the understanding is correct, or if I am doing something contrary to the how lmdb should be used.

Thank you very much.

- H Law