summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGeorge Hazan <ghazan@miranda.im>2018-09-20 09:51:43 +0300
committerGeorge Hazan <ghazan@miranda.im>2018-09-20 09:51:43 +0300
commit97a52219651508b12c40427d01fcfbd9ab206df0 (patch)
tree4ec5986e0b74a7c2c62c1a094e24c15ca18e315b
parent77ea5b95cd68a295068394e9d0c505f0b26221ba (diff)
final fix for libmdbx problem with GC
-rw-r--r--libs/libmdbx/src/src/mdbx.c38
-rw-r--r--libs/libmdbx/src/src/tools/mdbx_chk.c6
-rw-r--r--plugins/Dbx_mdbx/src/dbintf.cpp4
3 files changed, 25 insertions, 23 deletions
diff --git a/libs/libmdbx/src/src/mdbx.c b/libs/libmdbx/src/src/mdbx.c
index e8be0832f1..0390a219f3 100644
--- a/libs/libmdbx/src/src/mdbx.c
+++ b/libs/libmdbx/src/src/mdbx.c
@@ -2136,13 +2136,13 @@ static const char *mdbx_durable_str(const MDBX_meta *const meta) {
/* Find oldest txnid still referenced. */
static txnid_t mdbx_find_oldest(MDBX_txn *txn) {
mdbx_tassert(txn, (txn->mt_flags & MDBX_RDONLY) == 0);
- const MDBX_env *env = txn->mt_env;
+ MDBX_env *env = txn->mt_env;
const txnid_t edge = mdbx_reclaiming_detent(env);
mdbx_tassert(txn, edge <= txn->mt_txnid - 1);
MDBX_lockinfo *const lck = env->me_lck;
if (unlikely(env->me_lck == NULL /* exclusive mode */))
- return edge;
+ return env->me_oldest_stub = edge;
const txnid_t last_oldest = lck->mti_oldest;
mdbx_tassert(txn, edge >= last_oldest);
@@ -3807,6 +3807,9 @@ static int mdbx_update_gc(MDBX_txn *txn) {
if (unlikely(rc != MDBX_SUCCESS))
goto bailout;
+ mc.mc_next = txn->mt_cursors[FREE_DBI];
+ txn->mt_cursors[FREE_DBI] = &mc;
+
retry:
mdbx_trace(" >> restart");
mdbx_tassert(txn, mdbx_pnl_check(env->me_reclaimed_pglist, true));
@@ -3853,7 +3856,7 @@ retry:
mdbx_trace("%s.cleanup-reclaimed-id [%u]%" PRIaTXN, dbg_prefix_mode,
cleaned_gc_slot, cleaned_gc_id);
mc.mc_flags |= C_RECLAIMING;
- WITH_CURSOR_TRACKING(mc, rc = mdbx_cursor_del(&mc, 0));
+ rc = mdbx_cursor_del(&mc, 0);
mc.mc_flags ^= C_RECLAIMING;
if (unlikely(rc != MDBX_SUCCESS))
goto bailout;
@@ -3872,12 +3875,12 @@ retry:
if (unlikely(rc != MDBX_SUCCESS))
goto bailout;
cleaned_gc_id = head_gc_id = *(txnid_t *)key.iov_base;
- mdbx_tassert(txn, cleaned_gc_id < *env->me_oldest);
mdbx_tassert(txn, cleaned_gc_id <= env->me_last_reclaimed);
+ mdbx_tassert(txn, cleaned_gc_id < *env->me_oldest);
mdbx_trace("%s.cleanup-reclaimed-id %" PRIaTXN, dbg_prefix_mode,
cleaned_gc_id);
mc.mc_flags |= C_RECLAIMING;
- WITH_CURSOR_TRACKING(mc, rc = mdbx_cursor_del(&mc, 0));
+ rc = mdbx_cursor_del(&mc, 0);
mc.mc_flags ^= C_RECLAIMING;
if (unlikely(rc != MDBX_SUCCESS))
goto bailout;
@@ -4040,8 +4043,7 @@ retry:
key.iov_base = &txn->mt_txnid;
do {
data.iov_len = MDBX_PNL_SIZEOF(txn->mt_befree_pages);
- WITH_CURSOR_TRACKING(
- mc, rc = mdbx_cursor_put(&mc, &key, &data, MDBX_RESERVE));
+ rc = mdbx_cursor_put(&mc, &key, &data, MDBX_RESERVE);
if (unlikely(rc != MDBX_SUCCESS))
goto bailout;
/* Retry if mt_befree_pages[] grew during the Put() */
@@ -4250,9 +4252,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);
- WITH_CURSOR_TRACKING(mc,
- 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));
if (unlikely(rc != MDBX_SUCCESS))
goto bailout;
@@ -4349,15 +4349,14 @@ retry:
if (unlikely(chunk > left)) {
mdbx_trace("%s: chunk %u > left %u, @%" PRIaTXN, dbg_prefix_mode, chunk,
left, fill_gc_id);
- chunk = left;
- if (loop < 3) {
- mc.mc_flags ^= C_GCFREEZE;
+ if (loop < 5 || chunk - left > env->me_maxgc_ov1page) {
data.iov_len = (left + 1) * sizeof(pgno_t);
+ if (loop < 21)
+ mc.mc_flags -= C_GCFREEZE;
}
+ chunk = left;
}
- WITH_CURSOR_TRACKING(
- mc,
- rc = mdbx_cursor_put(&mc, &key, &data, MDBX_CURRENT | MDBX_RESERVE));
+ rc = mdbx_cursor_put(&mc, &key, &data, MDBX_CURRENT | MDBX_RESERVE);
mc.mc_flags &= ~(C_RECLAIMING | C_GCFREEZE);
if (unlikely(rc != MDBX_SUCCESS))
goto bailout;
@@ -4427,6 +4426,8 @@ retry:
cleaned_gc_slot == MDBX_PNL_SIZE(txn->mt_lifo_reclaimed));
bailout:
+ txn->mt_cursors[FREE_DBI] = mc.mc_next;
+
if (txn->mt_lifo_reclaimed) {
MDBX_PNL_SIZE(txn->mt_lifo_reclaimed) = 0;
if (txn != env->me_txn0) {
@@ -9848,7 +9849,7 @@ static int mdbx_node_move(MDBX_cursor *csrc, MDBX_cursor *cdst, int fromleft) {
mdbx_cassert(cdst, cdst->mc_top > 0);
if (cdst->mc_ki[cdst->mc_top - 1] != 0) {
MDBX_val key;
- if (IS_LEAF2(psrc)) {
+ if (IS_LEAF2(pdst)) {
key.iov_len = pdst->mp_leaf2_ksize;
key.iov_base = LEAF2KEY(pdst, 0, key.iov_len);
} else {
@@ -10889,7 +10890,7 @@ static int mdbx_page_split(MDBX_cursor *mc, const MDBX_val *newkey,
switch (PAGETYPE(rp)) {
case P_BRANCH: {
mdbx_cassert(mc, (nflags & (F_BIGDATA | F_SUBDATA | F_DUPDATA)) == 0);
- mdbx_cassert(mc, newpgno != 0 || newpgno != P_INVALID);
+ mdbx_cassert(mc, newpgno != 0 && newpgno != P_INVALID);
rc = mdbx_node_add_branch(mc, 0, newkey, newpgno);
} break;
case P_LEAF: {
@@ -10949,6 +10950,7 @@ static int mdbx_page_split(MDBX_cursor *mc, const MDBX_val *newkey,
} break;
case P_LEAF: {
mdbx_cassert(mc, pgno == 0);
+ mdbx_cassert(mc, rdata != NULL);
rc = mdbx_node_add_leaf(mc, n, &rkey, rdata, flags);
} break;
/* case P_LEAF | P_LEAF2: {
diff --git a/libs/libmdbx/src/src/tools/mdbx_chk.c b/libs/libmdbx/src/src/tools/mdbx_chk.c
index d11bef54c9..ca6c56fa2c 100644
--- a/libs/libmdbx/src/src/tools/mdbx_chk.c
+++ b/libs/libmdbx/src/src/tools/mdbx_chk.c
@@ -420,10 +420,10 @@ static int handle_freedb(const uint64_t record_number, const MDBX_val *key,
"%" PRIuSIZE " > %" PRIuSIZE " (corruption)",
(number + 1) * sizeof(pgno_t), data->iov_len);
number = data->iov_len / sizeof(pgno_t) - 1;
- } else if (data->iov_len - (number + 1) * sizeof(pgno_t) >
- /* LY: allow gap upto half of page. it is ok
+ } else if (data->iov_len - (number + 1) * sizeof(pgno_t) >=
+ /* LY: allow gap upto one page. it is ok
* and better than shink-and-retry inside mdbx_update_gc() */
- envstat.ms_psize / 2)
+ envstat.ms_psize)
problem_add("entry", record_number, "extra idl space",
"%" PRIuSIZE " < %" PRIuSIZE " (minor, not a trouble)",
(number + 1) * sizeof(pgno_t), data->iov_len);
diff --git a/plugins/Dbx_mdbx/src/dbintf.cpp b/plugins/Dbx_mdbx/src/dbintf.cpp
index 93463f9850..9cbbf2656d 100644
--- a/plugins/Dbx_mdbx/src/dbintf.cpp
+++ b/plugins/Dbx_mdbx/src/dbintf.cpp
@@ -239,11 +239,11 @@ void CDbxMDBX::SetCacheSafetyMode(BOOL bIsSet)
static void assert_func(const MDBX_env*, const char *msg, const char *function, unsigned line)
{
-/* Netlib_Logf(nullptr, "MDBX: assertion failed (%s, %d): %s", function, line, msg);
+ Netlib_Logf(nullptr, "MDBX: assertion failed (%s, %d): %s", function, line, msg);
#if defined(_DEBUG)
_wassert(_A2T(msg), _A2T(function), line);
- #endif */
+ #endif
}
int CDbxMDBX::Map()