mdbx: a whole snapshot inside mdbx_env_info_ex().

This commit is contained in:
Leonid Yuriev 2021-11-07 21:17:15 +03:00
parent 0c3a5da3cb
commit 96139eef48

View File

@ -19378,31 +19378,11 @@ __cold int mdbx_env_info(const MDBX_env *env, MDBX_envinfo *info,
}
#endif /* LIBMDBX_NO_EXPORTS_LEGACY_API */
__cold int mdbx_env_info_ex(const MDBX_env *env, const MDBX_txn *txn,
MDBX_envinfo *arg, size_t bytes) {
if (unlikely((env == NULL && txn == NULL) || arg == NULL))
return MDBX_EINVAL;
if (txn) {
int err = check_txn(txn, MDBX_TXN_BLOCKED);
if (unlikely(err != MDBX_SUCCESS))
return err;
}
if (env) {
int err = check_env(env, false);
if (unlikely(err != MDBX_SUCCESS))
return err;
if (txn && unlikely(txn->mt_env != env))
return MDBX_EINVAL;
} else {
env = txn->mt_env;
}
__cold static int fetch_envinfo_ex(const MDBX_env *env, const MDBX_txn *txn,
MDBX_envinfo *arg, const size_t bytes) {
const size_t size_before_bootid = offsetof(MDBX_envinfo, mi_bootid);
const size_t size_before_pgop_stat = offsetof(MDBX_envinfo, mi_pgop_stat);
if (unlikely(bytes != sizeof(MDBX_envinfo)) && bytes != size_before_bootid &&
bytes != size_before_pgop_stat)
return MDBX_EINVAL;
/* is the environment open? (https://github.com/erthink/libmdbx/issues/171) */
if (unlikely(!env->me_map)) {
@ -19432,8 +19412,6 @@ __cold int mdbx_env_info_ex(const MDBX_env *env, const MDBX_txn *txn,
const MDBX_meta *const meta0 = METAPAGE(env, 0);
const MDBX_meta *const meta1 = METAPAGE(env, 1);
const MDBX_meta *const meta2 = METAPAGE(env, 2);
pgno_t unsynced_pages;
while (1) {
if (unlikely(env->me_flags & MDBX_FATAL_ERROR))
return MDBX_PANIC;
@ -19469,26 +19447,12 @@ __cold int mdbx_env_info_ex(const MDBX_env *env, const MDBX_txn *txn,
arg->mi_geo.upper = pgno2bytes(env, txn_meta->mm_geo.upper);
arg->mi_geo.shrink = pgno2bytes(env, pv2pages(txn_meta->mm_geo.shrink_pv));
arg->mi_geo.grow = pgno2bytes(env, pv2pages(txn_meta->mm_geo.grow_pv));
unsynced_pages =
const pgno_t unsynced_pages =
atomic_load32(&env->me_lck->mti_unsynced_pages, mo_Relaxed) +
(atomic_load32(&env->me_lck->mti_meta_sync_txnid, mo_Relaxed) !=
(uint32_t)arg->mi_last_pgno);
arg->mi_mapsize = env->me_dxb_mmap.limit;
mdbx_compiler_barrier();
if (likely(arg->mi_meta0_txnid == mdbx_meta_txnid_fluid(env, meta0) &&
arg->mi_meta0_sign ==
unaligned_peek_u64(4, meta0->mm_datasync_sign) &&
arg->mi_meta1_txnid == mdbx_meta_txnid_fluid(env, meta1) &&
arg->mi_meta1_sign ==
unaligned_peek_u64(4, meta1->mm_datasync_sign) &&
arg->mi_meta2_txnid == mdbx_meta_txnid_fluid(env, meta2) &&
arg->mi_meta2_sign ==
unaligned_peek_u64(4, meta2->mm_datasync_sign) &&
recent_meta == mdbx_meta_head(env) &&
arg->mi_recent_txnid == mdbx_meta_txnid_fluid(env, recent_meta)))
break;
}
const MDBX_lockinfo *const lck = env->me_lck;
arg->mi_maxreaders = env->me_maxreaders;
@ -19555,9 +19519,51 @@ __cold int mdbx_env_info_ex(const MDBX_env *env, const MDBX_txn *txn,
}
}
mdbx_compiler_barrier();
return MDBX_SUCCESS;
}
__cold int mdbx_env_info_ex(const MDBX_env *env, const MDBX_txn *txn,
MDBX_envinfo *arg, size_t bytes) {
if (unlikely((env == NULL && txn == NULL) || arg == NULL))
return MDBX_EINVAL;
if (txn) {
int err = check_txn(txn, MDBX_TXN_BLOCKED);
if (unlikely(err != MDBX_SUCCESS))
return err;
}
if (env) {
int err = check_env(env, false);
if (unlikely(err != MDBX_SUCCESS))
return err;
if (txn && unlikely(txn->mt_env != env))
return MDBX_EINVAL;
} else {
env = txn->mt_env;
}
const size_t size_before_bootid = offsetof(MDBX_envinfo, mi_bootid);
const size_t size_before_pgop_stat = offsetof(MDBX_envinfo, mi_pgop_stat);
if (unlikely(bytes != sizeof(MDBX_envinfo)) && bytes != size_before_bootid &&
bytes != size_before_pgop_stat)
return MDBX_EINVAL;
MDBX_envinfo snap;
int rc = fetch_envinfo_ex(env, txn, &snap, sizeof(snap));
if (unlikely(rc != MDBX_SUCCESS))
return rc;
while (1) {
rc = fetch_envinfo_ex(env, txn, arg, sizeof(bytes));
if (unlikely(rc != MDBX_SUCCESS))
return rc;
if (likely(memcmp(&snap, arg, bytes) == 0))
return MDBX_SUCCESS;
memcpy(&snap, arg, bytes);
}
}
static __inline MDBX_cmp_func *get_default_keycmp(unsigned flags) {
return (flags & MDBX_REVERSEKEY)
? cmp_reverse