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 5c488d7033
commit c7674f671d

View File

@ -3455,7 +3455,7 @@ static __inline int mdbx_backlog_size(MDBX_txn *txn) {
int reclaimed = txn->mt_env->me_reclaimed_pglist
? txn->mt_env->me_reclaimed_pglist[0]
: 0;
return reclaimed + txn->mt_loose_count + txn->mt_end_pgno - txn->mt_next_pgno;
return reclaimed + txn->mt_loose_count;
}
static __inline int mdbx_backlog_extragap(MDBX_env *env) {
@ -3468,7 +3468,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;
@ -3476,11 +3478,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;
}
@ -3491,6 +3492,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;
}
}
/* Cleanup reclaimed GC records, than save the befree-list as of this
* transaction to GC (aka freeDB). This recursive changes the reclaimed-list
* loose-list and befree-list. Keep trying until it stabilizes. */
@ -3683,7 +3698,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 */
@ -3691,6 +3706,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;
@ -3888,6 +3904,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));
if (unlikely(rc != MDBX_SUCCESS))