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

Re: [lmdb] MDB_BAD_RSLOT for mdb_txn_get()



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