mirror of
https://github.com/isar/libmdbx.git
synced 2025-08-25 21:54:28 +08:00
mdbx: новые настройки clang-format (косметика).
This commit is contained in:
118
src/coherency.c
118
src/coherency.c
@@ -4,8 +4,7 @@
|
||||
#include "internals.h"
|
||||
|
||||
/* check against https://libmdbx.dqdkfa.ru/dead-github/issues/269 */
|
||||
static bool coherency_check(const MDBX_env *env, const txnid_t txnid,
|
||||
const volatile tree_t *trees,
|
||||
static bool coherency_check(const MDBX_env *env, const txnid_t txnid, const volatile tree_t *trees,
|
||||
const volatile meta_t *meta, bool report) {
|
||||
const txnid_t freedb_mod_txnid = trees[FREE_DBI].mod_txnid;
|
||||
const txnid_t maindb_mod_txnid = trees[MAIN_DBI].mod_txnid;
|
||||
@@ -13,67 +12,42 @@ static bool coherency_check(const MDBX_env *env, const txnid_t txnid,
|
||||
|
||||
const pgno_t freedb_root_pgno = trees[FREE_DBI].root;
|
||||
const page_t *freedb_root =
|
||||
(env->dxb_mmap.base && freedb_root_pgno < last_pgno)
|
||||
? pgno2page(env, freedb_root_pgno)
|
||||
: nullptr;
|
||||
(env->dxb_mmap.base && freedb_root_pgno < last_pgno) ? pgno2page(env, freedb_root_pgno) : nullptr;
|
||||
|
||||
const pgno_t maindb_root_pgno = trees[MAIN_DBI].root;
|
||||
const page_t *maindb_root =
|
||||
(env->dxb_mmap.base && maindb_root_pgno < last_pgno)
|
||||
? pgno2page(env, maindb_root_pgno)
|
||||
: nullptr;
|
||||
const uint64_t magic_and_version =
|
||||
unaligned_peek_u64_volatile(4, &meta->magic_and_version);
|
||||
(env->dxb_mmap.base && maindb_root_pgno < last_pgno) ? pgno2page(env, maindb_root_pgno) : nullptr;
|
||||
const uint64_t magic_and_version = unaligned_peek_u64_volatile(4, &meta->magic_and_version);
|
||||
|
||||
bool ok = true;
|
||||
if (freedb_root_pgno != P_INVALID &&
|
||||
unlikely(freedb_root_pgno >= last_pgno)) {
|
||||
if (freedb_root_pgno != P_INVALID && unlikely(freedb_root_pgno >= last_pgno)) {
|
||||
if (report)
|
||||
WARNING(
|
||||
"catch invalid %s-db root %" PRIaPGNO " for meta_txnid %" PRIaTXN
|
||||
" %s",
|
||||
"free", freedb_root_pgno, txnid,
|
||||
(env->stuck_meta < 0)
|
||||
? "(workaround for incoherent flaw of unified page/buffer cache)"
|
||||
: "(wagering meta)");
|
||||
WARNING("catch invalid %s-db root %" PRIaPGNO " for meta_txnid %" PRIaTXN " %s", "free", freedb_root_pgno, txnid,
|
||||
(env->stuck_meta < 0) ? "(workaround for incoherent flaw of unified page/buffer cache)"
|
||||
: "(wagering meta)");
|
||||
ok = false;
|
||||
}
|
||||
if (maindb_root_pgno != P_INVALID &&
|
||||
unlikely(maindb_root_pgno >= last_pgno)) {
|
||||
if (maindb_root_pgno != P_INVALID && unlikely(maindb_root_pgno >= last_pgno)) {
|
||||
if (report)
|
||||
WARNING(
|
||||
"catch invalid %s-db root %" PRIaPGNO " for meta_txnid %" PRIaTXN
|
||||
" %s",
|
||||
"main", maindb_root_pgno, txnid,
|
||||
(env->stuck_meta < 0)
|
||||
? "(workaround for incoherent flaw of unified page/buffer cache)"
|
||||
: "(wagering meta)");
|
||||
WARNING("catch invalid %s-db root %" PRIaPGNO " for meta_txnid %" PRIaTXN " %s", "main", maindb_root_pgno, txnid,
|
||||
(env->stuck_meta < 0) ? "(workaround for incoherent flaw of unified page/buffer cache)"
|
||||
: "(wagering meta)");
|
||||
ok = false;
|
||||
}
|
||||
if (unlikely(txnid < freedb_mod_txnid ||
|
||||
(!freedb_mod_txnid && freedb_root &&
|
||||
likely(magic_and_version == MDBX_DATA_MAGIC)))) {
|
||||
(!freedb_mod_txnid && freedb_root && likely(magic_and_version == MDBX_DATA_MAGIC)))) {
|
||||
if (report)
|
||||
WARNING(
|
||||
"catch invalid %s-db.mod_txnid %" PRIaTXN " for meta_txnid %" PRIaTXN
|
||||
" %s",
|
||||
"free", freedb_mod_txnid, txnid,
|
||||
(env->stuck_meta < 0)
|
||||
? "(workaround for incoherent flaw of unified page/buffer cache)"
|
||||
: "(wagering meta)");
|
||||
"catch invalid %s-db.mod_txnid %" PRIaTXN " for meta_txnid %" PRIaTXN " %s", "free", freedb_mod_txnid, txnid,
|
||||
(env->stuck_meta < 0) ? "(workaround for incoherent flaw of unified page/buffer cache)" : "(wagering meta)");
|
||||
ok = false;
|
||||
}
|
||||
if (unlikely(txnid < maindb_mod_txnid ||
|
||||
(!maindb_mod_txnid && maindb_root &&
|
||||
likely(magic_and_version == MDBX_DATA_MAGIC)))) {
|
||||
(!maindb_mod_txnid && maindb_root && likely(magic_and_version == MDBX_DATA_MAGIC)))) {
|
||||
if (report)
|
||||
WARNING(
|
||||
"catch invalid %s-db.mod_txnid %" PRIaTXN " for meta_txnid %" PRIaTXN
|
||||
" %s",
|
||||
"main", maindb_mod_txnid, txnid,
|
||||
(env->stuck_meta < 0)
|
||||
? "(workaround for incoherent flaw of unified page/buffer cache)"
|
||||
: "(wagering meta)");
|
||||
"catch invalid %s-db.mod_txnid %" PRIaTXN " for meta_txnid %" PRIaTXN " %s", "main", maindb_mod_txnid, txnid,
|
||||
(env->stuck_meta < 0) ? "(workaround for incoherent flaw of unified page/buffer cache)" : "(wagering meta)");
|
||||
ok = false;
|
||||
}
|
||||
|
||||
@@ -81,15 +55,13 @@ static bool coherency_check(const MDBX_env *env, const txnid_t txnid,
|
||||
* в пределах текущего отображения. Иначе возможны SIGSEGV до переноса
|
||||
* вызова coherency_check_head() после dxb_resize() внутри txn_renew(). */
|
||||
if (likely(freedb_root && freedb_mod_txnid &&
|
||||
(size_t)ptr_dist(env->dxb_mmap.base, freedb_root) <
|
||||
env->dxb_mmap.limit)) {
|
||||
(size_t)ptr_dist(env->dxb_mmap.base, freedb_root) < env->dxb_mmap.limit)) {
|
||||
VALGRIND_MAKE_MEM_DEFINED(freedb_root, sizeof(freedb_root->txnid));
|
||||
MDBX_ASAN_UNPOISON_MEMORY_REGION(freedb_root, sizeof(freedb_root->txnid));
|
||||
const txnid_t root_txnid = freedb_root->txnid;
|
||||
if (unlikely(root_txnid != freedb_mod_txnid)) {
|
||||
if (report)
|
||||
WARNING("catch invalid root_page %" PRIaPGNO " mod_txnid %" PRIaTXN
|
||||
" for %s-db.mod_txnid %" PRIaTXN " %s",
|
||||
WARNING("catch invalid root_page %" PRIaPGNO " mod_txnid %" PRIaTXN " for %s-db.mod_txnid %" PRIaTXN " %s",
|
||||
freedb_root_pgno, root_txnid, "free", freedb_mod_txnid,
|
||||
(env->stuck_meta < 0) ? "(workaround for incoherent flaw of "
|
||||
"unified page/buffer cache)"
|
||||
@@ -98,15 +70,13 @@ static bool coherency_check(const MDBX_env *env, const txnid_t txnid,
|
||||
}
|
||||
}
|
||||
if (likely(maindb_root && maindb_mod_txnid &&
|
||||
(size_t)ptr_dist(env->dxb_mmap.base, maindb_root) <
|
||||
env->dxb_mmap.limit)) {
|
||||
(size_t)ptr_dist(env->dxb_mmap.base, maindb_root) < env->dxb_mmap.limit)) {
|
||||
VALGRIND_MAKE_MEM_DEFINED(maindb_root, sizeof(maindb_root->txnid));
|
||||
MDBX_ASAN_UNPOISON_MEMORY_REGION(maindb_root, sizeof(maindb_root->txnid));
|
||||
const txnid_t root_txnid = maindb_root->txnid;
|
||||
if (unlikely(root_txnid != maindb_mod_txnid)) {
|
||||
if (report)
|
||||
WARNING("catch invalid root_page %" PRIaPGNO " mod_txnid %" PRIaTXN
|
||||
" for %s-db.mod_txnid %" PRIaTXN " %s",
|
||||
WARNING("catch invalid root_page %" PRIaPGNO " mod_txnid %" PRIaTXN " for %s-db.mod_txnid %" PRIaTXN " %s",
|
||||
maindb_root_pgno, root_txnid, "main", maindb_mod_txnid,
|
||||
(env->stuck_meta < 0) ? "(workaround for incoherent flaw of "
|
||||
"unified page/buffer cache)"
|
||||
@@ -116,24 +86,19 @@ static bool coherency_check(const MDBX_env *env, const txnid_t txnid,
|
||||
}
|
||||
if (unlikely(!ok) && report)
|
||||
env->lck->pgops.incoherence.weak =
|
||||
(env->lck->pgops.incoherence.weak >= INT32_MAX)
|
||||
? INT32_MAX
|
||||
: env->lck->pgops.incoherence.weak + 1;
|
||||
(env->lck->pgops.incoherence.weak >= INT32_MAX) ? INT32_MAX : env->lck->pgops.incoherence.weak + 1;
|
||||
return ok;
|
||||
}
|
||||
|
||||
__cold int coherency_timeout(uint64_t *timestamp, intptr_t pgno,
|
||||
const MDBX_env *env) {
|
||||
__cold int coherency_timeout(uint64_t *timestamp, intptr_t pgno, const MDBX_env *env) {
|
||||
if (likely(timestamp && *timestamp == 0))
|
||||
*timestamp = osal_monotime();
|
||||
else if (unlikely(!timestamp || osal_monotime() - *timestamp >
|
||||
osal_16dot16_to_monotime(65536 / 10))) {
|
||||
else if (unlikely(!timestamp || osal_monotime() - *timestamp > osal_16dot16_to_monotime(65536 / 10))) {
|
||||
if (pgno >= 0 && pgno != env->stuck_meta)
|
||||
ERROR("bailout waiting for %" PRIuSIZE " page arrival %s", pgno,
|
||||
"(workaround for incoherent flaw of unified page/buffer cache)");
|
||||
else if (env->stuck_meta < 0)
|
||||
ERROR("bailout waiting for valid snapshot (%s)",
|
||||
"workaround for incoherent flaw of unified page/buffer cache");
|
||||
ERROR("bailout waiting for valid snapshot (%s)", "workaround for incoherent flaw of unified page/buffer cache");
|
||||
return MDBX_PROBLEM;
|
||||
}
|
||||
|
||||
@@ -152,28 +117,23 @@ __cold int coherency_timeout(uint64_t *timestamp, intptr_t pgno,
|
||||
|
||||
/* check with timeout as the workaround
|
||||
* for https://libmdbx.dqdkfa.ru/dead-github/issues/269 */
|
||||
__hot int coherency_fetch_head(MDBX_txn *txn, const meta_ptr_t head,
|
||||
uint64_t *timestamp) {
|
||||
__hot int coherency_fetch_head(MDBX_txn *txn, const meta_ptr_t head, uint64_t *timestamp) {
|
||||
/* Copy the DB info and flags */
|
||||
txn->txnid = head.txnid;
|
||||
txn->geo = head.ptr_c->geometry;
|
||||
memcpy(txn->dbs, &head.ptr_c->trees, sizeof(head.ptr_c->trees));
|
||||
STATIC_ASSERT(sizeof(head.ptr_c->trees) == CORE_DBS * sizeof(tree_t));
|
||||
VALGRIND_MAKE_MEM_UNDEFINED(txn->dbs + CORE_DBS,
|
||||
txn->env->max_dbi - CORE_DBS);
|
||||
VALGRIND_MAKE_MEM_UNDEFINED(txn->dbs + CORE_DBS, txn->env->max_dbi - CORE_DBS);
|
||||
txn->canary = head.ptr_c->canary;
|
||||
|
||||
if (unlikely(!coherency_check(txn->env, head.txnid, txn->dbs, head.ptr_v,
|
||||
*timestamp == 0) ||
|
||||
if (unlikely(!coherency_check(txn->env, head.txnid, txn->dbs, head.ptr_v, *timestamp == 0) ||
|
||||
txn->txnid != meta_txnid(head.ptr_v)))
|
||||
return coherency_timeout(timestamp, -1, txn->env);
|
||||
|
||||
if (unlikely(txn->dbs[FREE_DBI].flags != MDBX_INTEGERKEY)) {
|
||||
if ((txn->dbs[FREE_DBI].flags & DB_PERSISTENT_FLAGS) != MDBX_INTEGERKEY ||
|
||||
unaligned_peek_u64(4, &head.ptr_c->magic_and_version) ==
|
||||
MDBX_DATA_MAGIC) {
|
||||
ERROR("unexpected/invalid db-flags 0x%x for %s", txn->dbs[FREE_DBI].flags,
|
||||
"GC/FreeDB");
|
||||
unaligned_peek_u64(4, &head.ptr_c->magic_and_version) == MDBX_DATA_MAGIC) {
|
||||
ERROR("unexpected/invalid db-flags 0x%x for %s", txn->dbs[FREE_DBI].flags, "GC/FreeDB");
|
||||
return MDBX_INCOMPATIBLE;
|
||||
}
|
||||
txn->dbs[FREE_DBI].flags &= DB_PERSISTENT_FLAGS;
|
||||
@@ -183,23 +143,19 @@ __hot int coherency_fetch_head(MDBX_txn *txn, const meta_ptr_t head,
|
||||
return MDBX_SUCCESS;
|
||||
}
|
||||
|
||||
int coherency_check_written(const MDBX_env *env, const txnid_t txnid,
|
||||
const volatile meta_t *meta, const intptr_t pgno,
|
||||
int coherency_check_written(const MDBX_env *env, const txnid_t txnid, const volatile meta_t *meta, const intptr_t pgno,
|
||||
uint64_t *timestamp) {
|
||||
const bool report = !(timestamp && *timestamp);
|
||||
const txnid_t head_txnid = meta_txnid(meta);
|
||||
if (likely(head_txnid >= MIN_TXNID && head_txnid >= txnid)) {
|
||||
if (likely(
|
||||
coherency_check(env, head_txnid, &meta->trees.gc, meta, report))) {
|
||||
if (likely(coherency_check(env, head_txnid, &meta->trees.gc, meta, report))) {
|
||||
eASSERT(env, meta->trees.gc.flags == MDBX_INTEGERKEY);
|
||||
eASSERT(env, check_table_flags(meta->trees.main.flags));
|
||||
return MDBX_SUCCESS;
|
||||
}
|
||||
} else if (report) {
|
||||
env->lck->pgops.incoherence.weak =
|
||||
(env->lck->pgops.incoherence.weak >= INT32_MAX)
|
||||
? INT32_MAX
|
||||
: env->lck->pgops.incoherence.weak + 1;
|
||||
(env->lck->pgops.incoherence.weak >= INT32_MAX) ? INT32_MAX : env->lck->pgops.incoherence.weak + 1;
|
||||
WARNING("catch %s txnid %" PRIaTXN " for meta_%" PRIaPGNO " %s",
|
||||
(head_txnid < MIN_TXNID) ? "invalid" : "unexpected", head_txnid,
|
||||
bytes2pgno(env, ptr_dist(meta, env->dxb_mmap.base)),
|
||||
@@ -208,9 +164,7 @@ int coherency_check_written(const MDBX_env *env, const txnid_t txnid,
|
||||
return coherency_timeout(timestamp, pgno, env);
|
||||
}
|
||||
|
||||
bool coherency_check_meta(const MDBX_env *env, const volatile meta_t *meta,
|
||||
bool report) {
|
||||
bool coherency_check_meta(const MDBX_env *env, const volatile meta_t *meta, bool report) {
|
||||
uint64_t timestamp = 0;
|
||||
return coherency_check_written(env, 0, meta, -1,
|
||||
report ? ×tamp : nullptr) == MDBX_SUCCESS;
|
||||
return coherency_check_written(env, 0, meta, -1, report ? ×tamp : nullptr) == MDBX_SUCCESS;
|
||||
}
|
||||
|
Reference in New Issue
Block a user