From 8779f665dc1d83fdeb8d19695c44b883bbc18f72 Mon Sep 17 00:00:00 2001 From: Leonid Yuriev Date: Thu, 20 Jan 2022 14:40:59 +0300 Subject: [PATCH] mdbx: fix excessive PNL checking after sort for spilling. This bug triggered only in the DEBUG builds or when the assertion checking is forcibly enabled. It does not affect any core logic and cannot lead to DB corruption, data loss, and so on. Fixes https://github.com/erthink/libmdbx/issues/260. --- src/core.c | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/src/core.c b/src/core.c index 99bd8ca4..f0db843b 100644 --- a/src/core.c +++ b/src/core.c @@ -3101,11 +3101,12 @@ RADIXSORT_IMPL(pgno, pgno_t, MDBX_PNL_EXTRACT_KEY, MDBX_PNL_PREALLOC_FOR_RADIXSORT, 0) SORT_IMPL(pgno_sort, false, pgno_t, MDBX_PNL_ORDERED) -static __hot void mdbx_pnl_sort(MDBX_PNL pnl) { +static __hot void mdbx_pnl_sort(MDBX_PNL pnl, size_t limit4check) { if (likely(MDBX_PNL_SIZE(pnl) < MDBX_RADIXSORT_THRESHOLD) || unlikely(!pgno_radixsort(&MDBX_PNL_FIRST(pnl), MDBX_PNL_SIZE(pnl)))) pgno_sort(MDBX_PNL_BEGIN(pnl), MDBX_PNL_END(pnl)); - assert(mdbx_pnl_check(pnl, MAX_PAGENO + 1)); + assert(mdbx_pnl_check(pnl, limit4check)); + (void)limit4check; } /* Search for an pgno in an PNL. @@ -4402,7 +4403,7 @@ static void mdbx_refund_loose(MDBX_txn *txn) { if (most + 1 == txn->mt_next_pgno) { /* Sort suitable list and refund pages at the tail. */ MDBX_PNL_SIZE(suitable) = w; - mdbx_pnl_sort(suitable); + mdbx_pnl_sort(suitable, MAX_PAGENO + 1); /* Scanning in descend order */ const int step = MDBX_PNL_ASCENDING ? -1 : 1; @@ -5401,7 +5402,7 @@ static int mdbx_txn_spill(MDBX_txn *const txn, MDBX_cursor *const m0, if (unlikely(rc != MDBX_SUCCESS)) goto bailout; - mdbx_pnl_sort(txn->tw.spill_pages); + mdbx_pnl_sort(txn->tw.spill_pages, (size_t)txn->mt_next_pgno << 1); txn->mt_flags |= MDBX_TXN_SPILLS; mdbx_notice("spilled %u dirty-entries, now have %u dirty-room", spilled, txn->tw.dirtyroom); @@ -8963,7 +8964,7 @@ retry: } mdbx_tassert(txn, count == txn->tw.loose_count); MDBX_PNL_SIZE(loose) = count; - mdbx_pnl_sort(loose); + mdbx_pnl_sort(loose, txn->mt_next_pgno); mdbx_pnl_xmerge(txn->tw.reclaimed_pglist, loose); mdbx_trace("%s: append %u loose-pages to reclaimed-pages", dbg_prefix_mode, txn->tw.loose_count); @@ -9027,7 +9028,7 @@ retry: } while (data.iov_len < MDBX_PNL_SIZEOF(txn->tw.retired_pages)); retired_stored = (unsigned)MDBX_PNL_SIZE(txn->tw.retired_pages); - mdbx_pnl_sort(txn->tw.retired_pages); + mdbx_pnl_sort(txn->tw.retired_pages, txn->mt_next_pgno); mdbx_assert(env, data.iov_len == MDBX_PNL_SIZEOF(txn->tw.retired_pages)); memcpy(data.iov_base, txn->tw.retired_pages, data.iov_len);