Changes from a failed liblmdb operation can be visible. Sometimes
the resulting DB will also be inconsistent. The operation should
invalidate the affected transaction/cursors or revert the change.
At least I hope it's feasible to invalidate so the user cannot see
surprising results, instead of just documenting "don't do that".
put(MDB_MULTIPLE) can write some of the provided items and then
fail, but be able to keep the txn usable. It should invalidate the
txn anyway, or document that the caller must check for e.g. return
value MDB_PARTIAL_SUCCESS. Maybe invalidate unless the the caller
requests support for partial success. put() would update the input
params to indicate which items remain unwritten.
A failed txn could still grow the txn size, unless MDB "un-touches"
pages which memcmp says have not changed, rewinds me_pglast and
me_pghead, etc. Which seems a lot of work, likely not worth the
I think cursors need a C_INVALID flag, so future ops cannot give a
surprising success result instead of failing: get(MDB_NEXT/MDB_PREV)
take ~C_INITIALIZED to mean (re)start from the beginning/end.
Don't know how often reverting is a relevant option. Rearranging
code can help, but maybe not much. E.g. the mdb_del() in mdb_drop()
can do some harmless touches and then fail cleanly - but mdb_drop()
must invalidate the txn anyway since mdb_drop0() has deleted pages.
Unless it does extra work - remember mt_free_pgs before and after
mdb_drop0(), then delete from mt_free_pgs the pages added by
drop0. Or drop0 could be done last since it can fail cleanly just
by resetting mt_free_pgs. But I don't know if del(MDB_MULTIPLE)
can also do that if the DB used a subpage. drop0 can't examine the
subpage after it got deleted.
Show replies by date