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

Re: LMDB: issue with mdb_cursor_del



On 16. okt. 2017 12:51, Howard Chu wrote:
timur.kristof@gmail.com wrote:
I have an app that uses LMDB, and I've experienced an interesting
issue: when trying to delete a certain item with mdb_cursor_del, it
crashed with the following backtrace: https://pastebin.com/7p9wtkj9

Weird backtrace.  It says mdb_page_dirty(), which is small, streches
over 300+ lines (frames #3-#4).  And mdb_page_alloc() alone has no
hex address for prefix.  Maybe miscompilation, two liblmdb libraries
linked into the same executable, or something like that?  Or some
wild pointer write or whatever messed things up.

It appears that it couldn't mark a page as dirty.
Here is the relevant assertion from mdb_page_dirty:
rc = insert(txn->mt_u.dirty_list, &mid);
mdb_tassert(txn, rc == 0); // assertion failed

What might I be doing wrong in my application that triggers this sort
of error?

Take a look at the value of rc, then look in midl.c.

Also txn->mt_dirty_room and txn->mt_u.dirty_list[0].mid (the array length).

Most likely the dirty list is too big, which means you're trying to do too much in a single transaction.

Shouldn't happen though. The txn should have failed earlier with
MDB_TXN_FULL.

Which also shouldn't happen since LMDB should have spilled enough pages to
make room - unless you have hundreds of cursors at modified pages so
LMDB can't spill enough.

But we should probably test LMDB with impractically tight dirty-list arrays (i.e. a very small MDB_IDL_UM_MAX), so LMDB keeps running into such cases.

--
Hallvard