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.
--
Hallvard