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) +
|
? MDBX_PNL_SIZE(txn->mt_env->me_reclaimed_pglist) +
|
||||||
txn->mt_loose_count
|
txn->mt_loose_count
|
||||||
: 0;
|
: 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) {
|
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. */
|
* in mdbx_page_alloc() during a deleting, when freeDB tree is unbalanced. */
|
||||||
static int mdbx_prep_backlog(MDBX_txn *txn, MDBX_cursor *mc) {
|
static int mdbx_prep_backlog(MDBX_txn *txn, MDBX_cursor *mc) {
|
||||||
/* LY: extra page(s) for b-tree rebalancing */
|
/* 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) {
|
if (mdbx_backlog_size(txn) < mc->mc_db->md_depth + extra) {
|
||||||
mc->mc_flags &= ~C_RECLAIMING;
|
mc->mc_flags &= ~C_RECLAIMING;
|
||||||
@ -3760,11 +3762,10 @@ static int mdbx_prep_backlog(MDBX_txn *txn, MDBX_cursor *mc) {
|
|||||||
if (unlikely(rc))
|
if (unlikely(rc))
|
||||||
return rc;
|
return rc;
|
||||||
|
|
||||||
int backlog;
|
while (unlikely(mdbx_backlog_size(txn) < extra)) {
|
||||||
while (unlikely((backlog = mdbx_backlog_size(txn)) < extra)) {
|
|
||||||
rc = mdbx_page_alloc(mc, 1, NULL, MDBX_ALLOC_GC);
|
rc = mdbx_page_alloc(mc, 1, NULL, MDBX_ALLOC_GC);
|
||||||
if (unlikely(rc)) {
|
if (unlikely(rc)) {
|
||||||
if (unlikely(rc != MDBX_NOTFOUND))
|
if (rc != MDBX_NOTFOUND)
|
||||||
return rc;
|
return rc;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -3775,6 +3776,20 @@ static int mdbx_prep_backlog(MDBX_txn *txn, MDBX_cursor *mc) {
|
|||||||
return MDBX_SUCCESS;
|
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
|
/* Count all the pages in each DB and in the freelist and make sure
|
||||||
* it matches the actual number of pages being used.
|
* it matches the actual number of pages being used.
|
||||||
* All named DBs must be open for a correct count. */
|
* All named DBs must be open for a correct count. */
|
||||||
@ -4106,7 +4121,7 @@ retry:
|
|||||||
mc.mc_flags &= ~C_RECLAIMING;
|
mc.mc_flags &= ~C_RECLAIMING;
|
||||||
rc = mdbx_page_search(&mc, NULL, MDBX_PS_LAST | MDBX_PS_MODIFY);
|
rc = mdbx_page_search(&mc, NULL, MDBX_PS_LAST | MDBX_PS_MODIFY);
|
||||||
mc.mc_flags |= C_RECLAIMING;
|
mc.mc_flags |= C_RECLAIMING;
|
||||||
if (unlikely(rc != MDBX_SUCCESS && rc != MDBX_NOTFOUND))
|
if (unlikely(rc != MDBX_SUCCESS) && rc != MDBX_NOTFOUND)
|
||||||
goto bailout;
|
goto bailout;
|
||||||
}
|
}
|
||||||
/* Write to last page of freeDB */
|
/* Write to last page of freeDB */
|
||||||
@ -4114,6 +4129,7 @@ retry:
|
|||||||
key.iov_base = &txn->mt_txnid;
|
key.iov_base = &txn->mt_txnid;
|
||||||
do {
|
do {
|
||||||
data.iov_len = MDBX_PNL_SIZEOF(txn->mt_befree_pages);
|
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);
|
rc = mdbx_cursor_put(&mc, &key, &data, MDBX_RESERVE);
|
||||||
if (unlikely(rc != MDBX_SUCCESS))
|
if (unlikely(rc != MDBX_SUCCESS))
|
||||||
goto bailout;
|
goto bailout;
|
||||||
@ -4323,6 +4339,7 @@ retry:
|
|||||||
data.iov_len = (chunk + 1) * sizeof(pgno_t);
|
data.iov_len = (chunk + 1) * sizeof(pgno_t);
|
||||||
mdbx_trace("%s.reserve: %u [%u...%u] @%" PRIaTXN, dbg_prefix_mode, chunk,
|
mdbx_trace("%s.reserve: %u [%u...%u] @%" PRIaTXN, dbg_prefix_mode, chunk,
|
||||||
settled + 1, settled + chunk + 1, reservation_gc_id);
|
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);
|
rc = mdbx_cursor_put(&mc, &key, &data, MDBX_RESERVE | MDBX_NOOVERWRITE);
|
||||||
mdbx_tassert(txn, mdbx_pnl_check(env->me_reclaimed_pglist, true));
|
mdbx_tassert(txn, mdbx_pnl_check(env->me_reclaimed_pglist, true));
|
||||||
if (unlikely(rc != MDBX_SUCCESS))
|
if (unlikely(rc != MDBX_SUCCESS))
|
||||||
@ -4420,9 +4437,10 @@ retry:
|
|||||||
if (unlikely(chunk > left)) {
|
if (unlikely(chunk > left)) {
|
||||||
mdbx_trace("%s: chunk %u > left %u, @%" PRIaTXN, dbg_prefix_mode, chunk,
|
mdbx_trace("%s: chunk %u > left %u, @%" PRIaTXN, dbg_prefix_mode, chunk,
|
||||||
left, fill_gc_id);
|
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);
|
data.iov_len = (left + 1) * sizeof(pgno_t);
|
||||||
if (loop < 21)
|
if (loop < 7)
|
||||||
mc.mc_flags &= ~C_GCFREEZE;
|
mc.mc_flags &= ~C_GCFREEZE;
|
||||||
}
|
}
|
||||||
chunk = left;
|
chunk = left;
|
||||||
|
Loading…
Reference in New Issue
Block a user