mirror of
https://github.com/isar/libmdbx.git
synced 2025-01-04 18:14:12 +08:00
mdbx: internal build option for debuging dirtyroom reservation and spilling.
Related to https://github.com/erthink/libmdbx/issues/186 Change-Id: Ia315ae2cae5f5b5b82891843de22487db0139df3
This commit is contained in:
parent
39230c9a22
commit
aa5a39160a
36
src/core.c
36
src/core.c
@ -5101,12 +5101,13 @@ static unsigned spill_prio(const MDBX_txn *txn, const unsigned i,
|
|||||||
* the child aborted. */
|
* the child aborted. */
|
||||||
static int mdbx_txn_spill(MDBX_txn *const txn, MDBX_cursor *const m0,
|
static int mdbx_txn_spill(MDBX_txn *const txn, MDBX_cursor *const m0,
|
||||||
const unsigned need) {
|
const unsigned need) {
|
||||||
#ifndef MDBX_DEBUG_SPILLING
|
#if MDBX_DEBUG_SPILLING != 1
|
||||||
|
/* production mode */
|
||||||
if (likely(txn->tw.dirtyroom + txn->tw.loose_count >= need))
|
if (likely(txn->tw.dirtyroom + txn->tw.loose_count >= need))
|
||||||
return MDBX_SUCCESS;
|
return MDBX_SUCCESS;
|
||||||
unsigned wanna_spill = need - txn->tw.dirtyroom;
|
unsigned wanna_spill = need - txn->tw.dirtyroom;
|
||||||
#else
|
#else
|
||||||
/* spill at least one page if defined MDBX_DEBUG_SPILLING */
|
/* debug mode: spill at least one page if MDBX_DEBUG_SPILLING == 1 */
|
||||||
unsigned wanna_spill =
|
unsigned wanna_spill =
|
||||||
(need > txn->tw.dirtyroom) ? need - txn->tw.dirtyroom : 1;
|
(need > txn->tw.dirtyroom) ? need - txn->tw.dirtyroom : 1;
|
||||||
#endif /* MDBX_DEBUG_SPILLING */
|
#endif /* MDBX_DEBUG_SPILLING */
|
||||||
@ -5335,6 +5336,20 @@ static int mdbx_txn_spill(MDBX_txn *const txn, MDBX_cursor *const m0,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if MDBX_DEBUG_SPILLING == 2
|
||||||
|
if (txn->tw.loose_count + txn->tw.dirtyroom <= need / 2 + 1)
|
||||||
|
mdbx_error("dirty-list length: before %u, after %u, parent %i, loose %u; "
|
||||||
|
"needed %u, spillable %u; "
|
||||||
|
"spilled %u dirty-entries, now have %u dirty-room",
|
||||||
|
dl->length + spilled, dl->length,
|
||||||
|
(txn->mt_parent && txn->mt_parent->tw.dirtylist)
|
||||||
|
? (int)txn->mt_parent->tw.dirtylist->length
|
||||||
|
: -1,
|
||||||
|
txn->tw.loose_count, need, spillable, spilled,
|
||||||
|
txn->tw.dirtyroom);
|
||||||
|
mdbx_ensure(txn->mt_env, txn->tw.loose_count + txn->tw.dirtyroom > need / 2);
|
||||||
|
#endif /* MDBX_DEBUG_SPILLING */
|
||||||
|
|
||||||
return likely(txn->tw.loose_count + txn->tw.dirtyroom > need / 2)
|
return likely(txn->tw.loose_count + txn->tw.dirtyroom > need / 2)
|
||||||
? MDBX_SUCCESS
|
? MDBX_SUCCESS
|
||||||
: MDBX_TXN_FULL;
|
: MDBX_TXN_FULL;
|
||||||
@ -5353,11 +5368,21 @@ static int mdbx_cursor_spill(MDBX_cursor *mc, const MDBX_val *key,
|
|||||||
if (mc->mc_dbi > MAIN_DBI)
|
if (mc->mc_dbi > MAIN_DBI)
|
||||||
need += txn->mt_dbs[MAIN_DBI].md_depth + 3;
|
need += txn->mt_dbs[MAIN_DBI].md_depth + 3;
|
||||||
}
|
}
|
||||||
|
#if MDBX_DEBUG_SPILLING != 2
|
||||||
|
/* production mode */
|
||||||
/* 4) Double the page chain estimation
|
/* 4) Double the page chain estimation
|
||||||
* for extensively splitting, rebalance and merging */
|
* for extensively splitting, rebalance and merging */
|
||||||
need += need;
|
need += need;
|
||||||
/* 5) Factor the key+data which to be put in */
|
/* 5) Factor the key+data which to be put in */
|
||||||
need += bytes2pgno(txn->mt_env, node_size(key, data)) + 1;
|
need += bytes2pgno(txn->mt_env, node_size(key, data)) + 1;
|
||||||
|
#else
|
||||||
|
/* debug mode */
|
||||||
|
(void)key;
|
||||||
|
(void)data;
|
||||||
|
mc->mc_txn->mt_env->debug_dirtied_est = ++need;
|
||||||
|
mc->mc_txn->mt_env->debug_dirtied_act = 0;
|
||||||
|
#endif /* MDBX_DEBUG_SPILLING == 2 */
|
||||||
|
|
||||||
return mdbx_txn_spill(txn, mc, need);
|
return mdbx_txn_spill(txn, mc, need);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -5653,6 +5678,13 @@ static __cold pgno_t mdbx_find_largest(MDBX_env *env, pgno_t largest) {
|
|||||||
/* Add a page to the txn's dirty list */
|
/* Add a page to the txn's dirty list */
|
||||||
static int __must_check_result mdbx_page_dirty(MDBX_txn *txn, MDBX_page *mp,
|
static int __must_check_result mdbx_page_dirty(MDBX_txn *txn, MDBX_page *mp,
|
||||||
unsigned npages) {
|
unsigned npages) {
|
||||||
|
#if MDBX_DEBUG_SPILLING == 2
|
||||||
|
txn->mt_env->debug_dirtied_act += 1;
|
||||||
|
mdbx_ensure(txn->mt_env,
|
||||||
|
txn->mt_env->debug_dirtied_act < txn->mt_env->debug_dirtied_est);
|
||||||
|
mdbx_ensure(txn->mt_env, txn->tw.dirtyroom + txn->tw.loose_count > 0);
|
||||||
|
#endif /* MDBX_DEBUG_SPILLING == 2 */
|
||||||
|
|
||||||
int rc;
|
int rc;
|
||||||
mp->mp_txnid = txn->mt_front;
|
mp->mp_txnid = txn->mt_front;
|
||||||
if (unlikely(txn->tw.dirtyroom == 0)) {
|
if (unlikely(txn->tw.dirtyroom == 0)) {
|
||||||
|
@ -1226,6 +1226,13 @@ struct MDBX_env {
|
|||||||
pgno_t me_poison_edge;
|
pgno_t me_poison_edge;
|
||||||
#endif /* MDBX_USE_VALGRIND || __SANITIZE_ADDRESS__ */
|
#endif /* MDBX_USE_VALGRIND || __SANITIZE_ADDRESS__ */
|
||||||
|
|
||||||
|
#ifndef MDBX_DEBUG_SPILLING
|
||||||
|
#define MDBX_DEBUG_SPILLING 0
|
||||||
|
#endif
|
||||||
|
#if MDBX_DEBUG_SPILLING == 2
|
||||||
|
unsigned debug_dirtied_est, debug_dirtied_act;
|
||||||
|
#endif /* MDBX_DEBUG_SPILLING */
|
||||||
|
|
||||||
/* ------------------------------------------------- stub for lck-less mode */
|
/* ------------------------------------------------- stub for lck-less mode */
|
||||||
alignas(MDBX_CACHELINE_SIZE) uint64_t
|
alignas(MDBX_CACHELINE_SIZE) uint64_t
|
||||||
me_lckless_stub[((sizeof(MDBX_lockinfo) + MDBX_CACHELINE_SIZE - 1) &
|
me_lckless_stub[((sizeof(MDBX_lockinfo) + MDBX_CACHELINE_SIZE - 1) &
|
||||||
|
Loading…
x
Reference in New Issue
Block a user