mdbx: fix mp_txnid check for spilled pages.

This is OMG stupid bug.

Тем не менее, ошибка не была замечена по трём причинам:
- some TODOs should be resolved, like [this](faddc71eac/src/core.c (4014)) and some others;
- test cases should be extended to triggering the page spilling threshold;
- mdbx_env_set_option() should be provide to tunning such threshold(s) (https://github.com/erthink/libmdbx/issues/128).

Resolves https://github.com/erthink/libmdbx/issues/126

Change-Id: If76336620aa83e6916e3aeaa838e0b6e68c34fd7
This commit is contained in:
Leonid Yuriev 2020-10-30 16:43:07 +03:00
parent 16c900b0a1
commit d5658c496f

View File

@ -3138,7 +3138,7 @@ static int mdbx_txn_end(MDBX_txn *txn, unsigned mode);
static int __must_check_result mdbx_page_get(MDBX_cursor *mc, pgno_t pgno,
MDBX_page **mp, int *lvl,
const txnid_t pp_txnid);
txnid_t pp_txnid);
static int __must_check_result mdbx_page_search_root(MDBX_cursor *mc,
const MDBX_val *key,
int flags);
@ -11306,7 +11306,7 @@ static int mdbx_cursor_push(MDBX_cursor *mc, MDBX_page *mp) {
*
* Returns 0 on success, non-zero on failure. */
__hot static int mdbx_page_get(MDBX_cursor *mc, pgno_t pgno, MDBX_page **ret,
int *lvl, const txnid_t pp_txnid) {
int *lvl, txnid_t pp_txnid) {
MDBX_txn *txn = mc->mc_txn;
if (unlikely(pgno >= txn->mt_next_pgno)) {
mdbx_error("page #%" PRIaPGNO " beyond next-pgno", pgno);
@ -11331,8 +11331,11 @@ __hot static int mdbx_page_get(MDBX_cursor *mc, pgno_t pgno, MDBX_page **ret,
* because the dirty list got full. Bring this page
* back in from the map (but don't unspill it here,
* leave that unless page_touch happens again). */
if (txn->tw.spill_pages && mdbx_pnl_exist(txn->tw.spill_pages, pgno << 1))
if (txn->tw.spill_pages &&
mdbx_pnl_exist(txn->tw.spill_pages, pgno << 1)) {
pp_txnid = txn->mt_txnid;
goto spilled;
}
p = mdbx_dpl_find(txn->tw.dirtylist, pgno);
if (p)
goto dirty;