From d5658c496faf681d436cb4e7a47d87552701eec2 Mon Sep 17 00:00:00 2001 From: Leonid Yuriev Date: Fri, 30 Oct 2020 16:43:07 +0300 Subject: [PATCH] mdbx: fix `mp_txnid` check for spilled pages. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This is OMG stupid bug. Тем не менее, ошибка не была замечена по трём причинам: - some TODOs should be resolved, like [this](https://github.com/erthink/libmdbx/blob/faddc71eace1088f077a022a235cd097ef0c21c2/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 --- src/core.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/core.c b/src/core.c index 35f1445a..2008a39d 100644 --- a/src/core.c +++ b/src/core.c @@ -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;