(This is a quick follow-up to an earlier discussion, a note left for anyone confused by MDB_NOLOCK.)
On Mon, Dec 1, 2014 at 6:55 AM, Hallvard Breien Furuseth < h.b.furuseth@usit.uio.no> wrote:
A write transaction frees pages which its new snapshot cannot see. A later writer will overwrite them, when no *known* readers can see them either. But with MDB_NOLOCK, writers don't know about old readers and might overwrite pages which old readers can see.
Last snapshot is never overwritten. So readers which did begin/renew after latest commit(write txn) are safe from txn_begin(write txn).
The same with the commit of the write txn before that. I think. MDB keeps the last two snapshots in the metapages.
I've been reading the MDB source code a bit more to verify this assumption. It is not valid.
MDB does keep the last two metapages, but may begin to dismantle the elder of the two for pages if there are no readers for it. With MDB_NOLOCK, it simply assumes there are no readers for it (cf. mdb_find_oldest). **Only the most recent snapshot is preserved.**
For my current use case, I believe that I can still achieve a sufficient level of parallelism even if limited to double-buffering (whereas two snapshots would give me triple-buffering). I'm not going to press for any changes at this time.