mdbx: возможность логирования ошибок возвращаемых из API (return LOG_IFERR).

Возможность полезная, но пожалуй еще нуждается в доработке и/или
до-осмыслении. Основное неудобство в нестыковке с основным логированием.

С одной стороны, сообщение об ошибках следует выводить с
уровнем/severity MDBX_LOG_ERROR. Однако, это замусоривает и ломает
тесты.

Поэтому сейчас при возвращении ошибок из API сообщения логируются
MDBX_LOG_ERROR, но производится это только при включении уровня
логирования MDBX_LOG_DEBUG или более детальном.
This commit is contained in:
Леонид Юрьев (Leonid Yuriev)
2024-11-25 21:20:02 +03:00
parent 9daff17c82
commit 28bd805ed8
15 changed files with 433 additions and 389 deletions

View File

@@ -29,16 +29,16 @@ MDBX_cursor *mdbx_cursor_create(void *context) {
int mdbx_cursor_renew(const MDBX_txn *txn, MDBX_cursor *mc) {
return likely(mc)
? mdbx_cursor_bind(txn, mc, (kvx_t *)mc->clc - txn->env->kvs)
: MDBX_EINVAL;
: LOG_IFERR(MDBX_EINVAL);
}
int mdbx_cursor_reset(MDBX_cursor *mc) {
if (unlikely(!mc))
return MDBX_EINVAL;
return LOG_IFERR(MDBX_EINVAL);
if (unlikely(mc->signature != cur_signature_ready4dispose &&
mc->signature != cur_signature_live))
return MDBX_EBADSIGN;
return LOG_IFERR(MDBX_EBADSIGN);
cursor_couple_t *couple = (cursor_couple_t *)mc;
couple->outer.top_and_flags = z_poor_mark;
@@ -48,29 +48,29 @@ int mdbx_cursor_reset(MDBX_cursor *mc) {
int mdbx_cursor_bind(const MDBX_txn *txn, MDBX_cursor *mc, MDBX_dbi dbi) {
if (unlikely(!mc))
return MDBX_EINVAL;
return LOG_IFERR(MDBX_EINVAL);
if (unlikely(mc->signature != cur_signature_ready4dispose &&
mc->signature != cur_signature_live))
return MDBX_EBADSIGN;
return LOG_IFERR(MDBX_EBADSIGN);
int rc = check_txn(txn, MDBX_TXN_BLOCKED);
if (unlikely(rc != MDBX_SUCCESS))
return rc;
return LOG_IFERR(rc);
rc = dbi_check(txn, dbi);
if (unlikely(rc != MDBX_SUCCESS))
return rc;
return LOG_IFERR(rc);
if (unlikely(dbi == FREE_DBI && !(txn->flags & MDBX_TXN_RDONLY)))
return MDBX_EACCESS;
return LOG_IFERR(MDBX_EACCESS);
if (unlikely(mc->backup)) /* Cursor from parent transaction */ {
cASSERT(mc, mc->signature == cur_signature_live);
if (unlikely(cursor_dbi(mc) != dbi ||
/* paranoia */ mc->signature != cur_signature_live ||
mc->txn != txn))
return MDBX_EINVAL;
return LOG_IFERR(MDBX_EINVAL);
cASSERT(mc, mc->tree == &txn->dbs[dbi]);
cASSERT(mc, mc->clc == &txn->env->kvs[dbi].clc);
@@ -79,7 +79,9 @@ int mdbx_cursor_bind(const MDBX_txn *txn, MDBX_cursor *mc, MDBX_dbi dbi) {
/* paranoia */ mc->signature == cur_signature_live &&
mc->txn == txn)
? MDBX_SUCCESS
: MDBX_EINVAL /* Disallow change DBI in nested transactions */;
: LOG_IFERR(MDBX_EINVAL) /* Disallow change DBI in nested
transactions */
;
}
if (mc->signature == cur_signature_live) {
@@ -91,7 +93,7 @@ int mdbx_cursor_bind(const MDBX_txn *txn, MDBX_cursor *mc, MDBX_dbi dbi) {
rc = cursor_init(mc, txn, dbi);
if (unlikely(rc != MDBX_SUCCESS))
return rc;
return LOG_IFERR(rc);
mc->next = txn->cursors[dbi];
txn->cursors[dbi] = mc;
@@ -100,14 +102,15 @@ int mdbx_cursor_bind(const MDBX_txn *txn, MDBX_cursor *mc, MDBX_dbi dbi) {
int mdbx_cursor_unbind(MDBX_cursor *mc) {
if (unlikely(!mc))
return MDBX_EINVAL;
return LOG_IFERR(MDBX_EINVAL);
if (unlikely(mc->signature != cur_signature_live))
return (mc->signature == cur_signature_ready4dispose) ? MDBX_SUCCESS
: MDBX_EBADSIGN;
return (mc->signature == cur_signature_ready4dispose)
? MDBX_SUCCESS
: LOG_IFERR(MDBX_EBADSIGN);
if (unlikely(mc->backup)) /* Cursor from parent transaction */
return MDBX_EINVAL;
return LOG_IFERR(MDBX_EINVAL);
eASSERT(nullptr, mc->txn && mc->txn->signature == txn_signature);
cASSERT(mc, mc->signature == cur_signature_live);
@@ -116,7 +119,7 @@ int mdbx_cursor_unbind(MDBX_cursor *mc) {
ERROR("Wrong cursor's transaction %p 0x%x",
__Wpedantic_format_voidptr(mc->txn),
mc->txn ? mc->txn->signature : 0);
return MDBX_PROBLEM;
return LOG_IFERR(MDBX_PROBLEM);
}
if (mc->next != mc) {
const size_t dbi = (kvx_t *)mc->clc - mc->txn->env->kvs;
@@ -138,17 +141,17 @@ int mdbx_cursor_unbind(MDBX_cursor *mc) {
int mdbx_cursor_open(const MDBX_txn *txn, MDBX_dbi dbi, MDBX_cursor **ret) {
if (unlikely(!ret))
return MDBX_EINVAL;
return LOG_IFERR(MDBX_EINVAL);
*ret = nullptr;
MDBX_cursor *const mc = mdbx_cursor_create(nullptr);
if (unlikely(!mc))
return MDBX_ENOMEM;
return LOG_IFERR(MDBX_ENOMEM);
int rc = mdbx_cursor_bind(txn, mc, dbi);
if (unlikely(rc != MDBX_SUCCESS)) {
mdbx_cursor_close(mc);
return rc;
return LOG_IFERR(rc);
}
*ret = mc;
@@ -189,10 +192,11 @@ void mdbx_cursor_close(MDBX_cursor *mc) {
int mdbx_cursor_copy(const MDBX_cursor *src, MDBX_cursor *dest) {
if (unlikely(!src))
return MDBX_EINVAL;
return LOG_IFERR(MDBX_EINVAL);
if (unlikely(src->signature != cur_signature_live))
return (src->signature == cur_signature_ready4dispose) ? MDBX_EINVAL
: MDBX_EBADSIGN;
return LOG_IFERR((src->signature == cur_signature_ready4dispose)
? MDBX_EINVAL
: MDBX_EBADSIGN);
int rc = mdbx_cursor_bind(src->txn, dest, cursor_dbi(src));
if (unlikely(rc != MDBX_SUCCESS))
@@ -241,6 +245,7 @@ int mdbx_txn_release_all_cursors(const MDBX_txn *txn, bool unbind) {
}
} else {
eASSERT(nullptr, rc < 0);
LOG_IFERR(rc);
}
return rc;
}
@@ -325,18 +330,19 @@ int mdbx_cursor_compare(const MDBX_cursor *l, const MDBX_cursor *r,
/* Return the count of duplicate data items for the current key */
int mdbx_cursor_count(const MDBX_cursor *mc, size_t *countp) {
if (unlikely(mc == nullptr))
return MDBX_EINVAL;
return LOG_IFERR(MDBX_EINVAL);
if (unlikely(mc->signature != cur_signature_live))
return (mc->signature == cur_signature_ready4dispose) ? MDBX_EINVAL
: MDBX_EBADSIGN;
return LOG_IFERR((mc->signature == cur_signature_ready4dispose)
? MDBX_EINVAL
: MDBX_EBADSIGN);
int rc = check_txn(mc->txn, MDBX_TXN_BLOCKED);
if (unlikely(rc != MDBX_SUCCESS))
return rc;
return LOG_IFERR(rc);
if (unlikely(countp == nullptr))
return MDBX_EINVAL;
return LOG_IFERR(MDBX_EINVAL);
if ((*countp = is_filled(mc)) > 0) {
if (!inner_hollow(mc)) {
@@ -353,11 +359,12 @@ int mdbx_cursor_count(const MDBX_cursor *mc, size_t *countp) {
int mdbx_cursor_on_first(const MDBX_cursor *mc) {
if (unlikely(mc == nullptr))
return MDBX_EINVAL;
return LOG_IFERR(MDBX_EINVAL);
if (unlikely(mc->signature != cur_signature_live))
return (mc->signature == cur_signature_ready4dispose) ? MDBX_EINVAL
: MDBX_EBADSIGN;
return LOG_IFERR((mc->signature == cur_signature_ready4dispose)
? MDBX_EINVAL
: MDBX_EBADSIGN);
for (intptr_t i = 0; i <= mc->top; ++i) {
if (mc->ki[i])
@@ -369,11 +376,12 @@ int mdbx_cursor_on_first(const MDBX_cursor *mc) {
int mdbx_cursor_on_first_dup(const MDBX_cursor *mc) {
if (unlikely(mc == nullptr))
return MDBX_EINVAL;
return LOG_IFERR(MDBX_EINVAL);
if (unlikely(mc->signature != cur_signature_live))
return (mc->signature == cur_signature_ready4dispose) ? MDBX_EINVAL
: MDBX_EBADSIGN;
return LOG_IFERR((mc->signature == cur_signature_ready4dispose)
? MDBX_EINVAL
: MDBX_EBADSIGN);
if (is_filled(mc) && mc->subcur) {
mc = &mc->subcur->cursor;
@@ -388,11 +396,12 @@ int mdbx_cursor_on_first_dup(const MDBX_cursor *mc) {
int mdbx_cursor_on_last(const MDBX_cursor *mc) {
if (unlikely(mc == nullptr))
return MDBX_EINVAL;
return LOG_IFERR(MDBX_EINVAL);
if (unlikely(mc->signature != cur_signature_live))
return (mc->signature == cur_signature_ready4dispose) ? MDBX_EINVAL
: MDBX_EBADSIGN;
return LOG_IFERR((mc->signature == cur_signature_ready4dispose)
? MDBX_EINVAL
: MDBX_EBADSIGN);
for (intptr_t i = 0; i <= mc->top; ++i) {
size_t nkeys = page_numkeys(mc->pg[i]);
@@ -405,11 +414,12 @@ int mdbx_cursor_on_last(const MDBX_cursor *mc) {
int mdbx_cursor_on_last_dup(const MDBX_cursor *mc) {
if (unlikely(mc == nullptr))
return MDBX_EINVAL;
return LOG_IFERR(MDBX_EINVAL);
if (unlikely(mc->signature != cur_signature_live))
return (mc->signature == cur_signature_ready4dispose) ? MDBX_EINVAL
: MDBX_EBADSIGN;
return LOG_IFERR((mc->signature == cur_signature_ready4dispose)
? MDBX_EINVAL
: MDBX_EBADSIGN);
if (is_filled(mc) && mc->subcur) {
mc = &mc->subcur->cursor;
@@ -425,11 +435,12 @@ int mdbx_cursor_on_last_dup(const MDBX_cursor *mc) {
int mdbx_cursor_eof(const MDBX_cursor *mc) {
if (unlikely(mc == nullptr))
return MDBX_EINVAL;
return LOG_IFERR(MDBX_EINVAL);
if (unlikely(mc->signature != cur_signature_live))
return (mc->signature == cur_signature_ready4dispose) ? MDBX_EINVAL
: MDBX_EBADSIGN;
return LOG_IFERR((mc->signature == cur_signature_ready4dispose)
? MDBX_EINVAL
: MDBX_EBADSIGN);
return is_eof(mc) ? MDBX_RESULT_TRUE : MDBX_RESULT_FALSE;
}
@@ -437,20 +448,21 @@ int mdbx_cursor_eof(const MDBX_cursor *mc) {
int mdbx_cursor_get(MDBX_cursor *mc, MDBX_val *key, MDBX_val *data,
MDBX_cursor_op op) {
if (unlikely(mc == nullptr))
return MDBX_EINVAL;
return LOG_IFERR(MDBX_EINVAL);
if (unlikely(mc->signature != cur_signature_live))
return (mc->signature == cur_signature_ready4dispose) ? MDBX_EINVAL
: MDBX_EBADSIGN;
return LOG_IFERR((mc->signature == cur_signature_ready4dispose)
? MDBX_EINVAL
: MDBX_EBADSIGN);
int rc = check_txn(mc->txn, MDBX_TXN_BLOCKED);
if (unlikely(rc != MDBX_SUCCESS))
return rc;
return LOG_IFERR(rc);
if (unlikely(cursor_dbi_changed(mc)))
return MDBX_BAD_DBI;
return LOG_IFERR(MDBX_BAD_DBI);
return cursor_ops(mc, key, data, op);
return LOG_IFERR(cursor_ops(mc, key, data, op));
}
__hot static int scan_confinue(MDBX_cursor *mc, MDBX_predicate_func *predicate,
@@ -520,33 +532,34 @@ int mdbx_cursor_scan(MDBX_cursor *mc, MDBX_predicate_func *predicate,
void *context, MDBX_cursor_op start_op,
MDBX_cursor_op turn_op, void *arg) {
if (unlikely(!predicate))
return MDBX_EINVAL;
return LOG_IFERR(MDBX_EINVAL);
const unsigned valid_start_mask =
1 << MDBX_FIRST | 1 << MDBX_FIRST_DUP | 1 << MDBX_LAST |
1 << MDBX_LAST_DUP | 1 << MDBX_GET_CURRENT | 1 << MDBX_GET_MULTIPLE;
if (unlikely(start_op > 30 || ((1 << start_op) & valid_start_mask) == 0))
return MDBX_EINVAL;
return LOG_IFERR(MDBX_EINVAL);
const unsigned valid_turn_mask =
1 << MDBX_NEXT | 1 << MDBX_NEXT_DUP | 1 << MDBX_NEXT_NODUP |
1 << MDBX_PREV | 1 << MDBX_PREV_DUP | 1 << MDBX_PREV_NODUP |
1 << MDBX_NEXT_MULTIPLE | 1 << MDBX_PREV_MULTIPLE;
if (unlikely(turn_op > 30 || ((1 << turn_op) & valid_turn_mask) == 0))
return MDBX_EINVAL;
return LOG_IFERR(MDBX_EINVAL);
MDBX_val key = {nullptr, 0}, value = {nullptr, 0};
int rc = mdbx_cursor_get(mc, &key, &value, start_op);
if (unlikely(rc != MDBX_SUCCESS))
return rc;
return scan_confinue(mc, predicate, context, arg, &key, &value, turn_op);
return LOG_IFERR(rc);
return LOG_IFERR(
scan_confinue(mc, predicate, context, arg, &key, &value, turn_op));
}
int mdbx_cursor_scan_from(MDBX_cursor *mc, MDBX_predicate_func *predicate,
void *context, MDBX_cursor_op from_op, MDBX_val *key,
MDBX_val *value, MDBX_cursor_op turn_op, void *arg) {
if (unlikely(!predicate || !key))
return MDBX_EINVAL;
return LOG_IFERR(MDBX_EINVAL);
const unsigned valid_start_mask =
1 << MDBX_GET_BOTH | 1 << MDBX_GET_BOTH_RANGE | 1 << MDBX_SET_KEY |
@@ -554,18 +567,18 @@ int mdbx_cursor_scan_from(MDBX_cursor *mc, MDBX_predicate_func *predicate,
1 << MDBX_SET_UPPERBOUND;
if (unlikely(from_op < MDBX_TO_KEY_LESSER_THAN &&
((1 << from_op) & valid_start_mask) == 0))
return MDBX_EINVAL;
return LOG_IFERR(MDBX_EINVAL);
const unsigned valid_turn_mask =
1 << MDBX_NEXT | 1 << MDBX_NEXT_DUP | 1 << MDBX_NEXT_NODUP |
1 << MDBX_PREV | 1 << MDBX_PREV_DUP | 1 << MDBX_PREV_NODUP |
1 << MDBX_NEXT_MULTIPLE | 1 << MDBX_PREV_MULTIPLE;
if (unlikely(turn_op > 30 || ((1 << turn_op) & valid_turn_mask) == 0))
return MDBX_EINVAL;
return LOG_IFERR(MDBX_EINVAL);
int rc = mdbx_cursor_get(mc, key, value, from_op);
if (unlikely(MDBX_IS_ERROR(rc)))
return rc;
return LOG_IFERR(rc);
cASSERT(mc, key != nullptr);
MDBX_val stub;
@@ -573,51 +586,53 @@ int mdbx_cursor_scan_from(MDBX_cursor *mc, MDBX_predicate_func *predicate,
value = &stub;
rc = cursor_ops(mc, key, value, MDBX_GET_CURRENT);
if (unlikely(rc != MDBX_SUCCESS))
return rc;
return LOG_IFERR(rc);
}
return scan_confinue(mc, predicate, context, arg, key, value, turn_op);
return LOG_IFERR(
scan_confinue(mc, predicate, context, arg, key, value, turn_op));
}
int mdbx_cursor_get_batch(MDBX_cursor *mc, size_t *count, MDBX_val *pairs,
size_t limit, MDBX_cursor_op op) {
if (unlikely(!count))
return MDBX_EINVAL;
return LOG_IFERR(MDBX_EINVAL);
*count = 0;
if (unlikely(mc == nullptr || limit < 4 || limit > INTPTR_MAX - 2))
return MDBX_EINVAL;
return LOG_IFERR(MDBX_EINVAL);
if (unlikely(mc->signature != cur_signature_live))
return (mc->signature == cur_signature_ready4dispose) ? MDBX_EINVAL
: MDBX_EBADSIGN;
return LOG_IFERR((mc->signature == cur_signature_ready4dispose)
? MDBX_EINVAL
: MDBX_EBADSIGN);
int rc = check_txn(mc->txn, MDBX_TXN_BLOCKED);
if (unlikely(rc != MDBX_SUCCESS))
return rc;
return LOG_IFERR(rc);
if (unlikely(cursor_dbi_changed(mc)))
return MDBX_BAD_DBI;
return LOG_IFERR(MDBX_BAD_DBI);
if (unlikely(mc->subcur))
return MDBX_INCOMPATIBLE /* must be a non-dupsort table */;
return LOG_IFERR(MDBX_INCOMPATIBLE) /* must be a non-dupsort table */;
switch (op) {
case MDBX_NEXT:
if (unlikely(is_eof(mc)))
return is_pointed(mc) ? MDBX_NOTFOUND : MDBX_ENODATA;
return LOG_IFERR(is_pointed(mc) ? MDBX_NOTFOUND : MDBX_ENODATA);
break;
case MDBX_FIRST:
if (!is_filled(mc)) {
rc = outer_first(mc, nullptr, nullptr);
if (unlikely(rc != MDBX_SUCCESS))
return rc;
return LOG_IFERR(rc);
}
break;
default:
DEBUG("unhandled/unimplemented cursor operation %u", op);
return MDBX_EINVAL;
return LOG_IFERR(MDBX_EINVAL);
}
const page_t *mp = mc->pg[mc->top];
@@ -662,18 +677,18 @@ int mdbx_cursor_get_batch(MDBX_cursor *mc, size_t *count, MDBX_val *pairs,
bailout:
*count = n;
return rc;
return LOG_IFERR(rc);
}
/*----------------------------------------------------------------------------*/
int mdbx_cursor_set_userctx(MDBX_cursor *mc, void *ctx) {
if (unlikely(!mc))
return MDBX_EINVAL;
return LOG_IFERR(MDBX_EINVAL);
if (unlikely(mc->signature != cur_signature_ready4dispose &&
mc->signature != cur_signature_live))
return MDBX_EBADSIGN;
return LOG_IFERR(MDBX_EBADSIGN);
cursor_couple_t *couple = container_of(mc, cursor_couple_t, outer);
couple->userctx = ctx;
@@ -714,80 +729,84 @@ MDBX_dbi mdbx_cursor_dbi(const MDBX_cursor *mc) {
int mdbx_cursor_put(MDBX_cursor *mc, const MDBX_val *key, MDBX_val *data,
MDBX_put_flags_t flags) {
if (unlikely(mc == nullptr || key == nullptr || data == nullptr))
return MDBX_EINVAL;
return LOG_IFERR(MDBX_EINVAL);
if (unlikely(mc->signature != cur_signature_live))
return (mc->signature == cur_signature_ready4dispose) ? MDBX_EINVAL
: MDBX_EBADSIGN;
return LOG_IFERR((mc->signature == cur_signature_ready4dispose)
? MDBX_EINVAL
: MDBX_EBADSIGN);
int rc = check_txn_rw(mc->txn, MDBX_TXN_BLOCKED);
if (unlikely(rc != MDBX_SUCCESS))
return rc;
return LOG_IFERR(rc);
if (unlikely(cursor_dbi_changed(mc)))
return MDBX_BAD_DBI;
return LOG_IFERR(MDBX_BAD_DBI);
cASSERT(mc, cursor_is_tracked(mc));
/* Check this first so counter will always be zero on any early failures. */
if (unlikely(flags & MDBX_MULTIPLE)) {
if (unlikely(flags & MDBX_RESERVE))
return MDBX_EINVAL;
return LOG_IFERR(MDBX_EINVAL);
if (unlikely(!(mc->tree->flags & MDBX_DUPFIXED)))
return MDBX_INCOMPATIBLE;
return LOG_IFERR(MDBX_INCOMPATIBLE);
const size_t dcount = data[1].iov_len;
if (unlikely(dcount < 2 || data->iov_len == 0))
return MDBX_BAD_VALSIZE;
return LOG_IFERR(MDBX_BAD_VALSIZE);
if (unlikely(mc->tree->dupfix_size != data->iov_len) &&
mc->tree->dupfix_size)
return MDBX_BAD_VALSIZE;
return LOG_IFERR(MDBX_BAD_VALSIZE);
if (unlikely(dcount >
MAX_MAPSIZE / 2 /
(BRANCH_NODE_MAX(MDBX_MAX_PAGESIZE) - NODESIZE))) {
/* checking for multiplication overflow */
if (unlikely(dcount > MAX_MAPSIZE / 2 / data->iov_len))
return MDBX_TOO_LARGE;
return LOG_IFERR(MDBX_TOO_LARGE);
}
}
if (flags & MDBX_RESERVE) {
if (unlikely(mc->tree->flags & (MDBX_DUPSORT | MDBX_REVERSEDUP |
MDBX_INTEGERDUP | MDBX_DUPFIXED)))
return MDBX_INCOMPATIBLE;
return LOG_IFERR(MDBX_INCOMPATIBLE);
data->iov_base = nullptr;
}
if (unlikely(mc->txn->flags & (MDBX_TXN_RDONLY | MDBX_TXN_BLOCKED)))
return (mc->txn->flags & MDBX_TXN_RDONLY) ? MDBX_EACCESS : MDBX_BAD_TXN;
return LOG_IFERR((mc->txn->flags & MDBX_TXN_RDONLY) ? MDBX_EACCESS
: MDBX_BAD_TXN);
return cursor_put_checklen(mc, key, data, flags);
return LOG_IFERR(cursor_put_checklen(mc, key, data, flags));
}
int mdbx_cursor_del(MDBX_cursor *mc, MDBX_put_flags_t flags) {
if (unlikely(!mc))
return MDBX_EINVAL;
return LOG_IFERR(MDBX_EINVAL);
if (unlikely(mc->signature != cur_signature_live))
return (mc->signature == cur_signature_ready4dispose) ? MDBX_EINVAL
: MDBX_EBADSIGN;
return LOG_IFERR((mc->signature == cur_signature_ready4dispose)
? MDBX_EINVAL
: MDBX_EBADSIGN);
int rc = check_txn_rw(mc->txn, MDBX_TXN_BLOCKED);
if (unlikely(rc != MDBX_SUCCESS))
return rc;
return LOG_IFERR(rc);
if (unlikely(cursor_dbi_changed(mc)))
return MDBX_BAD_DBI;
return LOG_IFERR(MDBX_BAD_DBI);
return cursor_del(mc, flags);
return LOG_IFERR(cursor_del(mc, flags));
}
__cold int mdbx_cursor_ignord(MDBX_cursor *mc) {
if (unlikely(!mc))
return MDBX_EINVAL;
return LOG_IFERR(MDBX_EINVAL);
if (unlikely(mc->signature != cur_signature_live))
return (mc->signature == cur_signature_ready4dispose) ? MDBX_EINVAL
: MDBX_EBADSIGN;
return LOG_IFERR((mc->signature == cur_signature_ready4dispose)
? MDBX_EINVAL
: MDBX_EBADSIGN);
mc->checking |= z_ignord;
if (mc->subcur)