mirror of
https://github.com/isar/libmdbx.git
synced 2024-12-30 03:14:14 +08:00
mdbx: merge branch issue-269
into the devel
branch.
This commit is contained in:
commit
44fb240955
81
src/core.c
81
src/core.c
@ -3733,7 +3733,7 @@ static int mdbx_txn_end(MDBX_txn *txn, const unsigned mode);
|
||||
|
||||
__hot static struct page_result __must_check_result
|
||||
mdbx_page_get_ex(MDBX_cursor *const mc, const pgno_t pgno, txnid_t front);
|
||||
static __inline int __must_check_result mdbx_page_get(MDBX_cursor *mc,
|
||||
static __always_inline int __must_check_result mdbx_page_get(MDBX_cursor *mc,
|
||||
pgno_t pgno,
|
||||
MDBX_page **mp,
|
||||
txnid_t front) {
|
||||
@ -5791,7 +5791,8 @@ static txnid_t mdbx_find_oldest(const MDBX_txn *txn) {
|
||||
}
|
||||
|
||||
if (oldest != last_oldest) {
|
||||
mdbx_notice("update oldest %" PRIaTXN " -> %" PRIaTXN, last_oldest, oldest);
|
||||
mdbx_verbose("update oldest %" PRIaTXN " -> %" PRIaTXN, last_oldest,
|
||||
oldest);
|
||||
mdbx_tassert(txn, oldest >= lck->mti_oldest_reader.weak);
|
||||
atomic_store64(&lck->mti_oldest_reader, oldest, mo_Relaxed);
|
||||
}
|
||||
@ -10161,9 +10162,7 @@ int mdbx_txn_commit_ex(MDBX_txn *txn, MDBX_commit_latency *latency) {
|
||||
/* Update parent's DBs array */
|
||||
memcpy(parent->mt_dbs, txn->mt_dbs, txn->mt_numdbs * sizeof(MDBX_db));
|
||||
parent->mt_numdbs = txn->mt_numdbs;
|
||||
parent->mt_dbistate[FREE_DBI] = txn->mt_dbistate[FREE_DBI];
|
||||
parent->mt_dbistate[MAIN_DBI] = txn->mt_dbistate[MAIN_DBI];
|
||||
for (unsigned i = CORE_DBS; i < txn->mt_numdbs; i++) {
|
||||
for (unsigned i = 0; i < txn->mt_numdbs; i++) {
|
||||
/* preserve parent's status */
|
||||
const uint8_t state =
|
||||
txn->mt_dbistate[i] |
|
||||
@ -10258,6 +10257,14 @@ int mdbx_txn_commit_ex(MDBX_txn *txn, MDBX_commit_latency *latency) {
|
||||
if (unlikely(rc != MDBX_SUCCESS))
|
||||
goto fail;
|
||||
|
||||
txn->mt_dbs[FREE_DBI].md_mod_txnid = (txn->mt_dbistate[FREE_DBI] & DBI_DIRTY)
|
||||
? txn->mt_txnid
|
||||
: txn->mt_dbs[FREE_DBI].md_mod_txnid;
|
||||
|
||||
txn->mt_dbs[MAIN_DBI].md_mod_txnid = (txn->mt_dbistate[MAIN_DBI] & DBI_DIRTY)
|
||||
? txn->mt_txnid
|
||||
: txn->mt_dbs[MAIN_DBI].md_mod_txnid;
|
||||
|
||||
ts_2 = latency ? mdbx_osal_monotime() : 0;
|
||||
if (mdbx_audit_enabled()) {
|
||||
rc = mdbx_audit_ex(txn, MDBX_PNL_SIZE(txn->tw.retired_pages), true);
|
||||
@ -10277,7 +10284,6 @@ int mdbx_txn_commit_ex(MDBX_txn *txn, MDBX_commit_latency *latency) {
|
||||
ts_3 = latency ? mdbx_osal_monotime() : 0;
|
||||
|
||||
if (likely(rc == MDBX_SUCCESS)) {
|
||||
|
||||
const MDBX_meta *head = constmeta_prefer_last(env);
|
||||
MDBX_meta meta;
|
||||
memcpy(meta.mm_magic_and_version, head->mm_magic_and_version, 8);
|
||||
@ -10287,18 +10293,9 @@ int mdbx_txn_commit_ex(MDBX_txn *txn, MDBX_commit_latency *latency) {
|
||||
unaligned_poke_u64(4, meta.mm_pages_retired,
|
||||
unaligned_peek_u64(4, head->mm_pages_retired) +
|
||||
MDBX_PNL_SIZE(txn->tw.retired_pages));
|
||||
|
||||
meta.mm_geo = txn->mt_geo;
|
||||
meta.mm_dbs[FREE_DBI] = txn->mt_dbs[FREE_DBI];
|
||||
meta.mm_dbs[FREE_DBI].md_mod_txnid =
|
||||
(txn->mt_dbistate[FREE_DBI] & DBI_DIRTY)
|
||||
? txn->mt_txnid
|
||||
: txn->mt_dbs[FREE_DBI].md_mod_txnid;
|
||||
meta.mm_dbs[MAIN_DBI] = txn->mt_dbs[MAIN_DBI];
|
||||
meta.mm_dbs[MAIN_DBI].md_mod_txnid =
|
||||
(txn->mt_dbistate[MAIN_DBI] & DBI_DIRTY)
|
||||
? txn->mt_txnid
|
||||
: txn->mt_dbs[MAIN_DBI].md_mod_txnid;
|
||||
meta.mm_canary = txn->mt_canary;
|
||||
meta_set_txnid(env, &meta, txn->mt_txnid);
|
||||
|
||||
@ -10550,12 +10547,12 @@ static int mdbx_validate_meta(MDBX_env *env, MDBX_meta *const meta,
|
||||
meta->mm_dbs[FREE_DBI].md_entries ||
|
||||
meta->mm_dbs[FREE_DBI].md_leaf_pages ||
|
||||
meta->mm_dbs[FREE_DBI].md_overflow_pages)) {
|
||||
mdbx_warning("meta[%u] has false-empty GC, skip it", meta_number);
|
||||
mdbx_warning("meta[%u] has false-empty %s, skip it", meta_number, "GC");
|
||||
return MDBX_CORRUPTED;
|
||||
}
|
||||
} else if (unlikely(meta->mm_dbs[FREE_DBI].md_root >= meta->mm_geo.next)) {
|
||||
mdbx_warning("meta[%u] has invalid GC-root %" PRIaPGNO ", skip it",
|
||||
meta_number, meta->mm_dbs[FREE_DBI].md_root);
|
||||
mdbx_warning("meta[%u] has invalid %s-root %" PRIaPGNO ", skip it",
|
||||
meta_number, "GC", meta->mm_dbs[FREE_DBI].md_root);
|
||||
return MDBX_CORRUPTED;
|
||||
}
|
||||
|
||||
@ -10566,12 +10563,24 @@ static int mdbx_validate_meta(MDBX_env *env, MDBX_meta *const meta,
|
||||
meta->mm_dbs[MAIN_DBI].md_entries ||
|
||||
meta->mm_dbs[MAIN_DBI].md_leaf_pages ||
|
||||
meta->mm_dbs[MAIN_DBI].md_overflow_pages)) {
|
||||
mdbx_warning("meta[%u] has false-empty maindb", meta_number);
|
||||
mdbx_warning("meta[%u] has false-empty %s", meta_number, "MainDB");
|
||||
return MDBX_CORRUPTED;
|
||||
}
|
||||
} else if (unlikely(meta->mm_dbs[MAIN_DBI].md_root >= meta->mm_geo.next)) {
|
||||
mdbx_warning("meta[%u] has invalid maindb-root %" PRIaPGNO ", skip it",
|
||||
meta_number, meta->mm_dbs[MAIN_DBI].md_root);
|
||||
mdbx_warning("meta[%u] has invalid %s-root %" PRIaPGNO ", skip it",
|
||||
meta_number, "MainDB", meta->mm_dbs[MAIN_DBI].md_root);
|
||||
return MDBX_CORRUPTED;
|
||||
}
|
||||
|
||||
if (unlikely(meta->mm_dbs[FREE_DBI].md_mod_txnid > txnid)) {
|
||||
mdbx_warning("meta[%u] has wrong md_mod_txnid %" PRIaTXN " for %s, skip it",
|
||||
meta_number, meta->mm_dbs[FREE_DBI].md_mod_txnid, "GC");
|
||||
return MDBX_CORRUPTED;
|
||||
}
|
||||
|
||||
if (unlikely(meta->mm_dbs[MAIN_DBI].md_mod_txnid > txnid)) {
|
||||
mdbx_warning("meta[%u] has wrong md_mod_txnid %" PRIaTXN " for %s, skip it",
|
||||
meta_number, meta->mm_dbs[MAIN_DBI].md_mod_txnid, "MainDB");
|
||||
return MDBX_CORRUPTED;
|
||||
}
|
||||
|
||||
@ -11536,14 +11545,22 @@ mdbx_env_set_geometry(MDBX_env *env, intptr_t size_lower, intptr_t size_now,
|
||||
/* apply new params to opened environment */
|
||||
mdbx_ensure(env, pagesize == (intptr_t)env->me_psize);
|
||||
MDBX_meta meta;
|
||||
const MDBX_meta *head = nullptr;
|
||||
memset(&meta, 0, sizeof(meta));
|
||||
const MDBX_geo *current_geo;
|
||||
if (inside_txn) {
|
||||
current_geo = &env->me_txn->mt_geo;
|
||||
} else {
|
||||
head = constmeta_prefer_last(env);
|
||||
if (!inside_txn) {
|
||||
mdbx_assert(env, need_unlock);
|
||||
const MDBX_meta *head = constmeta_prefer_last(env);
|
||||
meta = *head;
|
||||
const txnid_t txnid = safe64_txnid_next(constmeta_txnid(env, &meta));
|
||||
if (unlikely(txnid > MAX_TXNID)) {
|
||||
rc = MDBX_TXN_FULL;
|
||||
mdbx_error("txnid overflow, raise %d", rc);
|
||||
goto bailout;
|
||||
}
|
||||
meta_set_txnid(env, &meta, txnid);
|
||||
current_geo = &meta.mm_geo;
|
||||
} else {
|
||||
current_geo = &env->me_txn->mt_geo;
|
||||
}
|
||||
|
||||
MDBX_geo new_geo;
|
||||
@ -11614,24 +11631,14 @@ mdbx_env_set_geometry(MDBX_env *env, intptr_t size_lower, intptr_t size_now,
|
||||
false);
|
||||
if (unlikely(rc != MDBX_SUCCESS))
|
||||
goto bailout;
|
||||
mdbx_assert(env, (head == nullptr) == inside_txn);
|
||||
if (head)
|
||||
head = /* base address could be changed */ constmeta_prefer_last(env);
|
||||
}
|
||||
if (inside_txn) {
|
||||
env->me_txn->mt_geo = new_geo;
|
||||
env->me_txn->mt_flags |= MDBX_TXN_DIRTY;
|
||||
} else {
|
||||
meta.mm_geo = new_geo;
|
||||
const txnid_t txnid = safe64_txnid_next(constmeta_txnid(env, head));
|
||||
if (unlikely(txnid > MAX_TXNID)) {
|
||||
rc = MDBX_TXN_FULL;
|
||||
mdbx_error("txnid overflow, raise %d", rc);
|
||||
} else {
|
||||
meta_set_txnid(env, &meta, txnid);
|
||||
rc = mdbx_sync_locked(env, env->me_flags, &meta);
|
||||
}
|
||||
}
|
||||
|
||||
if (likely(rc == MDBX_SUCCESS)) {
|
||||
/* store new geo to env to avoid influences */
|
||||
@ -13717,6 +13724,7 @@ __hot static int mdbx_page_search(MDBX_cursor *mc, const MDBX_val *key,
|
||||
pp_txnid = /* mc->mc_db->md_mod_txnid maybe zero in a legacy DB */ pp_txnid
|
||||
? pp_txnid
|
||||
: mc->mc_txn->mt_txnid;
|
||||
if ((mc->mc_txn->mt_flags & MDBX_TXN_RDONLY) == 0) {
|
||||
MDBX_txn *scan = mc->mc_txn;
|
||||
do
|
||||
if ((scan->mt_flags & MDBX_TXN_DIRTY) &&
|
||||
@ -13726,6 +13734,7 @@ __hot static int mdbx_page_search(MDBX_cursor *mc, const MDBX_val *key,
|
||||
break;
|
||||
}
|
||||
while (unlikely((scan = scan->mt_parent) != nullptr));
|
||||
}
|
||||
if (unlikely((rc = mdbx_page_get(mc, root, &mc->mc_pg[0], pp_txnid)) != 0))
|
||||
return rc;
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user