Ben Johnson writes:
{Rearranging a bit}
Am I doing something wrong with how I'm creating read-only transactions?
Maybe this, from Caveats: * - A thread can only use one transaction at a time, plus any child * transactions. Each transaction belongs to one thread. See below. * The #MDB_NOTLS flag changes this for read-only transactions.
I'm using the gomdb interface so I'll do my best to translate this to the C calls. I'm performing an mdb_txn_put(), committing the transaction and then later I'm opening a new read-only transaction where I do an mdb_txn_get() and I receive a "MDB_BAD_RSLOT: Invalid reuse of reader locktable slot" error.
Possibly you (or Go) should use the recently added MDB_NOTLS environment flag. Either that, or you are breaking some "Restrictions/caveats" listed in the doc (ldmb.h). If Go is garbage-collected and trusts GC to end the transaction, for example.
When I switch the second transaction to not be read-only then the error goes away and it works fine. I checked the LMDB code and on line 1798, it's checking:
if (r->mr_pid != env->me_pid || r->mr_txnid != (txnid_t)-1) return MDB_BAD_RSLOT;
The r->mr_pid == env->me_pid (I'm only running one process) and the r->mr_txnid is 0
mr_txnid = 0 supposedly "cannot happen" at that point, unless you break some Caveats. Or maybe if you have a platform which does not give the unified buffer cache (and memory coherence?) which mdb expects. Which OS/platform is this?
and the txnid_t is 0 (so the txnid_t - 1 is -1).
No, txnid_t is a type. (txnid_t)-1 means -1 converted to txnid_t, which wraps around to the max possible value since it is txnid_t is unsigned.