mdbx: Fixed non-closing of DBI descriptors for tables created in nested transactions when such transactions are aborted (v0.14.1-215-g541e81ed).

2026-01-01 mdbx: update ChangeLog.
2025-12-31 mdbx-test: add `extra/dbi_nested_txn`.
2025-12-31 mdbx: explicitly clearing dbi-handles opened inside an aborted nested transaction.
2025-12-31 mdbx: cleaning gone DBI-handles immediately upon unsuccessful opening.
2025-12-31 mdbx: disallow open table with different flags, including zeroes.
2025-12-31 mdbx-dist: cleanup `CMakeLists.txt` of non-amalgamated portion.
This commit is contained in:
Леонид Юрьев (Leonid Yuriev)
2026-01-01 01:18:29 +03:00
parent 78a917f6d6
commit dd898175ec
12 changed files with 60 additions and 262 deletions
+8 -224
View File
@@ -53,129 +53,12 @@ endif()
cmake_policy(SET CMP0054 NEW)
if(EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/.git"
AND EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/COPYRIGHT"
AND EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/LICENSE"
AND EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/NOTICE"
AND EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/README.md"
AND EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/mdbx.h"
AND EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/mdbx.h++"
AND EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/src/alloy.c"
AND EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/src/api-cold.c"
AND EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/src/api-copy.c"
AND EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/src/api-cursor.c"
AND EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/src/api-dbi.c"
AND EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/src/api-env.c"
AND EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/src/api-extra.c"
AND EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/src/api-key-transform.c"
AND EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/src/api-misc.c"
AND EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/src/api-opts.c"
AND EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/src/api-range-estimate.c"
AND EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/src/api-txn-data.c"
AND EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/src/api-txn.c"
AND EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/src/atomics-ops.h"
AND EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/src/atomics-types.h"
AND EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/src/audit.c"
AND EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/src/chk.c"
AND EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/src/cogs.c"
AND EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/src/cogs.h"
AND EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/src/coherency.c"
AND EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/src/config.h.in"
AND EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/src/cursor.c"
AND EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/src/cursor.h"
AND EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/src/dbi.c"
AND EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/src/dbi.h"
AND EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/src/debug_begin.h"
AND EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/src/debug_end.h"
AND EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/src/dpl.c"
AND EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/src/dpl.h"
AND EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/src/dxb.c"
AND EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/src/env.c"
AND EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/src/essentials.h"
AND EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/src/gc-get.c"
AND EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/src/gc-put.c"
AND EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/src/gc.h"
AND EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/src/global.c"
AND EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/src/internals.h"
AND EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/src/layout-dxb.h"
AND EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/src/layout-lck.h"
AND EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/src/lck-posix.c"
AND EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/src/lck-windows.c"
AND EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/src/lck.c"
AND EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/src/lck.h"
AND EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/src/logging_and_debug.c"
AND EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/src/logging_and_debug.h"
AND EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/src/man1/mdbx_chk.1"
AND EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/src/man1/mdbx_copy.1"
AND EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/src/man1/mdbx_drop.1"
AND EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/src/man1/mdbx_dump.1"
AND EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/src/man1/mdbx_load.1"
AND EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/src/man1/mdbx_stat.1"
AND EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/src/mdbx.c++"
AND EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/src/meta.c"
AND EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/src/meta.h"
AND EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/src/mvcc-readers.c"
AND EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/src/node.c"
AND EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/src/node.h"
AND EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/src/ntdll.def"
AND EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/src/options.h"
AND EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/src/osal.c"
AND EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/src/osal.h"
AND EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/src/page-get.c"
AND EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/src/page-iov.c"
AND EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/src/page-iov.h"
AND EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/src/page-ops.c"
AND EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/src/page-ops.h"
AND EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/src/tree-search.c"
AND EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/src/pnl.c"
AND EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/src/pnl.h"
AND EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/src/preface.h"
AND EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/src/proto.h"
AND EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/src/refund.c"
AND EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/src/rkl.c"
AND EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/src/rkl.h"
AND EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/src/sort.h"
AND EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/src/spill.c"
AND EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/src/spill.h"
AND EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/src/table.c"
AND EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/src/tls.c"
AND EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/src/tls.h"
AND EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/src/tools/chk.c"
AND EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/src/tools/copy.c"
AND EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/src/tools/drop.c"
AND EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/src/tools/dump.c"
AND EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/src/tools/load.c"
AND EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/src/tools/stat.c"
AND EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/src/tools/wingetopt.c"
AND EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/src/tools/wingetopt.h"
AND EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/src/tree-ops.c"
AND EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/src/txl.c"
AND EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/src/txl.h"
AND EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/src/txn-basal.c"
AND EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/src/txn-nested.c"
AND EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/src/txn-ro.c"
AND EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/src/txn.c"
AND EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/src/unaligned.h"
AND EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/src/utils.c"
AND EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/src/utils.h"
AND EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/src/version.c.in"
AND EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/src/walk.c"
AND EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/src/walk.h"
AND EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/src/windows-import.c"
AND EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/src/windows-import.h"
AND EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/test/CMakeLists.txt")
set(MDBX_AMALGAMATED_SOURCE FALSE)
find_program(GIT git)
if(NOT GIT)
message(SEND_ERROR "Git command-line tool not found")
endif()
set(MDBX_SOURCE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/src")
elseif(
EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/VERSION.json"
if(EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/VERSION.json"
AND EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/COPYRIGHT"
AND EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/LICENSE"
AND EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/NOTICE"
AND EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/README.md"
AND EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/GNUmakefile"
AND EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/mdbx.c"
AND EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/mdbx.c++"
AND EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/mdbx.h"
@@ -193,8 +76,9 @@ elseif(
else()
message(
FATAL_ERROR
"\nThe set of libmdbx source code files is incomplete! "
"Instead just follow the https://libmdbx.dqdkfa.ru/usage.html " "PLEASE, AVOID USING ANY OTHER TECHNIQUES.")
"\nThe set of libmdbx source code files is incomplete!"
" Instead just follow the https://libmdbx.dqdkfa.ru/usage.html"
" PLEASE, AVOID USING ANY OTHER TECHNIQUES.")
endif()
# Provide version
@@ -772,109 +656,10 @@ set(LIBMDBX_SOURCES mdbx.h "${CMAKE_CURRENT_BINARY_DIR}/config-cmake.h")
if(MDBX_AMALGAMATED_SOURCE)
list(APPEND LIBMDBX_SOURCES mdbx.c)
else()
# generate version file
file(REMOVE "${MDBX_SOURCE_DIR}/version.c")
configure_file("${MDBX_SOURCE_DIR}/version.c.in" "${CMAKE_CURRENT_BINARY_DIR}/version.c" ESCAPE_QUOTES)
file(SHA256 "${CMAKE_CURRENT_BINARY_DIR}/version.c" MDBX_SOURCERY_DIGEST)
string(MAKE_C_IDENTIFIER "${MDBX_GIT_DESCRIBE}" MDBX_SOURCERY_SUFFIX)
set(MDBX_BUILD_SOURCERY "${MDBX_SOURCERY_DIGEST}_${MDBX_SOURCERY_SUFFIX}")
if(MDBX_ALLOY_BUILD)
list(APPEND LIBMDBX_SOURCES "${MDBX_SOURCE_DIR}/alloy.c")
include_directories("${MDBX_SOURCE_DIR}" "${CMAKE_CURRENT_BINARY_DIR}")
else()
list(
APPEND
LIBMDBX_SOURCES
"${MDBX_SOURCE_DIR}/api-cold.c"
"${MDBX_SOURCE_DIR}/api-copy.c"
"${MDBX_SOURCE_DIR}/api-cursor.c"
"${MDBX_SOURCE_DIR}/api-dbi.c"
"${MDBX_SOURCE_DIR}/api-env.c"
"${MDBX_SOURCE_DIR}/api-extra.c"
"${MDBX_SOURCE_DIR}/api-key-transform.c"
"${MDBX_SOURCE_DIR}/api-misc.c"
"${MDBX_SOURCE_DIR}/api-opts.c"
"${MDBX_SOURCE_DIR}/api-range-estimate.c"
"${MDBX_SOURCE_DIR}/api-txn-data.c"
"${MDBX_SOURCE_DIR}/api-txn.c"
"${MDBX_SOURCE_DIR}/atomics-ops.h"
"${MDBX_SOURCE_DIR}/atomics-types.h"
"${MDBX_SOURCE_DIR}/audit.c"
"${MDBX_SOURCE_DIR}/chk.c"
"${MDBX_SOURCE_DIR}/cogs.c"
"${MDBX_SOURCE_DIR}/cogs.h"
"${MDBX_SOURCE_DIR}/coherency.c"
"${MDBX_SOURCE_DIR}/cursor.c"
"${MDBX_SOURCE_DIR}/cursor.h"
"${MDBX_SOURCE_DIR}/dbi.c"
"${MDBX_SOURCE_DIR}/dbi.h"
"${MDBX_SOURCE_DIR}/dpl.c"
"${MDBX_SOURCE_DIR}/dpl.h"
"${MDBX_SOURCE_DIR}/dxb.c"
"${MDBX_SOURCE_DIR}/env.c"
"${MDBX_SOURCE_DIR}/essentials.h"
"${MDBX_SOURCE_DIR}/gc-get.c"
"${MDBX_SOURCE_DIR}/gc-put.c"
"${MDBX_SOURCE_DIR}/gc.h"
"${MDBX_SOURCE_DIR}/global.c"
"${MDBX_SOURCE_DIR}/internals.h"
"${MDBX_SOURCE_DIR}/layout-dxb.h"
"${MDBX_SOURCE_DIR}/layout-lck.h"
"${MDBX_SOURCE_DIR}/lck.c"
"${MDBX_SOURCE_DIR}/lck.h"
"${MDBX_SOURCE_DIR}/logging_and_debug.c"
"${MDBX_SOURCE_DIR}/logging_and_debug.h"
"${MDBX_SOURCE_DIR}/meta.c"
"${MDBX_SOURCE_DIR}/meta.h"
"${MDBX_SOURCE_DIR}/mvcc-readers.c"
"${MDBX_SOURCE_DIR}/node.c"
"${MDBX_SOURCE_DIR}/node.h"
"${MDBX_SOURCE_DIR}/options.h"
"${MDBX_SOURCE_DIR}/osal.c"
"${MDBX_SOURCE_DIR}/osal.h"
"${MDBX_SOURCE_DIR}/page-get.c"
"${MDBX_SOURCE_DIR}/page-iov.c"
"${MDBX_SOURCE_DIR}/page-iov.h"
"${MDBX_SOURCE_DIR}/page-ops.c"
"${MDBX_SOURCE_DIR}/page-ops.h"
"${MDBX_SOURCE_DIR}/tree-search.c"
"${MDBX_SOURCE_DIR}/pnl.c"
"${MDBX_SOURCE_DIR}/pnl.h"
"${MDBX_SOURCE_DIR}/preface.h"
"${MDBX_SOURCE_DIR}/proto.h"
"${MDBX_SOURCE_DIR}/refund.c"
"${MDBX_SOURCE_DIR}/rkl.c"
"${MDBX_SOURCE_DIR}/rkl.h"
"${MDBX_SOURCE_DIR}/sort.h"
"${MDBX_SOURCE_DIR}/spill.c"
"${MDBX_SOURCE_DIR}/spill.h"
"${MDBX_SOURCE_DIR}/table.c"
"${MDBX_SOURCE_DIR}/tls.c"
"${MDBX_SOURCE_DIR}/tls.h"
"${MDBX_SOURCE_DIR}/tree-ops.c"
"${MDBX_SOURCE_DIR}/txl.c"
"${MDBX_SOURCE_DIR}/txl.h"
"${MDBX_SOURCE_DIR}/txn-basal.c"
"${MDBX_SOURCE_DIR}/txn-nested.c"
"${MDBX_SOURCE_DIR}/txn-ro.c"
"${MDBX_SOURCE_DIR}/txn.c"
"${MDBX_SOURCE_DIR}/unaligned.h"
"${MDBX_SOURCE_DIR}/utils.c"
"${MDBX_SOURCE_DIR}/utils.h"
"${MDBX_SOURCE_DIR}/walk.c"
"${MDBX_SOURCE_DIR}/walk.h"
"${CMAKE_CURRENT_BINARY_DIR}/version.c")
if(NOT MSVC)
list(APPEND LIBMDBX_SOURCES "${MDBX_SOURCE_DIR}/lck-posix.c")
endif()
if(NOT APPLE)
list(APPEND LIBMDBX_SOURCES "${MDBX_SOURCE_DIR}/windows-import.h" "${MDBX_SOURCE_DIR}/windows-import.c"
"${MDBX_SOURCE_DIR}/lck-windows.c")
endif()
include_directories("${MDBX_SOURCE_DIR}")
if(NOT CMAKE_CURRENT_LIST_FILE)
set(CMAKE_CURRENT_LIST_FILE "CMakeLists.txt")
endif()
add_custom_target(doc-files SOURCES README.md TODO.md ChangeLog.md LICENSE NOTICE COPYRIGHT)
message(FATAL_ERROR "This \"${CMAKE_CURRENT_LIST_FILE}\" has been trimmed and is therefore intended only for build from an amalgamated form of the source code.")
endif(MDBX_AMALGAMATED_SOURCE)
if(MDBX_BUILD_CXX)
message(STATUS "Use C${MDBX_C_STANDARD} and C++${MDBX_CXX_STANDARD} for libmdbx")
@@ -1269,7 +1054,6 @@ if(NOT MDBX_AMALGAMATED_SOURCE AND MDBX_ENABLE_TESTS)
if(NOT CMAKE_CXX_COMPILER_LOADED)
message(FATAL_ERROR "MDBX_ENABLE_TESTS=${MDBX_ENABLE_TESTS}: The C++ compiler is required to build the tests.")
endif()
add_subdirectory(test)
endif()
# ######################################################################################################################
+7
View File
@@ -19,6 +19,7 @@ Donations are welcome to ETH `0xD104d8f8B2dC312aaD74899F83EBf3EEBDC1EA3A`. Вс
- [Erigon](https://erigon.tech/) за спонсорство.
- [Артёму Воротникову](https://github.com/vorot93) за сообщение об ошибках и тестировании [призязок для Rust](https://github.com/vorot93/libmdbx-rs).
- [Stefan de Konink](https://github.com/skinkie) for fixing [Python bindings](https://github.com/wtdcode/mdbx-py) and documentation improvement.
- [Cosmin Apreutesei](https://github.com/capr) за сообщение об ошибках и тестирование.
Новое:
@@ -84,6 +85,10 @@ Donations are welcome to ETH `0xD104d8f8B2dC312aaD74899F83EBf3EEBDC1EA3A`. Вс
- В CMake-скриптах устранён регресс, из-за которого инфраструктура `ctest` не использовала задаваемые параметры Valgrind, в том числе `MEMORYCHECK_SUPPRESSIONS_FILE`.
Теперь использование `ctest -D ExperimentalMemCheck` не приводит к множественной ложно-положительной диагностики. Однако, для использования Valgrind по-прежнему необходимо собирать библиотеку с предопределением макроса `ENABLE_MEMCHECK`.
- Устранено использование идентификатора `ERROR_UNHANDLED_ERROR`, который не определяется в новых версиях Windows SDK.
- Исправлено не-закрытие дескрипторов DBI для таблиц, созданных во вложенных транзакциях, когда такие транзакции прерывались.
Изменение поведения:
- Вновь включена/разрешена на старых ядрах Linux, начиная с версии 3.16, так как сейчас уже нет причин отказываться от работы на 3.16 поддерживая при этом ядра 4.x, и еще есть проекты (Isar, Isar-Community, Hive) которым требуется такая поддержка.
@@ -102,6 +107,8 @@ Donations are welcome to ETH `0xD104d8f8B2dC312aaD74899F83EBf3EEBDC1EA3A`. Вс
- При сборке посредством GNU Make и CMake теперь, вместо одного `config.h`, генерируются разные файлы `config-gnumake.h` и `config-cmake.h`.
- Запрещено открытие существующих таблиц с отличающимися флагами, если только явно не задана опция `MDBX_DB_ACCEDE`.
Прочие доработки:
- Доработана логика отказа от использования OFD-блокировок на POSIX-платформах.
+1 -1
View File
@@ -44,7 +44,7 @@ The _libmdbx_ code will forever remain open and with high-quality free support,
### на Русском (мой родной язык)
> **Для знакомства с важными изменениями и планами, рекомендуем посмотреть компактную [презентацию "libmdbx: успехи, премятствия, цели и план развития"](https://libmdbx.dqdkfa.ru/release/libmdbx-roadmap-HNY2026-russian.pdf), в которой важные пояснения даны в виде встроенных комментариев.**
> **Для знакомства с важными изменениями и планами, рекомендуем посмотреть компактную [презентацию "libmdbx: успехи, препятствия, цели и план развития"](https://libmdbx.dqdkfa.ru/release/libmdbx-roadmap-HNY2026-russian.pdf), в которой важные пояснения даны в виде встроенных комментариев.**
Для удобства использования и устранения потенциальных ограничений как в распространении, так и препятствий в разработке технологий, начиная с конца 2025 года _libmdbx_ распространяется в виде амальгамированного исходного кода. Исходный код тестов, как и внутренняя документация будет доступна только команде непосредственно занимающейся разработкой. Также [представлена](https://libmdbx.dqdkfa.ru/release/libmdbx-roadmap-HNY2026-russian.pdf) новая стратегия развития _libmdbx_, суть которой в непрерывном движении к _MithrilDB_. В связи с этим часть информации изложенной ниже и в других частях документации может быть неточной или неприменимой. Мы постараемся устранить все несоответствия по-быстрее.
+1 -1
View File
@@ -1 +1 @@
{ "git_describe": "v0.14.1-209-g67fcd717", "git_timestamp": "2025-12-31T01:07:06+03:00", "git_tree": "3292543f72fc3f6e135d900ee88d87dcd7112a18", "git_commit": "67fcd7174247288a8dfc63b2f5e75eade2413a94", "semver": "0.14.1.209" }
{ "git_describe": "v0.14.1-215-g541e81ed", "git_timestamp": "2026-01-01T01:10:47+03:00", "git_tree": "0d2ce6d87b92a6e4230b34454a2285496f8a75f2", "git_commit": "541e81ed1c8e47d5cbdb050a2102263a255002d4", "semver": "0.14.1.215" }
+36 -29
View File
@@ -4,7 +4,7 @@
#define xMDBX_ALLOY 1 /* alloyed build */
#define MDBX_BUILD_SOURCERY 9fae6763798200a36f4757d6f62711f47d8dbcd0769c36fe7bd8a60a4c8dcc43_v0_14_1_209_g67fcd717
#define MDBX_BUILD_SOURCERY f7f5123962e752f13134b4013b9332f1b311a5f0dd19f3d45ba4e65d806a3545_v0_14_1_215_g541e81ed
#define LIBMDBX_INTERNALS
#define MDBX_DEPRECATED
@@ -9339,7 +9339,7 @@ __cold int mdbx_cursor_ignord(MDBX_cursor *mc) {
/* FIXME: This naive implementation should be replaced by handling special cases
* and dropping with entire branches inside the B+tree. */
int mdbx_cursor_bunch_delete(MDBX_cursor *mc, MDBX_bunch_action_t action, size_t *number_of_affected) {
int mdbx_cursor_bunch_delete(MDBX_cursor *mc, MDBX_bunch_action_t action, uint64_t *number_of_affected) {
int rc = cursor_check_rw(mc);
if (unlikely(rc != MDBX_SUCCESS))
return LOG_IFERR(rc);
@@ -18629,6 +18629,8 @@ int cursor_check(const MDBX_cursor *mc, int txn_bad_bits) {
/// \copyright SPDX-License-Identifier: Apache-2.0
/// \author Леонид Юрьев aka Leonid Yuriev <leo@yuriev.ru> \date 2015-2025
static defer_free_item_t *dbi_close_locked(MDBX_env *env, MDBX_dbi dbi);
#if MDBX_ENABLE_DBI_SPARSE
size_t dbi_bitmap_ctz_fallback(const MDBX_txn *txn, intptr_t bmi) {
tASSERT(txn, bmi != 0);
@@ -18671,7 +18673,6 @@ int dbi_gone(MDBX_txn *txn, const size_t dbi, const int rc) {
txn = txn->parent;
}
/* TODO: FIXME */
txn->dbi_seqs[dbi] = 0;
return rc;
}
@@ -18822,7 +18823,7 @@ int dbi_defer_release(MDBX_env *const env, defer_free_item_t *const chain) {
/* Export or close DBI handles opened in this txn. */
int dbi_update(MDBX_txn *txn, bool keep) {
MDBX_env *const env = txn->env;
tASSERT(txn, !txn->parent && txn == env->basal_txn);
tASSERT(txn, (!txn->parent && txn == env->basal_txn) || !keep);
bool locked = false;
defer_free_item_t *defer_chain = nullptr;
TXN_FOREACH_DBI_USER(txn, dbi) {
@@ -18900,8 +18901,7 @@ int dbi_bind(MDBX_txn *txn, const size_t dbi, unsigned user_flags, MDBX_cmp_func
*/
if ((user_flags & ~MDBX_CREATE) != (unsigned)(env->dbs_flags[dbi] & DB_PERSISTENT_FLAGS)) {
/* flags are differs, check other conditions */
if ((!user_flags && (!keycmp || keycmp == env->kvs[dbi].clc.k.cmp) &&
(!datacmp || datacmp == env->kvs[dbi].clc.v.cmp)) ||
if (((!keycmp || keycmp == env->kvs[dbi].clc.k.cmp) && (!datacmp || datacmp == env->kvs[dbi].clc.v.cmp)) ||
user_flags == MDBX_DB_ACCEDE) {
user_flags = env->dbs_flags[dbi] & DB_PERSISTENT_FLAGS;
} else if ((user_flags & MDBX_CREATE) == 0)
@@ -18969,9 +18969,11 @@ static inline size_t dbi_namelen(const MDBX_val name) {
}
static int dbi_open_locked(MDBX_txn *txn, cursor_couple_t *maindb_cx, unsigned user_flags, MDBX_cmp_func *keycmp,
MDBX_cmp_func *datacmp, MDBX_val name, const size_t fastpath_slot) {
int rc;
MDBX_cmp_func *datacmp, MDBX_val name, const size_t fastpath_slot,
defer_free_item_t **defer_chain) {
MDBX_env *const env = txn->env;
*defer_chain = nullptr;
int rc;
/* Cannot mix named table(s) with DUPSORT flags */
tASSERT(txn, (txn->dbi_state[MAIN_DBI] & (DBI_LINDO | DBI_VALID | DBI_STALE)) == (DBI_LINDO | DBI_VALID));
@@ -19023,21 +19025,22 @@ static int dbi_open_locked(MDBX_txn *txn, cursor_couple_t *maindb_cx, unsigned u
if (env->kvs[MAIN_DBI].clc.k.cmp(&name, &env->kvs[scan].name) == 0) {
slot = scan;
rc = dbi_check(txn, slot);
if (rc == MDBX_BAD_DBI && txn->dbi_state[slot] == (DBI_OLDEN | DBI_LINDO)) {
/* хендл использовался, стал невалидным,
* но теперь явно пере-открывается в этой транзакции */
if (rc == MDBX_BAD_DBI &&
(txn->dbi_state[slot] ==
/* хендл использовался, стал невалидным, но теперь явно пере-открывается */ (DBI_OLDEN | DBI_LINDO) ||
(txn->dbi_state[slot] ==
/* хендл был инициализирован в дочерней транзакции, но она была прервана */ DBI_LINDO))) {
eASSERT(env, !txn->cursors[slot]);
txn->dbi_state[slot] = DBI_LINDO;
txn->dbi_seqs[slot] = 0;
rc = dbi_import(txn, slot);
/* TODO: FIXME */
}
if (unlikely(rc != MDBX_SUCCESS))
return rc;
goto gone;
rc = dbi_bind(txn, slot, user_flags, keycmp, datacmp);
if (unlikely(rc != MDBX_SUCCESS))
return rc;
goto gone;
if (unlikely((txn->dbi_state[slot] & DBI_STALE) == 0))
goto done;
@@ -19064,7 +19067,9 @@ static int dbi_open_locked(MDBX_txn *txn, cursor_couple_t *maindb_cx, unsigned u
goto create;
}
return dbi_gone(txn, slot, rc);
gone:
*defer_chain = dbi_close_locked(env, slot);
return rc;
}
}
@@ -19231,11 +19236,12 @@ int dbi_open(MDBX_txn *txn, const MDBX_val *const name, unsigned user_flags, MDB
goto slowpath_locking;
rc = dbi_check(txn, slot);
if (rc == MDBX_BAD_DBI && txn->dbi_state[slot] == (DBI_OLDEN | DBI_LINDO)) {
/* хендл использовался, стал невалидным,
* но теперь явно пере-открывается в этой транзакции */
if (rc == MDBX_BAD_DBI &&
(txn->dbi_state[slot] ==
/* хендл использовался, стал невалидным, но теперь явно пере-открывается */ (DBI_OLDEN | DBI_LINDO) ||
(txn->dbi_state[slot] ==
/* хендл был инициализирован в дочерней транзакции, но она была прервана */ DBI_LINDO)))
goto slowpath_locking;
}
if (unlikely(rc != MDBX_SUCCESS))
return rc;
@@ -19254,11 +19260,8 @@ int dbi_open(MDBX_txn *txn, const MDBX_val *const name, unsigned user_flags, MDB
if (txn->dbi_state[slot] & DBI_STALE) {
rc = tbl_fetch(txn, &cx.outer, fastpath_slot = slot, name, user_flags);
if (unlikely(rc != MDBX_SUCCESS)) {
if (rc == MDBX_NOTFOUND && (user_flags & MDBX_CREATE))
/* таблицы уже нет, но запрошено её пересоздание */
goto slowpath_locking;
return dbi_gone(txn, slot, rc);
/* таблица отсутствует, её нужно создавать (если запрос с MDBX_CREATE), либо освобождать слот. */
goto slowpath_locking;
}
txn->dbi_state[slot] -= DBI_STALE;
}
@@ -19282,8 +19285,9 @@ slowpath_locking:
cx.userctx = dbi;
rc = osal_fastmutex_acquire(&txn->env->dbi_lock);
if (likely(rc == MDBX_SUCCESS)) {
rc = dbi_open_locked(txn, &cx, user_flags, keycmp, datacmp, *name, fastpath_slot);
ENSURE(txn->env, osal_fastmutex_release(&txn->env->dbi_lock) == MDBX_SUCCESS);
defer_free_item_t *defer_chain = nullptr;
rc = dbi_open_locked(txn, &cx, user_flags, keycmp, datacmp, *name, fastpath_slot, &defer_chain);
dbi_defer_release(txn->env, defer_chain);
}
return rc;
}
@@ -38461,6 +38465,9 @@ void txn_nested_abort(MDBX_txn *nested) {
parent->wr.retired_pages = nested->wr.retired_pages;
}
if (nested->flags & MDBX_TXN_DIRTY)
dbi_update(nested, false);
tASSERT(parent, dpl_check(parent));
tASSERT(parent, audit_ex(parent, 0, false) == 0);
dpl_release_shadows(nested);
@@ -39897,10 +39904,10 @@ __dll_export
0,
14,
1,
209,
215,
"", /* pre-release suffix of SemVer
0.14.1.209 */
{"2025-12-31T01:07:06+03:00", "3292543f72fc3f6e135d900ee88d87dcd7112a18", "67fcd7174247288a8dfc63b2f5e75eade2413a94", "v0.14.1-209-g67fcd717"},
0.14.1.215 */
{"2026-01-01T01:10:47+03:00", "0d2ce6d87b92a6e4230b34454a2285496f8a75f2", "541e81ed1c8e47d5cbdb050a2102263a255002d4", "v0.14.1-215-g541e81ed"},
sourcery};
__dll_export
+1 -1
View File
@@ -2,7 +2,7 @@
/// \author Леонид Юрьев aka Leonid Yuriev <leo@yuriev.ru> \date 2015-2025
/* clang-format off */
#define MDBX_BUILD_SOURCERY 9fae6763798200a36f4757d6f62711f47d8dbcd0769c36fe7bd8a60a4c8dcc43_v0_14_1_209_g67fcd717
#define MDBX_BUILD_SOURCERY f7f5123962e752f13134b4013b9332f1b311a5f0dd19f3d45ba4e65d806a3545_v0_14_1_215_g541e81ed
#define LIBMDBX_INTERNALS
#define MDBX_DEPRECATED
+1 -1
View File
@@ -18,7 +18,7 @@
/// \copyright SPDX-License-Identifier: Apache-2.0
/// \author Леонид Юрьев aka Leonid Yuriev <leo@yuriev.ru> \date 2015-2025
#define MDBX_BUILD_SOURCERY 9fae6763798200a36f4757d6f62711f47d8dbcd0769c36fe7bd8a60a4c8dcc43_v0_14_1_209_g67fcd717
#define MDBX_BUILD_SOURCERY f7f5123962e752f13134b4013b9332f1b311a5f0dd19f3d45ba4e65d806a3545_v0_14_1_215_g541e81ed
#define LIBMDBX_INTERNALS
#define MDBX_DEPRECATED
+1 -1
View File
@@ -18,7 +18,7 @@
/// \copyright SPDX-License-Identifier: Apache-2.0
/// \author Леонид Юрьев aka Leonid Yuriev <leo@yuriev.ru> \date 2015-2025
#define MDBX_BUILD_SOURCERY 9fae6763798200a36f4757d6f62711f47d8dbcd0769c36fe7bd8a60a4c8dcc43_v0_14_1_209_g67fcd717
#define MDBX_BUILD_SOURCERY f7f5123962e752f13134b4013b9332f1b311a5f0dd19f3d45ba4e65d806a3545_v0_14_1_215_g541e81ed
#define LIBMDBX_INTERNALS
#define MDBX_DEPRECATED
+1 -1
View File
@@ -18,7 +18,7 @@
/// \copyright SPDX-License-Identifier: Apache-2.0
/// \author Леонид Юрьев aka Leonid Yuriev <leo@yuriev.ru> \date 2015-2025
#define MDBX_BUILD_SOURCERY 9fae6763798200a36f4757d6f62711f47d8dbcd0769c36fe7bd8a60a4c8dcc43_v0_14_1_209_g67fcd717
#define MDBX_BUILD_SOURCERY f7f5123962e752f13134b4013b9332f1b311a5f0dd19f3d45ba4e65d806a3545_v0_14_1_215_g541e81ed
#define LIBMDBX_INTERNALS
#define MDBX_DEPRECATED
+1 -1
View File
@@ -18,7 +18,7 @@
/// \copyright SPDX-License-Identifier: Apache-2.0
/// \author Леонид Юрьев aka Leonid Yuriev <leo@yuriev.ru> \date 2015-2025
#define MDBX_BUILD_SOURCERY 9fae6763798200a36f4757d6f62711f47d8dbcd0769c36fe7bd8a60a4c8dcc43_v0_14_1_209_g67fcd717
#define MDBX_BUILD_SOURCERY f7f5123962e752f13134b4013b9332f1b311a5f0dd19f3d45ba4e65d806a3545_v0_14_1_215_g541e81ed
#define LIBMDBX_INTERNALS
#define MDBX_DEPRECATED
+1 -1
View File
@@ -18,7 +18,7 @@
/// \copyright SPDX-License-Identifier: Apache-2.0
/// \author Леонид Юрьев aka Leonid Yuriev <leo@yuriev.ru> \date 2015-2025
#define MDBX_BUILD_SOURCERY 9fae6763798200a36f4757d6f62711f47d8dbcd0769c36fe7bd8a60a4c8dcc43_v0_14_1_209_g67fcd717
#define MDBX_BUILD_SOURCERY f7f5123962e752f13134b4013b9332f1b311a5f0dd19f3d45ba4e65d806a3545_v0_14_1_215_g541e81ed
#define LIBMDBX_INTERNALS
#define MDBX_DEPRECATED
+1 -1
View File
@@ -18,7 +18,7 @@
/// \copyright SPDX-License-Identifier: Apache-2.0
/// \author Леонид Юрьев aka Leonid Yuriev <leo@yuriev.ru> \date 2015-2025
#define MDBX_BUILD_SOURCERY 9fae6763798200a36f4757d6f62711f47d8dbcd0769c36fe7bd8a60a4c8dcc43_v0_14_1_209_g67fcd717
#define MDBX_BUILD_SOURCERY f7f5123962e752f13134b4013b9332f1b311a5f0dd19f3d45ba4e65d806a3545_v0_14_1_215_g541e81ed
#define LIBMDBX_INTERNALS
#define MDBX_DEPRECATED