mirror of
https://github.com/isar/libmdbx.git
synced 2025-01-04 18:34:12 +08:00
mdbx: rework & clarify backlog for gc-update.
Change-Id: I31f2b6919810b894e69af34bfee9a5b7f5a513fc
This commit is contained in:
parent
b6a00a881e
commit
13d68a1200
@ -5842,39 +5842,40 @@ static __always_inline unsigned backlog_size(MDBX_txn *txn) {
|
|||||||
return MDBX_PNL_SIZE(txn->tw.reclaimed_pglist) + txn->tw.loose_count;
|
return MDBX_PNL_SIZE(txn->tw.reclaimed_pglist) + txn->tw.loose_count;
|
||||||
}
|
}
|
||||||
|
|
||||||
static __always_inline unsigned gctree_backlog(MDBX_txn *txn) {
|
|
||||||
return /* for split upto root page */ txn->mt_dbs[FREE_DBI].md_depth +
|
|
||||||
/* for rebalance */ 2 + /* for grow */ 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* LY: Prepare a backlog of pages to modify GC itself,
|
/* LY: Prepare a backlog of pages to modify GC itself,
|
||||||
* while reclaiming is prohibited. It should be enough to prevent search
|
* while reclaiming is prohibited. It should be enough to prevent search
|
||||||
* in mdbx_page_alloc() during a deleting, when GC tree is unbalanced. */
|
* in mdbx_page_alloc() during a deleting, when GC tree is unbalanced. */
|
||||||
static int mdbx_prep_backlog(MDBX_txn *txn, MDBX_cursor *gc_cursor,
|
static int mdbx_prep_backlog(MDBX_txn *txn, MDBX_cursor *gc_cursor,
|
||||||
const size_t pnl_bytes) {
|
const size_t pnl_bytes) {
|
||||||
const unsigned linear = number_of_ovpages(
|
const unsigned linear4list = number_of_ovpages(txn->mt_env, pnl_bytes);
|
||||||
txn->mt_env,
|
const unsigned backlog4cow = txn->mt_dbs[FREE_DBI].md_depth;
|
||||||
pnl_bytes ? pnl_bytes : MDBX_PNL_SIZEOF(txn->tw.retired_pages));
|
const unsigned backlog4rebalance = backlog4cow + 1;
|
||||||
const unsigned backlog = linear + gctree_backlog(txn);
|
|
||||||
|
|
||||||
if (likely(
|
if (likely(linear4list == 1 &&
|
||||||
linear == 1 &&
|
backlog_size(txn) > (pnl_bytes
|
||||||
backlog_size(txn) >
|
? backlog4rebalance
|
||||||
(pnl_bytes
|
: (backlog4cow + backlog4rebalance))))
|
||||||
? backlog
|
|
||||||
: backlog + /* for COW */ txn->mt_dbs[FREE_DBI].md_depth)))
|
|
||||||
return MDBX_SUCCESS;
|
return MDBX_SUCCESS;
|
||||||
|
|
||||||
|
mdbx_trace(">> pnl_bytes %zu, backlog %u, 4list %u, 4cow %u, 4rebalance %u",
|
||||||
|
pnl_bytes, backlog_size(txn), linear4list, backlog4cow,
|
||||||
|
backlog4rebalance);
|
||||||
|
|
||||||
gc_cursor->mc_flags &= ~C_RECLAIMING;
|
gc_cursor->mc_flags &= ~C_RECLAIMING;
|
||||||
|
|
||||||
int err = mdbx_cursor_touch(gc_cursor);
|
int err = mdbx_cursor_touch(gc_cursor);
|
||||||
if (err == MDBX_SUCCESS && linear > 1)
|
mdbx_trace("== after-touch, backlog %u, err %d", backlog_size(txn), err);
|
||||||
err = mdbx_page_alloc(gc_cursor, linear, nullptr, MDBX_ALLOC_ALL);
|
|
||||||
|
|
||||||
while (err == MDBX_SUCCESS && backlog_size(txn) < backlog)
|
if (linear4list > 1 && err == MDBX_SUCCESS) {
|
||||||
|
err = mdbx_page_alloc(gc_cursor, linear4list, nullptr,
|
||||||
|
MDBX_ALLOC_GC | MDBX_ALLOC_CACHE);
|
||||||
|
mdbx_trace("== after-4linear, backlog %u, err %d", backlog_size(txn), err);
|
||||||
|
}
|
||||||
|
|
||||||
|
while (backlog_size(txn) < backlog4cow + linear4list && err == MDBX_SUCCESS)
|
||||||
err = mdbx_page_alloc(gc_cursor, 1, NULL, MDBX_ALLOC_GC);
|
err = mdbx_page_alloc(gc_cursor, 1, NULL, MDBX_ALLOC_GC);
|
||||||
|
|
||||||
gc_cursor->mc_flags |= C_RECLAIMING;
|
gc_cursor->mc_flags |= C_RECLAIMING;
|
||||||
|
mdbx_trace("<< backlog %u, err %d", backlog_size(txn), err);
|
||||||
return (err != MDBX_NOTFOUND) ? err : MDBX_SUCCESS;
|
return (err != MDBX_NOTFOUND) ? err : MDBX_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -5924,6 +5925,10 @@ retry:
|
|||||||
goto bailout;
|
goto bailout;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
rc = mdbx_prep_backlog(txn, &mc, MDBX_PNL_SIZEOF(txn->tw.retired_pages));
|
||||||
|
if (unlikely(rc != MDBX_SUCCESS))
|
||||||
|
goto bailout;
|
||||||
|
|
||||||
unsigned settled = 0, cleaned_gc_slot = 0, reused_gc_slot = 0,
|
unsigned settled = 0, cleaned_gc_slot = 0, reused_gc_slot = 0,
|
||||||
filled_gc_slot = ~0u;
|
filled_gc_slot = ~0u;
|
||||||
txnid_t cleaned_gc_id = 0, gc_rid = txn->tw.last_reclaimed;
|
txnid_t cleaned_gc_id = 0, gc_rid = txn->tw.last_reclaimed;
|
||||||
@ -6131,8 +6136,11 @@ retry:
|
|||||||
mdbx_debug_extra_print(" %" PRIaPGNO, txn->tw.retired_pages[i]);
|
mdbx_debug_extra_print(" %" PRIaPGNO, txn->tw.retired_pages[i]);
|
||||||
mdbx_debug_extra_print("%s", "\n");
|
mdbx_debug_extra_print("%s", "\n");
|
||||||
}
|
}
|
||||||
if (unlikely(amount != MDBX_PNL_SIZE(txn->tw.reclaimed_pglist)))
|
if (unlikely(amount != MDBX_PNL_SIZE(txn->tw.reclaimed_pglist))) {
|
||||||
|
mdbx_trace("%s.reclaimed-list changed %u -> %u, retry", dbg_prefix_mode,
|
||||||
|
amount, (unsigned)MDBX_PNL_SIZE(txn->tw.reclaimed_pglist));
|
||||||
goto retry /* rare case, but avoids GC fragmentation and one loop. */;
|
goto retry /* rare case, but avoids GC fragmentation and one loop. */;
|
||||||
|
}
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user