mirror of
https://github.com/isar/libmdbx.git
synced 2025-02-04 15:42:06 +08:00
mdbx: refine mdbx_page_alloc()
to avoid MDBX_TXN_FULL
.
More for https://github.com/erthink/libmdbx/issues/123 Change-Id: I527b7e9507f4c2aa565f1567924cfb1c477966dd
This commit is contained in:
parent
a4df0acb00
commit
c1210d7c73
43
src/core.c
43
src/core.c
@ -2676,8 +2676,10 @@ static int mdbx_pnl_reserve(MDBX_PNL *ppl, const size_t wanna) {
|
|||||||
if (likely(allocated >= wanna))
|
if (likely(allocated >= wanna))
|
||||||
return MDBX_SUCCESS;
|
return MDBX_SUCCESS;
|
||||||
|
|
||||||
if (unlikely(wanna > /* paranoia */ MDBX_PGL_LIMIT))
|
if (unlikely(wanna > /* paranoia */ MDBX_PGL_LIMIT)) {
|
||||||
|
mdbx_error("PNL too long (%zu > %zu)", wanna, (size_t)MDBX_PGL_LIMIT);
|
||||||
return MDBX_TXN_FULL;
|
return MDBX_TXN_FULL;
|
||||||
|
}
|
||||||
|
|
||||||
const size_t size = (wanna + wanna - allocated < MDBX_PGL_LIMIT)
|
const size_t size = (wanna + wanna - allocated < MDBX_PGL_LIMIT)
|
||||||
? wanna + wanna - allocated
|
? wanna + wanna - allocated
|
||||||
@ -2919,8 +2921,10 @@ static int mdbx_txl_reserve(MDBX_TXL *ptl, const size_t wanna) {
|
|||||||
if (likely(allocated >= wanna))
|
if (likely(allocated >= wanna))
|
||||||
return MDBX_SUCCESS;
|
return MDBX_SUCCESS;
|
||||||
|
|
||||||
if (unlikely(wanna > /* paranoia */ MDBX_TXL_MAX))
|
if (unlikely(wanna > /* paranoia */ MDBX_TXL_MAX)) {
|
||||||
|
mdbx_error("TXL too long (%zu > %zu)", wanna, (size_t)MDBX_TXL_MAX);
|
||||||
return MDBX_TXN_FULL;
|
return MDBX_TXN_FULL;
|
||||||
|
}
|
||||||
|
|
||||||
const size_t size = (wanna + wanna - allocated < MDBX_TXL_MAX)
|
const size_t size = (wanna + wanna - allocated < MDBX_TXL_MAX)
|
||||||
? wanna + wanna - allocated
|
? wanna + wanna - allocated
|
||||||
@ -3131,8 +3135,10 @@ mdbx_dpl_append(MDBX_txn *txn, pgno_t pgno, MDBX_page *page) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (unlikely(dl->length == dl->allocated)) {
|
if (unlikely(dl->length == dl->allocated)) {
|
||||||
if (unlikely(dl->allocated == txn->mt_env->me_options.dp_limit))
|
if (unlikely(dl->allocated == txn->mt_env->me_options.dp_limit)) {
|
||||||
|
mdbx_error("DPL is full (%u)", txn->mt_env->me_options.dp_limit);
|
||||||
return MDBX_TXN_FULL;
|
return MDBX_TXN_FULL;
|
||||||
|
}
|
||||||
const size_t size = (dl->allocated < MDBX_PNL_INITIAL * 42)
|
const size_t size = (dl->allocated < MDBX_PNL_INITIAL * 42)
|
||||||
? dl->allocated + dl->allocated
|
? dl->allocated + dl->allocated
|
||||||
: dl->allocated + dl->allocated / 2;
|
: dl->allocated + dl->allocated / 2;
|
||||||
@ -4354,7 +4360,10 @@ static int mdbx_page_spill(MDBX_cursor *mc, const MDBX_val *key,
|
|||||||
} else {
|
} else {
|
||||||
/* purge deleted slots */
|
/* purge deleted slots */
|
||||||
mdbx_pnl_purge_odd(txn->tw.spill_pages, 1);
|
mdbx_pnl_purge_odd(txn->tw.spill_pages, 1);
|
||||||
mdbx_pnl_reserve(&txn->tw.spill_pages, spill);
|
rc = mdbx_pnl_reserve(&txn->tw.spill_pages, spill);
|
||||||
|
(void)rc /* ignore since the resulting list may be shorter
|
||||||
|
and mdbx_pnl_append() will increase pnl on demand */
|
||||||
|
;
|
||||||
}
|
}
|
||||||
mdbx_notice("spilling %zu pages (have %u dirty-room, need %zu)", spill,
|
mdbx_notice("spilling %zu pages (have %u dirty-room, need %zu)", spill,
|
||||||
txn->tw.dirtyroom, need);
|
txn->tw.dirtyroom, need);
|
||||||
@ -5327,7 +5336,8 @@ skip_cache:
|
|||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
const unsigned gc_len = MDBX_PNL_SIZE(gc_pnl);
|
const unsigned gc_len = MDBX_PNL_SIZE(gc_pnl);
|
||||||
if (unlikely(gc_len + MDBX_PNL_SIZE(txn->tw.reclaimed_pglist) >
|
if (flags != MDBX_ALLOC_GC &&
|
||||||
|
unlikely(gc_len + MDBX_PNL_SIZE(txn->tw.reclaimed_pglist) >
|
||||||
env->me_options.rp_augment_limit) &&
|
env->me_options.rp_augment_limit) &&
|
||||||
(pgno_add(txn->mt_next_pgno, num) <= txn->mt_geo.upper ||
|
(pgno_add(txn->mt_next_pgno, num) <= txn->mt_geo.upper ||
|
||||||
gc_len + MDBX_PNL_SIZE(txn->tw.reclaimed_pglist) >=
|
gc_len + MDBX_PNL_SIZE(txn->tw.reclaimed_pglist) >=
|
||||||
@ -5336,11 +5346,6 @@ skip_cache:
|
|||||||
* This is a rare case while search for a continuously multi-page region
|
* This is a rare case while search for a continuously multi-page region
|
||||||
* in a large database. https://github.com/erthink/libmdbx/issues/123 */
|
* in a large database. https://github.com/erthink/libmdbx/issues/123 */
|
||||||
flags &= ~MDBX_ALLOC_GC;
|
flags &= ~MDBX_ALLOC_GC;
|
||||||
if (unlikely((flags & MDBX_ALLOC_ALL) == 0)) {
|
|
||||||
/* Oh, we can't do anything */
|
|
||||||
rc = MDBX_TXN_FULL;
|
|
||||||
goto fail;
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
rc = mdbx_pnl_need(&txn->tw.reclaimed_pglist, gc_len);
|
rc = mdbx_pnl_need(&txn->tw.reclaimed_pglist, gc_len);
|
||||||
@ -5360,8 +5365,7 @@ skip_cache:
|
|||||||
mdbx_debug_extra("PNL read txn %" PRIaTXN " root %" PRIaPGNO
|
mdbx_debug_extra("PNL read txn %" PRIaTXN " root %" PRIaPGNO
|
||||||
" num %u, PNL",
|
" num %u, PNL",
|
||||||
last, txn->mt_dbs[FREE_DBI].md_root, gc_len);
|
last, txn->mt_dbs[FREE_DBI].md_root, gc_len);
|
||||||
unsigned i;
|
for (unsigned i = gc_len; i; i--)
|
||||||
for (i = gc_len; i; i--)
|
|
||||||
mdbx_debug_extra_print(" %" PRIaPGNO, gc_pnl[i]);
|
mdbx_debug_extra_print(" %" PRIaPGNO, gc_pnl[i]);
|
||||||
mdbx_debug_extra_print("%s", "\n");
|
mdbx_debug_extra_print("%s", "\n");
|
||||||
}
|
}
|
||||||
@ -5639,8 +5643,11 @@ static int __must_check_result mdbx_page_unspill(MDBX_txn *txn, MDBX_page *mp,
|
|||||||
unsigned i = mdbx_pnl_exist(tx2->tw.spill_pages, pn);
|
unsigned i = mdbx_pnl_exist(tx2->tw.spill_pages, pn);
|
||||||
if (!i)
|
if (!i)
|
||||||
continue;
|
continue;
|
||||||
if (txn->tw.dirtyroom == 0)
|
if (txn->tw.dirtyroom == 0) {
|
||||||
|
mdbx_error("Dirtyroom is depleted, DPL length %u",
|
||||||
|
txn->tw.dirtylist->length);
|
||||||
return MDBX_TXN_FULL;
|
return MDBX_TXN_FULL;
|
||||||
|
}
|
||||||
unsigned num = IS_OVERFLOW(mp) ? mp->mp_pages : 1;
|
unsigned num = IS_OVERFLOW(mp) ? mp->mp_pages : 1;
|
||||||
MDBX_page *np = mp;
|
MDBX_page *np = mp;
|
||||||
if ((env->me_flags & MDBX_WRITEMAP) == 0) {
|
if ((env->me_flags & MDBX_WRITEMAP) == 0) {
|
||||||
@ -6412,8 +6419,8 @@ static int mdbx_txn_renew0(MDBX_txn *txn, const unsigned flags) {
|
|||||||
const txnid_t snap = mdbx_meta_txnid_stable(env, meta);
|
const txnid_t snap = mdbx_meta_txnid_stable(env, meta);
|
||||||
txn->mt_txnid = safe64_txnid_next(snap);
|
txn->mt_txnid = safe64_txnid_next(snap);
|
||||||
if (unlikely(txn->mt_txnid > MAX_TXNID)) {
|
if (unlikely(txn->mt_txnid > MAX_TXNID)) {
|
||||||
mdbx_error("%s", "txnid overflow!");
|
|
||||||
rc = MDBX_TXN_FULL;
|
rc = MDBX_TXN_FULL;
|
||||||
|
mdbx_error("txnid overflow, raise %d", rc);
|
||||||
goto bailout;
|
goto bailout;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -9032,8 +9039,8 @@ static int mdbx_sync_locked(MDBX_env *env, unsigned flags,
|
|||||||
const txnid_t txnid =
|
const txnid_t txnid =
|
||||||
safe64_txnid_next(unaligned_peek_u64(4, pending->mm_txnid_a));
|
safe64_txnid_next(unaligned_peek_u64(4, pending->mm_txnid_a));
|
||||||
if (unlikely(txnid > MAX_TXNID)) {
|
if (unlikely(txnid > MAX_TXNID)) {
|
||||||
mdbx_error("%s", "txnid overflow!");
|
|
||||||
rc = MDBX_TXN_FULL;
|
rc = MDBX_TXN_FULL;
|
||||||
|
mdbx_error("txnid overflow, raise %d", rc);
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
mdbx_meta_set_txnid(env, pending, txnid);
|
mdbx_meta_set_txnid(env, pending, txnid);
|
||||||
@ -9659,8 +9666,8 @@ mdbx_env_set_geometry(MDBX_env *env, intptr_t size_lower, intptr_t size_now,
|
|||||||
const txnid_t txnid =
|
const txnid_t txnid =
|
||||||
safe64_txnid_next(mdbx_meta_txnid_stable(env, head));
|
safe64_txnid_next(mdbx_meta_txnid_stable(env, head));
|
||||||
if (unlikely(txnid > MAX_TXNID)) {
|
if (unlikely(txnid > MAX_TXNID)) {
|
||||||
mdbx_error("%s", "txnid overflow!");
|
|
||||||
rc = MDBX_TXN_FULL;
|
rc = MDBX_TXN_FULL;
|
||||||
|
mdbx_error("txnid overflow, raise %d", rc);
|
||||||
goto bailout;
|
goto bailout;
|
||||||
}
|
}
|
||||||
mdbx_meta_set_txnid(env, &meta, txnid);
|
mdbx_meta_set_txnid(env, &meta, txnid);
|
||||||
@ -10062,7 +10069,7 @@ static __cold int mdbx_setup_dxb(MDBX_env *env, const int lck_rc) {
|
|||||||
const txnid_t txnid = mdbx_meta_txnid_stable(env, head);
|
const txnid_t txnid = mdbx_meta_txnid_stable(env, head);
|
||||||
const txnid_t next_txnid = safe64_txnid_next(txnid);
|
const txnid_t next_txnid = safe64_txnid_next(txnid);
|
||||||
if (unlikely(txnid > MAX_TXNID)) {
|
if (unlikely(txnid > MAX_TXNID)) {
|
||||||
mdbx_error("%s", "txnid overflow!");
|
mdbx_error("txnid overflow, raise %d", MDBX_TXN_FULL);
|
||||||
return MDBX_TXN_FULL;
|
return MDBX_TXN_FULL;
|
||||||
}
|
}
|
||||||
mdbx_notice("updating meta.geo: "
|
mdbx_notice("updating meta.geo: "
|
||||||
@ -10519,7 +10526,7 @@ __cold int mdbx_env_turn_for_recovery(MDBX_env *env, unsigned target_meta) {
|
|||||||
|
|
||||||
if (!META_IS_STEADY(meta) || mdbx_recent_committed_txnid(env) != txnid) {
|
if (!META_IS_STEADY(meta) || mdbx_recent_committed_txnid(env) != txnid) {
|
||||||
if (unlikely(txnid > MAX_TXNID)) {
|
if (unlikely(txnid > MAX_TXNID)) {
|
||||||
mdbx_error("%s", "txnid overflow!");
|
mdbx_error("txnid overflow, raise %d", MDBX_TXN_FULL);
|
||||||
return MDBX_TXN_FULL;
|
return MDBX_TXN_FULL;
|
||||||
}
|
}
|
||||||
mdbx_meta_set_txnid(env, meta, txnid);
|
mdbx_meta_set_txnid(env, meta, txnid);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user