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