Full_Name: David Wilson Version: 919a0f5b54dad3acf2f84e7993bb00e7aa098037 OS: Linux URL: http://www.h1.botanicus.net/20130919-lmdb.trace.bz2 Submission from: (NULL) (178.238.153.20)
In some circumstances LMDB will segfault in mdb_cursor_get() on a cursor that existed prior to a deletion that just occurred. It is apparently related to the page the cursor points to becoming mutated by the deletion.
In LMDB 0.9.8, the issue may manifest as a NULL ptr dereference:
#0 mdb_xcursor_init1 (mc=mc@entry=0x1013da0, node=node@entry=0x7ffd76031ac2) at lib/mdb.c:6525 #1 0x00007ffff5209b73 in mdb_cursor_next (mc=0x1013da0, key=0xce39a0, data=data@entry=0xce3660, op=<optimized out>) at lib/mdb.c:5042 #2 0x00007ffff5208a6e in mdb_cursor_get (mc=0x1013da0, key=0xce39a0, data=0xce3660, op=op@entry=MDB_NEXT) at lib/mdb.c:5526 #3 0x00007ffff5202a83 in _cffi_f_mdb_cursor_get (self=<optimized out>, args=<optimized out>) at lmdb/__pycache__/lmdb_cffi.c:714 #4 0x0000000000471a8b in call_function (oparg=<optimized out>, pp_stack=0x7fffffffcf30) at ../Python/ceval.c:4021 #5 PyEval_EvalFrameEx (
Due to F_DUPDATA bit being set as tested on line 5041. Examining the leaf structure reveals a large chunk of ASCII text (which should have been written to the DB), interspersed with some integer values.
Versions of LMDB <= 0.9.7 exhibit similar crashes, although in a different place: "assert(mc)" at the start of mdb_cursor_get().
Various MDB versions going back 6 months were tested, and none exhibited any better behaviour. In the attached trace/replay, version c0575825730dd2aab4031100b25d632a3d052447 from April exhibited the bug after only 1993 operations executed from the trace file. Any more recent version requires the entire trace file to execute before triggering the assert or SEGV.
http://www.h1.botanicus.net/20130919-lmdb.trace.bz2 is a 33MiB trace file that can be loaded and executed using https://github.com/dw/acid/blob/master/misc/lmdb-replay.c
The apparent workaround is to reinitialize any existing cursors should a deletion occur within a transaction, as demonstrated in https://github.com/dw/acid/commit/56f183c71a668e540df58d5137e946616a446c49