mdbx: backport - refine backlog preparation inside update_gc().

Change-Id: Ib18842c2922afba794d6ab69337580bcea29bfe6
This commit is contained in:
Leonid Yuriev 2019-07-08 15:27:26 +03:00
parent 04a91adc70
commit 961f08a5d2

View File

@ -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;