mirror of
https://github.com/isar/libmdbx.git
synced 2024-10-30 23:39:19 +08:00
mdbx: backport - refine backlog preparation inside update_gc().
Change-Id: Ib18842c2922afba794d6ab69337580bcea29bfe6
This commit is contained in:
parent
04a91adc70
commit
961f08a5d2
34
src/mdbx.c
34
src/mdbx.c
@ -3739,7 +3739,7 @@ static __inline int mdbx_backlog_size(MDBX_txn *txn) {
|
||||
? MDBX_PNL_SIZE(txn->mt_env->me_reclaimed_pglist) +
|
||||
txn->mt_loose_count
|
||||
: 0;
|
||||
return reclaimed_and_loose + txn->mt_end_pgno - txn->mt_next_pgno;
|
||||
return reclaimed_and_loose;
|
||||
}
|
||||
|
||||
static __inline int mdbx_backlog_extragap(MDBX_env *env) {
|
||||
@ -3752,7 +3752,9 @@ static __inline int mdbx_backlog_extragap(MDBX_env *env) {
|
||||
* in mdbx_page_alloc() during a deleting, when freeDB tree is unbalanced. */
|
||||
static int mdbx_prep_backlog(MDBX_txn *txn, MDBX_cursor *mc) {
|
||||
/* LY: extra page(s) for b-tree rebalancing */
|
||||
const int extra = mdbx_backlog_extragap(txn->mt_env);
|
||||
const int extra =
|
||||
mdbx_backlog_extragap(txn->mt_env) +
|
||||
MDBX_PNL_SIZEOF(txn->mt_befree_pages) / txn->mt_env->me_maxkey_limit;
|
||||
|
||||
if (mdbx_backlog_size(txn) < mc->mc_db->md_depth + extra) {
|
||||
mc->mc_flags &= ~C_RECLAIMING;
|
||||
@ -3760,11 +3762,10 @@ static int mdbx_prep_backlog(MDBX_txn *txn, MDBX_cursor *mc) {
|
||||
if (unlikely(rc))
|
||||
return rc;
|
||||
|
||||
int backlog;
|
||||
while (unlikely((backlog = mdbx_backlog_size(txn)) < extra)) {
|
||||
while (unlikely(mdbx_backlog_size(txn) < extra)) {
|
||||
rc = mdbx_page_alloc(mc, 1, NULL, MDBX_ALLOC_GC);
|
||||
if (unlikely(rc)) {
|
||||
if (unlikely(rc != MDBX_NOTFOUND))
|
||||
if (rc != MDBX_NOTFOUND)
|
||||
return rc;
|
||||
break;
|
||||
}
|
||||
@ -3775,6 +3776,20 @@ static int mdbx_prep_backlog(MDBX_txn *txn, MDBX_cursor *mc) {
|
||||
return MDBX_SUCCESS;
|
||||
}
|
||||
|
||||
static void mdbx_prep_backlog_data(MDBX_txn *txn, MDBX_cursor *mc,
|
||||
size_t bytes) {
|
||||
const int wanna =
|
||||
(int)OVPAGES(txn->mt_env, bytes) + mdbx_backlog_extragap(txn->mt_env);
|
||||
if (unlikely(wanna > mdbx_backlog_size(txn))) {
|
||||
mc->mc_flags &= ~C_RECLAIMING;
|
||||
do {
|
||||
if (mdbx_page_alloc(mc, 1, NULL, MDBX_ALLOC_GC) != MDBX_SUCCESS)
|
||||
break;
|
||||
} while (wanna > mdbx_backlog_size(txn));
|
||||
mc->mc_flags |= C_RECLAIMING;
|
||||
}
|
||||
}
|
||||
|
||||
/* Count all the pages in each DB and in the freelist and make sure
|
||||
* it matches the actual number of pages being used.
|
||||
* All named DBs must be open for a correct count. */
|
||||
@ -4106,7 +4121,7 @@ retry:
|
||||
mc.mc_flags &= ~C_RECLAIMING;
|
||||
rc = mdbx_page_search(&mc, NULL, MDBX_PS_LAST | MDBX_PS_MODIFY);
|
||||
mc.mc_flags |= C_RECLAIMING;
|
||||
if (unlikely(rc != MDBX_SUCCESS && rc != MDBX_NOTFOUND))
|
||||
if (unlikely(rc != MDBX_SUCCESS) && rc != MDBX_NOTFOUND)
|
||||
goto bailout;
|
||||
}
|
||||
/* Write to last page of freeDB */
|
||||
@ -4114,6 +4129,7 @@ retry:
|
||||
key.iov_base = &txn->mt_txnid;
|
||||
do {
|
||||
data.iov_len = MDBX_PNL_SIZEOF(txn->mt_befree_pages);
|
||||
mdbx_prep_backlog_data(txn, &mc, data.iov_len);
|
||||
rc = mdbx_cursor_put(&mc, &key, &data, MDBX_RESERVE);
|
||||
if (unlikely(rc != MDBX_SUCCESS))
|
||||
goto bailout;
|
||||
@ -4323,6 +4339,7 @@ retry:
|
||||
data.iov_len = (chunk + 1) * sizeof(pgno_t);
|
||||
mdbx_trace("%s.reserve: %u [%u...%u] @%" PRIaTXN, dbg_prefix_mode, chunk,
|
||||
settled + 1, settled + chunk + 1, reservation_gc_id);
|
||||
mdbx_prep_backlog_data(txn, &mc, data.iov_len);
|
||||
rc = mdbx_cursor_put(&mc, &key, &data, MDBX_RESERVE | MDBX_NOOVERWRITE);
|
||||
mdbx_tassert(txn, mdbx_pnl_check(env->me_reclaimed_pglist, true));
|
||||
if (unlikely(rc != MDBX_SUCCESS))
|
||||
@ -4420,9 +4437,10 @@ retry:
|
||||
if (unlikely(chunk > left)) {
|
||||
mdbx_trace("%s: chunk %u > left %u, @%" PRIaTXN, dbg_prefix_mode, chunk,
|
||||
left, fill_gc_id);
|
||||
if (loop < 5 || chunk - left > env->me_maxgc_ov1page) {
|
||||
if ((loop < 5 && chunk - left > loop / 2) ||
|
||||
chunk - left > env->me_maxgc_ov1page) {
|
||||
data.iov_len = (left + 1) * sizeof(pgno_t);
|
||||
if (loop < 21)
|
||||
if (loop < 7)
|
||||
mc.mc_flags &= ~C_GCFREEZE;
|
||||
}
|
||||
chunk = left;
|
||||
|
Loading…
Reference in New Issue
Block a user