From bb664152b88adcc0c180288f29a485ab54e8db41 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=9B=D0=B5=D0=BE=D0=BD=D0=B8=D0=B4=20=D0=AE=D1=80=D1=8C?= =?UTF-8?q?=D0=B5=D0=B2=20=28Leonid=20Yuriev=29?= Date: Thu, 20 Mar 2025 23:53:22 +0300 Subject: [PATCH 01/52] =?UTF-8?q?mdbx:=20=D0=B4=D0=BE=D0=BF=D0=BE=D0=BB?= =?UTF-8?q?=D0=BD=D0=B5=D0=BD=D0=B8=D0=B5=20ChangeLog=20(=D0=BF=D0=BE?= =?UTF-8?q?=D0=B4=D0=B3=D0=BE=D1=82=D0=BE=D0=B2=D0=BA=D0=B0=20=D0=BA=20?= =?UTF-8?q?=D0=B2=D1=8B=D0=BF=D1=83=D1=81=D0=BA=D1=83).?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ChangeLog.md | 93 ++++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 90 insertions(+), 3 deletions(-) diff --git a/ChangeLog.md b/ChangeLog.md index 3d4634e3..97f94255 100644 --- a/ChangeLog.md +++ b/ChangeLog.md @@ -4,15 +4,39 @@ ChangeLog English version [by liar Google](https://libmdbx-dqdkfa-ru.translate.goog/md__change_log.html?_x_tr_sl=ru&_x_tr_tl=en) and [by Yandex](https://translated.turbopages.org/proxy_u/ru-en.en/https/libmdbx.dqdkfa.ru/md__change_log.html). -## v0.13.5 в процессе накопления изменений +## v0.13.5 "Труба" запланирован на 2025-03-21 Поддерживающий выпуск стабильной ветки с исправлением обнаруженных ошибок и устранением недочётов. Благодарности: - - [Erigon](https://docs.erigon.tech/) за спонсорство. + - [Erigon](https://erigon.tech/) за спонсорство. - [Илье Михееву](https://t.me/IlyaMkhv) за сообщения о недочетах и тестирование. + - [Alex Sharov](https://github.com/AskAlexSharov) за сообщение об ошибках и тестирование. - [maxc0d3r](https://gitflic.ru/user/maxc0d3r) for bug reporting and testing. + - [Alain Picard](https://github.com/castortech) for support [Java bindings](https://github.com/castortech/mdbxjni) and MacOS universal binaries patch for CMake build scenario, + also for bug reporting (put-`MDBX_MULTIPLE` regression). Big thank for assistance with debugging and testing. + + +Новое: + + - Добавлена опция сборки `MDBX_ENABLE_NON_READONLY_EXPORT` позволяющая использовать в режиме чтения-записи БД расположенных в файловых системах экспортированных через NFS. + По-умолчанию опция выключена и при открытии в неэксклюзивном режиме чтения-записи БД расположенных файловых системах доступных извне по NFS будет возвращаться ошибка `MDBX_EREMOTE`. + Включение опции позволяет открывать БД в описанных выше ситуациях, но риск чтения неверных данных на удалённой стороне ложится на пользователя. + + - Поддержка MacOS universal binaries при сборке посредством CMake. + + - Для закрытия или отсоединения всех курсоров с получением их количества в API добавлена функция `mdbx_txn_release_all_cursors_ex()`. + + - Добавлена операция `MDBX_SEEK_AND_GET_MULTIPLE` в API курсора, позволяющая за одну операцию выполнить позиционирование + курсора на конкретное значение и начать чтение multi-значений в пакетном режиме. + + - Добавлены методы `mdbx::cursor::put_multiple_samelength()`, `mdbx::cursor::seek_multiple_samelength()`, `mdbx::cursor_managed::withdraw_handle()`. + + - В политику управления выделением для `mdbx::buffer` добавлен параметр `inplace_storage_size_rounding`. + Одновременно с этим переработан внутренний union-тип `mdbx::buffer::silo::bin` для возможности увеличения без пенальти встроенного в экземпляр буфера места под данные. + + - В API добавлена функция `mdbx_cursor_close2()` возвращающая код ошибки. Исправления: @@ -39,13 +63,76 @@ and [by Yandex](https://translated.turbopages.org/proxy_u/ru-en.en/https/libmdbx - Устранена причина попыток рекурсивного захвата мьютекса при работе `mdbx_chk -w` в сборах с поддержкой Valring/ASAN и под управлением этих инструментов. - - Проверка владельца потока владеющего транзакцией только при `MDBX_TXN_CHECKOWNER=ON`. + - Устранены проверки потока владеющего транзакцией при сборке с опцией `MDBX_TXN_CHECKOWNER=OFF`. + + - Устранена вероятность ситуации гонки в `tbl_setup(MDBX_DUPFIXED | MDBX_INTEGERDUP)` при работе в разных потоках. + В реальных сценариях вероятность проявления проблемы была близка к нулю. + Для подробностей смотрите комментарий коммита `3e91500fac475947f5b58268d5edd3c9cc4f77f6`. + + - Устранён регресс затенения курсоров во вложенных транзакциях. + При реализации отложенной/ленивой инициализации dbi-дескрипторов также было реализовано отложенное затенение курсоров (создание копии состояния для отката при прерывании транзакции), + что существенно уменьшало накладные расходы при старте и завершении вложенных транзакций в сценариях с большим количеством курсоров. + Однако, была допущена логическая ошибка, вследствие которой отложенная инициализация и затенение выполнялись при использовании dbi-дескрипторов, но не курсора открытого в родительской транзакции. + В результате, родительские курсоры во вложенных транзакциях могли не затеняться, что приводило к неконсистентному состоянию в случае + прерывания/откате вложенной транзакции и в соответствующей таблицы были изменения в рамках прерванной вложенной транзакции. + Проблема не реализовывалась в тестовых сценариях и не была замечена при эксплуатации, но была обнаружена при расширении тестов. + Ошибка присутствует в версиях 0.13.x и последующих, начиная с коммита `e6af7d7c53428ca2892bcbf7eec1c2acee06fd44` от 2023-11-05. + + - Устранён регресс в пути обработки операции `MDBX_MULTIPLE`. + Пакетная вставка значений посредством `MDBX_MULTIPLE` могла приводить к падениям и повреждению структуры БД. Ошибка оставалось не + замеченной из-за специфических условий проявления, которые не реализовались в тестах. + Проблема присутствовала во всех выпусках начиная с v0.13.1, но соответствующая ошибка не связана с конкретным коммита в истории, а + является следствием нескольких доработок (шагов рефакторинга), которые суммарно привели к регрессу. + Технически ошибка обусловлена не-обнулением переменной, чего не происходило в некотором пути выполнения, так как исходно не требовалось. + Однако, такое обнуление потребовалось после ряда этапов оптимизации и рефакторинга смежных участков кода. + Для подробностей смотрите комментарий коммита `23a417fe19614481c6546845995d6dc845baf797`. + + - Скорректировано описание ошибки `MDBX_MVCC_RETARDED` и текста соответствующего сообщения. + + - В C++ API добавлена упущенная проверка `__cpp_concepts >= 202002` для использования концептов C++. Изменение поведения: - Функция `mdbx_txn_release_all_cursors()` возвращает только код ошибки, не смешивая его с количеством обработанных/закрытых курсоров. Для аналогичных действий с получением количества закрытых курсоров в API добавлена функция `mdbx_txn_release_all_cursors_ex()`. + - Использование системного кода ошибки `EREMOTEIO` ("Remote I/O error") вместо `ENOTBLK` ("Block device required") в качестве `MDBX_EREMOTE` для индикации ошибочной ситуации открытия БД расположенной на сетевом носителе. + + - Для основных вариантов использования шаблона `mdbx::buffer<>` теперь явно инстанцируются внутри библиотеки, + одновременно соответствующие специализации шаблона помечены как `external` для предотвращения повторного инстанцирования в пользовательском коде. + + - Запрещена отвязка/открепление курсоров во вложенных транзакциях, т.е. вызовы `mdbx_cursor_unbind()` и + `mdbx_txn_release_all_cursors(unbind=true)` для курсоров открытых в одной из родительских транзакций. + Причина в том, что в случае отмены вложенной транзакции возникает неконструктивная неопределенность + — следует ли восстанавливать состояние курсоров. Если не восстанавливать, то получается что вложенная транзакция может + поломать родительскую, сделав её продолжение невозможным. Если восстанавливать, то также следует «воскрешать» закрытые + курсоры, что неизбежно приведет к путанице, утечкам памяти и использованию после освобождения. + + - В C++ API отменён вброс исключения при запросе транзакции у отсоединённого курсора посредством вывоза `mdbx::cursor::txn()`. + +Прочие доработки: + + - Доработка использования LTO в CMake-сценариях: использование `-flto=auto` для GCC >= 11.4, + расслабление условий для включения LTO для CLANG на Linux, расширение поиска `LLVMgold.so` в относительных lib-директориях. + + - Добавлены дополнительные проверки сигнатур курсоров при итерации связанных списков. + + - Кратное сокращение итераций тестов в зависимости от конфигурации Valgrind/Debug/CI. + + - Устранены предупреждения UBASN о невыравненном доступе в тесте extra/close-dbi. + + - Добавлен перехват и логирование исключений в extra-тестах на C++. + + - Расширены тесты extra/dupfix-multiple, extra/cursor-closing и extra/txn. + + - В утилиту тестирования добавлена поддержка режима/опции `MDBX_VALIDATION` и поддержка значений `on`/`off` для опций командной строки. + + - Добавлены doxygen-описания для doubtless-positioning констант. + + - Переработана проверка курсоров на входе в API-функций с добавлением `cursor_check()`, `cursor_reset()` и `cursor_drown()`. + + - Отключено использование C23 `[[атрибутов]]` для версий CLANG меньше 20. + -------------------------------------------------------------------------------- From e3324cef918407fe48c90e513577ec99a0d15b62 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=9B=D0=B5=D0=BE=D0=BD=D0=B8=D0=B4=20=D0=AE=D1=80=D1=8C?= =?UTF-8?q?=D0=B5=D0=B2=20=28Leonid=20Yuriev=29?= Date: Fri, 21 Mar 2025 21:14:00 +0300 Subject: [PATCH 02/52] =?UTF-8?q?mdbx:=20=D0=B2=D1=8B=D0=BF=D1=83=D1=81?= =?UTF-8?q?=D0=BA=200.13.5=20"=D0=A2=D1=80=D1=83=D0=B1=D0=B0".?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Поддерживающий выпуск стабильной ветки с исправлением обнаруженных ошибок и устранением недочётов. За перечнем доработок и изменений обращайтесь к [ChangeLog](https://libmdbx.dqdkfa.ru/md__change_log.html). git diff' stat: 49 files changed, 2106 insertions(+), 1135 deletions(-) Signed-off-by: Леонид Юрьев (Leonid Yuriev) --- ChangeLog.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/ChangeLog.md b/ChangeLog.md index 97f94255..f8d23b11 100644 --- a/ChangeLog.md +++ b/ChangeLog.md @@ -4,7 +4,7 @@ ChangeLog English version [by liar Google](https://libmdbx-dqdkfa-ru.translate.goog/md__change_log.html?_x_tr_sl=ru&_x_tr_tl=en) and [by Yandex](https://translated.turbopages.org/proxy_u/ru-en.en/https/libmdbx.dqdkfa.ru/md__change_log.html). -## v0.13.5 "Труба" запланирован на 2025-03-21 +## v0.13.5 "Труба" от 2025-03-21 Поддерживающий выпуск стабильной ветки с исправлением обнаруженных ошибок и устранением недочётов. @@ -17,7 +17,6 @@ and [by Yandex](https://translated.turbopages.org/proxy_u/ru-en.en/https/libmdbx - [Alain Picard](https://github.com/castortech) for support [Java bindings](https://github.com/castortech/mdbxjni) and MacOS universal binaries patch for CMake build scenario, also for bug reporting (put-`MDBX_MULTIPLE` regression). Big thank for assistance with debugging and testing. - Новое: - Добавлена опция сборки `MDBX_ENABLE_NON_READONLY_EXPORT` позволяющая использовать в режиме чтения-записи БД расположенных в файловых системах экспортированных через NFS. From b9b14f0061e097e705a80eadd1306ed980205790 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=9B=D0=B5=D0=BE=D0=BD=D0=B8=D0=B4=20=D0=AE=D1=80=D1=8C?= =?UTF-8?q?=D0=B5=D0=B2=20=28Leonid=20Yuriev=29?= Date: Sat, 22 Mar 2025 20:01:52 +0300 Subject: [PATCH 03/52] =?UTF-8?q?mdbx:=20=D1=83=D1=81=D1=82=D1=80=D0=B0?= =?UTF-8?q?=D0=BD=D0=B5=D0=BD=D0=B8=D0=B5=20=D1=80=D0=B5=D0=B3=D1=80=D0=B5?= =?UTF-8?q?=D1=81=D1=81=D0=B0=20=D0=BF=D1=80=D0=B8=20=D0=B8=D1=81=D0=BF?= =?UTF-8?q?=D0=BE=D0=BB=D1=8C=D0=B7=D0=BE=D0=B2=D0=B0=D0=BD=D0=B8=D0=B8=20?= =?UTF-8?q?=D0=BA=D1=83=D1=80=D1=81=D0=BE=D1=80=D0=BE=D0=B2=20=D0=B4=D0=BB?= =?UTF-8?q?=D1=8F=20DBI=3D0=20=D0=B2=20=D1=87=D0=B8=D1=82=D0=B0=D1=8E?= =?UTF-8?q?=D1=89=D0=B8=D1=85=20=D1=82=D1=80=D0=B0=D0=BD=D0=B7=D0=B0=D0=BA?= =?UTF-8?q?=D1=86=D0=B8=D1=8F=D1=85=20(hotfix).?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit В результате рефакторинга и ряда оптимизаций для завершения/гашения курсоров в читающих и пишущих транзакций стал использоваться общий код. Причем за основу, был взят соответствующий фрагмент относящийся к пишущим транзакциям, в которых пользователю не позволяется использоваться курсоры для DBI=0 и поэтому эта итераций пропускалась. В результате, при завершении читающих транзакциях, курсоры связанные с DBI=0 не завершались должным образом, а при их повторном использовании или явном закрытии после завершения читающей транзакции происходило обращение к уже освобожденной памяти. Если же такие курсоры отсоединялись или закрывались до завершения читающей транзакции, то ошибка не имела шансов на проявление. Спасибо Илье Михееву (https://github.com/JkLondon) и команде Erigon (https://erigon.tech) за сообщения о проблеме. --- src/txn.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/txn.c b/src/txn.c index 36ddaf64..9d7e8bec 100644 --- a/src/txn.c +++ b/src/txn.c @@ -8,8 +8,7 @@ __hot txnid_t txn_snapshot_oldest(const MDBX_txn *const txn) { } void txn_done_cursors(MDBX_txn *txn, const bool merge) { - tASSERT(txn, txn->cursors[FREE_DBI] == nullptr); - TXN_FOREACH_DBI_FROM(txn, i, /* skip FREE_DBI */ 1) { + TXN_FOREACH_DBI_ALL(txn, i) { MDBX_cursor *mc = txn->cursors[i]; if (mc) { txn->cursors[i] = nullptr; From aa98d6a88e901146a4f717c53eab82782fd55908 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=9B=D0=B5=D0=BE=D0=BD=D0=B8=D0=B4=20=D0=AE=D1=80=D1=8C?= =?UTF-8?q?=D0=B5=D0=B2=20=28Leonid=20Yuriev=29?= Date: Sat, 22 Mar 2025 23:31:47 +0300 Subject: [PATCH 04/52] =?UTF-8?q?mdbx:=20=D0=BE=D0=B1=D0=BD=D0=BE=D0=B2?= =?UTF-8?q?=D0=BB=D0=B5=D0=BD=D0=B8=D0=B5=20`NOTICE`.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- NOTICE | 30 +++++++++++++++++++++++------- 1 file changed, 23 insertions(+), 7 deletions(-) diff --git a/NOTICE b/NOTICE index 4df84dba..dd58a0b5 100644 --- a/NOTICE +++ b/NOTICE @@ -8,16 +8,32 @@ documentation, C++ API description and links to the original git repo with the source code. Questions, feedback and suggestions are welcome to the Telegram' group https://t.me/libmdbx. -Donations are welcome to ETH `0xD104d8f8B2dC312aaD74899F83EBf3EEBDC1EA3A`. +Donations are welcome to the Ethereum/ERC-20 `0xD104d8f8B2dC312aaD74899F83EBf3EEBDC1EA3A`. Всё будет хорошо! Copyright 2015-2025 Леонид Юрьев aka Leonid Yuriev SPDX-License-Identifier: Apache-2.0 For notes about the license change, credits and acknowledgments, -please refer to the COPYRIGHT file within original libmdbx source code -repository https://gitflic.ru/project/erthink/libmdbx +please refer to the COPYRIGHT file within libmdbx source. -On 2022-04-15 the Github administration, without any warning nor -explanation, deleted _libmdbx_ along with a lot of other projects, -simultaneously blocking access for many developers. -For the same reason ~~Github~~ is blacklisted forever. +--- + +On 2022-04-15, without any warnings or following explanations, the +Github administration deleted _libmdbx_, my account and all other +projects (status 404). A few months later, without any involvement or +notification from/to me, the projects were restored/opened in the "public +read-only archive" status from some kind of incomplete backup. I regard +these actions of Github as malicious sabotage, and I consider the Github +service itself to have lost trust forever. + +As a result of what has happened, I will never, under any circumstances, +post the primary sources (aka origins) of my projects on Github, or rely +in any way on the Github infrastructure. + +Nevertheless, realizing that it is more convenient for users of +_libmdbx_ and other my projects to access ones on Github, I do not want +to restrict their freedom or create inconvenience, and therefore I place +mirrors (aka mirrors) of such repositories on Github since 2025. At the +same time, I would like to emphasize once again that these are only +mirrors that can be frozen, blocked or deleted at any time, as was the +case in 2022. From ca1808d57ffc2ae7fe532035888951d9c22e6ff2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=9B=D0=B5=D0=BE=D0=BD=D0=B8=D0=B4=20=D0=AE=D1=80=D1=8C?= =?UTF-8?q?=D0=B5=D0=B2=20=28Leonid=20Yuriev=29?= Date: Sat, 22 Mar 2025 19:44:17 +0300 Subject: [PATCH 05/52] =?UTF-8?q?mdbx-test:=20=D1=80=D0=B0=D1=81=D1=88?= =?UTF-8?q?=D0=B8=D1=80=D0=B5=D0=BD=D0=B8=D0=B5=20extra/cursor-closing=20(?= =?UTF-8?q?backport).?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- test/extra/cursor_closing.c++ | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/test/extra/cursor_closing.c++ b/test/extra/cursor_closing.c++ index 24633560..4bd4b7ca 100644 --- a/test/extra/cursor_closing.c++ +++ b/test/extra/cursor_closing.c++ @@ -332,6 +332,27 @@ bool case1(mdbx::env env) { //-------------------------------------------------------------------------------------------- +bool case2(mdbx::env env) { + bool ok = true; + + auto txn = env.start_write(); + auto dbi = txn.create_map("case2", mdbx::key_mode::usual, mdbx::value_mode::single); + txn.commit_embark_read(); + auto cursor1 = txn.open_cursor(dbi); + auto cursor2 = txn.open_cursor(0); + cursor1.move(mdbx::cursor::next, false); + cursor2.move(mdbx::cursor::next, false); + txn.commit_embark_read(); + cursor2.bind(txn, dbi); + cursor1.bind(txn, 0); + cursor1.move(mdbx::cursor::last, false); + cursor2.move(mdbx::cursor::last, false); + + return ok; +} + +//-------------------------------------------------------------------------------------------- + int doit() { mdbx::path db_filename = "test-cursor-closing"; mdbx::env::remove(db_filename); @@ -341,6 +362,7 @@ int doit() { bool ok = case0(env); ok = case1(env) && ok; + ok = case2(env) && ok; if (ok) { std::cout << "OK\n"; From 3d2b2212560a2b12d0f66788782fef7052b90552 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=9B=D0=B5=D0=BE=D0=BD=D0=B8=D0=B4=20=D0=AE=D1=80=D1=8C?= =?UTF-8?q?=D0=B5=D0=B2=20=28Leonid=20Yuriev=29?= Date: Sat, 22 Mar 2025 19:53:50 +0300 Subject: [PATCH 06/52] =?UTF-8?q?mdbx++:=20=D0=B2=D0=B1=D1=80=D0=BE=D1=81?= =?UTF-8?q?=20`std::invalid=5Fargument`=20=D1=81=20=D1=8F=D0=B2=D0=BD?= =?UTF-8?q?=D1=8B=D0=BC=20=D1=81=D0=BE=D0=BE=D0=B1=D1=89=D0=B5=D0=BD=D0=B8?= =?UTF-8?q?=D0=B5=D0=BC=20`"MDBX=5FEINVAL"`=20(backport).?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/mdbx.c++ | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/mdbx.c++ b/src/mdbx.c++ index 565c79e9..6ae73d8a 100644 --- a/src/mdbx.c++ +++ b/src/mdbx.c++ @@ -373,7 +373,7 @@ __cold std::string error::message() const { __cold void error::throw_exception() const { switch (code()) { case MDBX_EINVAL: - throw std::invalid_argument("mdbx"); + throw std::invalid_argument("MDBX_EINVAL"); case MDBX_ENOMEM: throw std::bad_alloc(); case MDBX_SUCCESS: From 5f1d8dcb3e036c73353c18bb79bea12b8fd68acd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=9B=D0=B5=D0=BE=D0=BD=D0=B8=D0=B4=20=D0=AE=D1=80=D1=8C?= =?UTF-8?q?=D0=B5=D0=B2=20=28Leonid=20Yuriev=29?= Date: Sat, 22 Mar 2025 23:17:35 +0300 Subject: [PATCH 07/52] =?UTF-8?q?mdbx:=20=D1=83=D1=82=D0=BE=D1=87=D0=BD?= =?UTF-8?q?=D0=B5=D0=BD=D0=B8=D0=B5=20=D1=82=D0=B8=D0=BF=D0=B0=20=D0=B0?= =?UTF-8?q?=D0=B4=D1=80=D0=B5=D1=81=D0=B0=20=D0=B4=D0=BB=D1=8F=20=D0=B4?= =?UTF-8?q?=D0=BE=D0=BD=D0=B0=D1=82=D0=BE=D0=B2=20(backport).?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index d3cd1c1b..39228e8e 100644 --- a/README.md +++ b/README.md @@ -9,7 +9,7 @@ > [5](https://libmdbx.dqdkfa.ru/tg-archive/messages5.html), [6](https://libmdbx.dqdkfa.ru/tg-archive/messages6.html), [7](https://libmdbx.dqdkfa.ru/tg-archive/messages7.html)). > See the [ChangeLog](https://gitflic.ru/project/erthink/libmdbx/blob?file=ChangeLog.md) for `NEWS` and latest updates. -> Donations are welcome to ETH `0xD104d8f8B2dC312aaD74899F83EBf3EEBDC1EA3A`. +> Donations are welcome to the Ethereum/ERC-20 `0xD104d8f8B2dC312aaD74899F83EBf3EEBDC1EA3A`. > Всё будет хорошо! From 19dc93fc76590dd309660fc10802b1f9e3f71f4c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=9B=D0=B5=D0=BE=D0=BD=D0=B8=D0=B4=20=D0=AE=D1=80=D1=8C?= =?UTF-8?q?=D0=B5=D0=B2=20=28Leonid=20Yuriev=29?= Date: Sun, 23 Mar 2025 17:46:28 +0300 Subject: [PATCH 08/52] =?UTF-8?q?mdbx:=20=D0=B4=D0=BE=D0=BF=D0=BE=D0=BB?= =?UTF-8?q?=D0=BD=D0=B5=D0=BD=D0=B8=D0=B5=20ChangeLog.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ChangeLog.md | 43 ++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 42 insertions(+), 1 deletion(-) diff --git a/ChangeLog.md b/ChangeLog.md index f8d23b11..414c65ba 100644 --- a/ChangeLog.md +++ b/ChangeLog.md @@ -4,6 +4,47 @@ ChangeLog English version [by liar Google](https://libmdbx-dqdkfa-ru.translate.goog/md__change_log.html?_x_tr_sl=ru&_x_tr_tl=en) and [by Yandex](https://translated.turbopages.org/proxy_u/ru-en.en/https/libmdbx.dqdkfa.ru/md__change_log.html). +## v0.13.6 в процессе накопления изменений + +Поддерживающий выпуск стабильной ветки с исправлением обнаруженных ошибок и устранением недочётов. + +Благодарности: + + - [Erigon](https://erigon.tech/) за спонсорство. + - [Илье Михееву](https://t.me/IlyaMkhv) и команде [Erigon](https://github.com/erigontech) за сообщения о проблеме и тестирование. + +Исправления: + + - Устраненен регресс при использовании курсоров для DBI=0 в читающих транзакциях. + + В результате рефакторинга и ряда оптимизаций для завершения/гашения + курсоров в читающих и пишущих транзакций стал использоваться общий код. + Причем за основу, был взят соответствующий фрагмент относящийся к + пишущим транзакциям, в которых пользователю не позволяется + использоваться курсоры для DBI=0 и поэтому эта итераций пропускалась. + + В результате, при завершении читающих транзакциях, курсоры связанные с + DBI=0 не завершались должным образом, а при их повторном использовании + или явном закрытии после завершения читающей транзакции происходило + обращение к уже освобожденной памяти. Если же такие курсоры + отсоединялись или закрывались до завершения читающей транзакции, то + ошибка не имела шансов на проявление. + +Прочие доработки: + + - Уточнен тип адреса для пожертвований. + Ethereum/ERC-20 позволяет перечислять не только ETH, но и другие валюты/токены, в том числе USDC. + + - Вброс `std::invalid_argument` теперь производится явным сообщением `MDBX_EINVAL`. + + - Дополнен тест курсоров extra/cursor-closing. + + - В `NOTICE` обновлена информация о Github. + + +-------------------------------------------------------------------------------- + + ## v0.13.5 "Труба" от 2025-03-21 Поддерживающий выпуск стабильной ветки с исправлением обнаруженных ошибок и устранением недочётов. @@ -107,7 +148,7 @@ and [by Yandex](https://translated.turbopages.org/proxy_u/ru-en.en/https/libmdbx поломать родительскую, сделав её продолжение невозможным. Если восстанавливать, то также следует «воскрешать» закрытые курсоры, что неизбежно приведет к путанице, утечкам памяти и использованию после освобождения. - - В C++ API отменён вброс исключения при запросе транзакции у отсоединённого курсора посредством вывоза `mdbx::cursor::txn()`. + - В C++ API отменён вброс исключения при запросе транзакции у отсоединённого курсора посредством вызова `mdbx::cursor::txn()`. Прочие доработки: From 56a6377622c35b8fee264b5075bd25ee53756395 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=9B=D0=B5=D0=BE=D0=BD=D0=B8=D0=B4=20=D0=AE=D1=80=D1=8C?= =?UTF-8?q?=D0=B5=D0=B2=20=28Leonid=20Yuriev=29?= Date: Fri, 28 Mar 2025 15:14:54 +0300 Subject: [PATCH 09/52] =?UTF-8?q?mdbx:=20=D0=BF=D0=BE=D0=BD=D0=B8=D0=B6?= =?UTF-8?q?=D0=B5=D0=BD=D0=B8=D0=B5=20=D1=83=D1=80=D0=BE=D0=B2=D0=BD=D1=8F?= =?UTF-8?q?=20=D0=BB=D0=BE=D0=B3=D0=B8=D1=80=D0=BE=D0=B2=D0=B0=D0=BD=D0=B8?= =?UTF-8?q?=D1=8F=20=D0=B4=D0=BB=D1=8F=20"skip=20update=20meta"=20(backpor?= =?UTF-8?q?t).?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Спасибо [Илье Михееву](https://github.com/JkLondon) за сообщение о недочете. --- src/dxb.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/dxb.c b/src/dxb.c index 29df1ee6..b6a353ce 100644 --- a/src/dxb.c +++ b/src/dxb.c @@ -1157,7 +1157,8 @@ int dxb_sync_locked(MDBX_env *env, unsigned flags, meta_t *const pending, troika if (!head.is_steady && meta_is_steady(pending)) target = (meta_t *)head.ptr_c; else { - WARNING("%s", "skip update meta"); + NOTICE("skip update meta%" PRIaPGNO " for txn#%" PRIaTXN "since it is already steady", + data_page(head.ptr_c)->pgno, head.txnid); return MDBX_SUCCESS; } } else { From 1c49548ea5ee9f58cf5c1f4f0fb69df2fddbf855 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=9B=D0=B5=D0=BE=D0=BD=D0=B8=D0=B4=20=D0=AE=D1=80=D1=8C?= =?UTF-8?q?=D0=B5=D0=B2=20=28Leonid=20Yuriev=29?= Date: Tue, 1 Apr 2025 21:18:11 +0300 Subject: [PATCH 10/52] mdbx-dc: fix typos. --- docs/_restrictions.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/_restrictions.md b/docs/_restrictions.md index 631f625f..6d17a5a3 100644 --- a/docs/_restrictions.md +++ b/docs/_restrictions.md @@ -54,7 +54,7 @@ cleans readers, as an a process aborting (especially with core dump) can take a long time, and checking readers cannot be performed too often due to performance degradation. -This issue will be addressed in MithrlDB and one of libmdbx releases, +This issue will be addressed in MithrilDB and one of libmdbx releases, presumably in 2025. To do this, nonlinear GC recycling will be implemented, without stopping garbage recycling on the old MVCC snapshot used by a long read transaction. @@ -92,7 +92,7 @@ free consecutive/adjacent pages through GC has been significantly speeded, including acceleration using NOEN/SSE2/AVX2/AVX512 instructions. -This issue will be addressed in MithrlDB and refined within one of +This issue will be addressed in MithrilDB and refined within one of 0.15.x libmdbx releases, presumably at end of 2025. From 187bd59aa0e3efa70b5d24af2a38ef2a9ec00339 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=9B=D0=B5=D0=BE=D0=BD=D0=B8=D0=B4=20=D0=AE=D1=80=D1=8C?= =?UTF-8?q?=D0=B5=D0=B2=20=28Leonid=20Yuriev=29?= Date: Wed, 2 Apr 2025 16:21:40 +0300 Subject: [PATCH 11/52] =?UTF-8?q?mdbx:=20=D0=B4=D0=BE=D0=B1=D0=B0=D0=B2?= =?UTF-8?q?=D0=BB=D0=B5=D0=BD=D0=B8=D0=B5=20badge-=D1=81=D1=81=D1=8B=D0=BB?= =?UTF-8?q?=D0=BA=D0=B8=20=D0=BD=D0=B0=20=D1=82=D0=B5=D0=BB=D0=B5=D0=B3?= =?UTF-8?q?=D1=80=D0=B0=D0=BC=20=D0=B8=20=D1=80=D0=BE=D0=BA=D0=B8=D1=80?= =?UTF-8?q?=D0=BE=D0=B2=D0=BA=D0=B0=20=D0=BF=D0=B0=D1=80=D0=B0=D0=B3=D1=80?= =?UTF-8?q?=D0=B0=D1=84=D0=BE=D0=B2=20=D0=B2=20=D0=BD=D0=B0=D1=87=D0=B0?= =?UTF-8?q?=D0=BB=D0=B5=20README.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 45 ++++++++++++++++++++++----------------------- 1 file changed, 22 insertions(+), 23 deletions(-) diff --git a/README.md b/README.md index 39228e8e..981d6c18 100644 --- a/README.md +++ b/README.md @@ -1,18 +1,5 @@ -> Please refer to the online [documentation](https://libmdbx.dqdkfa.ru) -> with [`C` API description](https://libmdbx.dqdkfa.ru/group__c__api.html) -> and pay attention to the [`C++` API](https://gitflic.ru/project/erthink/libmdbx/blob?file=mdbx.h%2B%2B#line-num-1). - -> Questions, feedback and suggestions are welcome to the [Telegram' group](https://t.me/libmdbx) (archive [1](https://libmdbx.dqdkfa.ru/tg-archive/messages1.html), -> [2](https://libmdbx.dqdkfa.ru/tg-archive/messages2.html), [3](https://libmdbx.dqdkfa.ru/tg-archive/messages3.html), [4](https://libmdbx.dqdkfa.ru/tg-archive/messages4.html), -> [5](https://libmdbx.dqdkfa.ru/tg-archive/messages5.html), [6](https://libmdbx.dqdkfa.ru/tg-archive/messages6.html), [7](https://libmdbx.dqdkfa.ru/tg-archive/messages7.html)). -> See the [ChangeLog](https://gitflic.ru/project/erthink/libmdbx/blob?file=ChangeLog.md) for `NEWS` and latest updates. - -> Donations are welcome to the Ethereum/ERC-20 `0xD104d8f8B2dC312aaD74899F83EBf3EEBDC1EA3A`. -> Всё будет хорошо! - - libmdbx ======== @@ -39,32 +26,44 @@ tree](https://en.wikipedia.org/wiki/B%2B_tree). [WAL](https://en.wikipedia.org/wiki/Write-ahead_logging), but that might be a caveat for write-intensive workloads with durability requirements. -4. **Compact and friendly for fully embedding**. Only ≈25KLOC of `C11`, -≈64K x86 binary code of core, no internal threads neither server process(es), -but implements a simplified variant of the [Berkeley -DB](https://en.wikipedia.org/wiki/Berkeley_DB) and -[dbm](https://en.wikipedia.org/wiki/DBM_(computing)) API. - -5. Enforces [serializability](https://en.wikipedia.org/wiki/Serializability) for +4. Enforces [serializability](https://en.wikipedia.org/wiki/Serializability) for writers just by single [mutex](https://en.wikipedia.org/wiki/Mutual_exclusion) and affords [wait-free](https://en.wikipedia.org/wiki/Non-blocking_algorithm#Wait-freedom) for parallel readers without atomic/interlocked operations, while **writing and reading transactions do not block each other**. -6. **Guarantee data integrity** after crash unless this was explicitly +5. **Guarantee data integrity** after crash unless this was explicitly neglected in favour of write performance. -7. Supports Linux, Windows, MacOS, Android, iOS, FreeBSD, DragonFly, Solaris, +6. Supports Linux, Windows, MacOS, Android, iOS, FreeBSD, DragonFly, Solaris, OpenSolaris, OpenIndiana, NetBSD, OpenBSD and other systems compliant with **POSIX.1-2008**. +7. **Compact and friendly for fully embedding**. Only ≈25KLOC of `C11`, +≈64K x86 binary code of core, no internal threads neither server process(es), +but implements a simplified variant of the [Berkeley +DB](https://en.wikipedia.org/wiki/Berkeley_DB) and +[dbm](https://en.wikipedia.org/wiki/DBM_(computing)) API. + -Historically, _libmdbx_ is a deeply revised and extended descendant of the amazing +Historically, _libmdbx_ is a deeply revised and extended descendant of the legendary [Lightning Memory-Mapped Database](https://en.wikipedia.org/wiki/Lightning_Memory-Mapped_Database). _libmdbx_ inherits all benefits from _LMDB_, but resolves some issues and adds [a set of improvements](#improvements-beyond-lmdb). +[![Telergam: Support | Discussions | News](https://img.shields.io/endpoint?color=scarlet&logo=telegram&label=Support%20%7C%20Discussions%20%7C%20News&url=https%3A%2F%2Ftg.sumanjay.workers.dev%2Flibmdbx)](https://t.me/libmdbx) + +> Please refer to the online [documentation](https://libmdbx.dqdkfa.ru) +> with [`C` API description](https://libmdbx.dqdkfa.ru/group__c__api.html) +> and pay attention to the [`C++` API](https://gitflic.ru/project/erthink/libmdbx/blob?file=mdbx.h%2B%2B#line-num-1). +> Donations are welcome to the Ethereum/ERC-20 `0xD104d8f8B2dC312aaD74899F83EBf3EEBDC1EA3A`. +> Всё будет хорошо! + +Telegram Group archive: [1](https://libmdbx.dqdkfa.ru/tg-archive/messages1.html), +[2](https://libmdbx.dqdkfa.ru/tg-archive/messages2.html), [3](https://libmdbx.dqdkfa.ru/tg-archive/messages3.html), [4](https://libmdbx.dqdkfa.ru/tg-archive/messages4.html), +[5](https://libmdbx.dqdkfa.ru/tg-archive/messages5.html), [6](https://libmdbx.dqdkfa.ru/tg-archive/messages6.html), [7](https://libmdbx.dqdkfa.ru/tg-archive/messages7.html). + ## Github ### на Русском (мой родной язык) From 6cb1b6754e77b1397bb54d417167c16066d56c8e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=9B=D0=B5=D0=BE=D0=BD=D0=B8=D0=B4=20=D0=AE=D1=80=D1=8C?= =?UTF-8?q?=D0=B5=D0=B2=20=28Leonid=20Yuriev=29?= Date: Sun, 6 Apr 2025 14:09:51 +0300 Subject: [PATCH 12/52] =?UTF-8?q?mdbx-doc:=20=D0=B8=D1=81=D0=BF=D1=80?= =?UTF-8?q?=D0=B0=D0=B2=D0=BB=D0=B5=D0=BD=D0=B8=D0=B5=20=D0=BF=D0=BE=D0=B2?= =?UTF-8?q?=D1=82=D0=BE=D1=80=D0=B0=20=D0=B2=20=D0=BA=D0=BE=D0=BC=D0=BC?= =?UTF-8?q?=D0=B5=D0=BD=D1=82=D0=B0=D1=80=D0=B8=D0=B8.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/layout-lck.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/layout-lck.h b/src/layout-lck.h index accf79a9..5c8022f4 100644 --- a/src/layout-lck.h +++ b/src/layout-lck.h @@ -186,7 +186,7 @@ typedef struct reader_slot { /* The header for the reader table (a memory-mapped lock file). */ typedef struct shared_lck { /* Stamp identifying this as an MDBX file. - * It must be set to MDBX_MAGIC with with MDBX_LOCK_VERSION. */ + * It must be set to MDBX_MAGIC with MDBX_LOCK_VERSION. */ uint64_t magic_and_version; /* Format of this lock file. Must be set to MDBX_LOCK_FORMAT. */ From 8d0eceee9f36be63cfa59c3e85d90533a920a897 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=9B=D0=B5=D0=BE=D0=BD=D0=B8=D0=B4=20=D0=AE=D1=80=D1=8C?= =?UTF-8?q?=D0=B5=D0=B2=20=28Leonid=20Yuriev=29?= Date: Mon, 7 Apr 2025 05:28:16 +0300 Subject: [PATCH 13/52] =?UTF-8?q?mdbx:=20=D0=BE=D1=82=D0=BA=D0=BB=D1=8E?= =?UTF-8?q?=D1=87=D0=B5=D0=BD=D0=B8=D0=B5=20=D0=B8=D1=81=D0=BF=D0=BE=D0=BB?= =?UTF-8?q?=D1=8C=D0=B7=D0=BE=D0=B2=D0=B0=D0=BD=D0=B8=D1=8F=20`copy=5Ffile?= =?UTF-8?q?=5Frange()`=20=D0=B4=D0=BB=D1=8F=20=D1=8F=D0=B4=D0=B5=D1=80=20l?= =?UTF-8?q?inux=205.3-5.18=20=D0=B2=D0=BA=D0=BB=D1=8E=D1=87=D0=B8=D1=82?= =?UTF-8?q?=D0=B5=D0=BB=D1=8C=D0=BD=D0=BE.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/api-copy.c | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/src/api-copy.c b/src/api-copy.c index 08c01192..ca109d84 100644 --- a/src/api-copy.c +++ b/src/api-copy.c @@ -571,11 +571,17 @@ retry_snap_meta: uint8_t *const data_buffer = buffer + ceil_powerof2(meta_bytes, globals.sys_pagesize); #if MDBX_USE_COPYFILERANGE static bool copyfilerange_unavailable; +#if (defined(__linux__) || defined(__gnu_linux__)) + if (globals.linux_kernel_version >= 0x05030000 && globals.linux_kernel_version < 0x05130000) + copyfilerange_unavailable = true; +#endif /* linux */ bool not_the_same_filesystem = false; - struct statfs statfs_info; - if (fstatfs(fd, &statfs_info) || statfs_info.f_type == /* ECRYPTFS_SUPER_MAGIC */ 0xf15f) - /* avoid use copyfilerange_unavailable() to ecryptfs due bugs */ - not_the_same_filesystem = true; + if (!copyfilerange_unavailable) { + struct statfs statfs_info; + if (fstatfs(fd, &statfs_info) || statfs_info.f_type == /* ECRYPTFS_SUPER_MAGIC */ 0xf15f) + /* avoid use copyfilerange_unavailable() to ecryptfs due bugs */ + not_the_same_filesystem = true; + } #endif /* MDBX_USE_COPYFILERANGE */ for (size_t offset = meta_bytes; rc == MDBX_SUCCESS && offset < used_size;) { From f91c2bb8daa5b896570fedb7c2895c474fc37584 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=9B=D0=B5=D0=BE=D0=BD=D0=B8=D0=B4=20=D0=AE=D1=80=D1=8C?= =?UTF-8?q?=D0=B5=D0=B2=20=28Leonid=20Yuriev=29?= Date: Wed, 9 Apr 2025 10:57:48 +0300 Subject: [PATCH 14/52] mdbx-doc: TODO typo and SWIG-url. --- TODO.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/TODO.md b/TODO.md index 8f3f1f21..9b6211b0 100644 --- a/TODO.md +++ b/TODO.md @@ -11,7 +11,7 @@ For the same reason ~~Github~~ is blacklisted forever. So currently most of the links are broken due to noted malicious ~~Github~~ sabotage. - - SWING. + - [SWIG](https://www.swig.org/). - Параллельная lto-сборка с устранением предупреждений. - Интеграция c DTrace и аналогами. - Новый стиль обработки ошибок с записью "трассы" и причин. From 29bed7cf5dfedeccd799c529184bc53aee956e20 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=9B=D0=B5=D0=BE=D0=BD=D0=B8=D0=B4=20=D0=AE=D1=80=D1=8C?= =?UTF-8?q?=D0=B5=D0=B2=20=28Leonid=20Yuriev=29?= Date: Mon, 7 Apr 2025 12:13:27 +0300 Subject: [PATCH 15/52] =?UTF-8?q?mdbx:=20=D0=B8=D0=B3=D0=BD=D0=BE=D1=80?= =?UTF-8?q?=D0=B8=D1=80=D0=BE=D0=B2=D0=B0=D0=BD=D0=B8=D0=B5=20`EAGAIN`=20?= =?UTF-8?q?=D0=BE=D1=82=20`flock()`=20=D0=B2=20=D1=81=D0=BB=D1=83=D1=87?= =?UTF-8?q?=D0=B0=D0=B5=20=D0=BA=D0=BE=D0=BF=D0=B8=D1=80=D0=BE=D0=B2=D0=B0?= =?UTF-8?q?=D0=BD=D0=B8=D1=8F=20=D0=BD=D0=B0=20NFS.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/api-copy.c | 22 ++++++++++++++++------ src/osal.c | 2 +- src/osal.h | 1 + 3 files changed, 18 insertions(+), 7 deletions(-) diff --git a/src/api-copy.c b/src/api-copy.c index ca109d84..9f0ce892 100644 --- a/src/api-copy.c +++ b/src/api-copy.c @@ -766,14 +766,24 @@ __cold static int copy2pathname(MDBX_txn *txn, const pathchar_t *dest_path, MDBX lock_op.l_whence = SEEK_SET; lock_op.l_start = 0; lock_op.l_len = OFF_T_MAX; - if (MDBX_FCNTL(newfd, MDBX_F_SETLK, &lock_op) -#if (defined(__linux__) || defined(__gnu_linux__)) && defined(LOCK_EX) && \ - (!defined(__ANDROID_API__) || __ANDROID_API__ >= 24) - || flock(newfd, LOCK_EX | LOCK_NB) -#endif /* Linux */ - ) + if (MDBX_FCNTL(newfd, MDBX_F_SETLK, &lock_op)) rc = errno; } + +#if defined(LOCK_EX) && (!defined(__ANDROID_API__) || __ANDROID_API__ >= 24) + if (rc == MDBX_SUCCESS && flock(newfd, LOCK_EX | LOCK_NB)) { + const int err_flock = errno, err_fs = osal_check_fs_local(newfd, 0); + if (err_flock != EAGAIN || err_fs != MDBX_EREMOTE) { + ERROR("%s flock(%" MDBX_PRIsPATH ") error %d, remote-fs check status %d", "unexpected", dest_path, err_flock, + err_fs); + rc = err_flock; + } else { + WARNING("%s flock(%" MDBX_PRIsPATH ") error %d, remote-fs check status %d", "ignore", dest_path, err_flock, + err_fs); + } + } +#endif /* LOCK_EX && ANDROID_API >= 24 */ + #endif /* Windows / POSIX */ if (rc == MDBX_SUCCESS) diff --git a/src/osal.c b/src/osal.c index ec2e0d7c..0ba44b61 100644 --- a/src/osal.c +++ b/src/osal.c @@ -1745,7 +1745,7 @@ MDBX_INTERNAL int osal_check_fs_incore(mdbx_filehandle_t handle) { return MDBX_RESULT_FALSE; } -static int osal_check_fs_local(mdbx_filehandle_t handle, int flags) { +MDBX_INTERNAL int osal_check_fs_local(mdbx_filehandle_t handle, int flags) { #if defined(_WIN32) || defined(_WIN64) if (globals.running_under_Wine && !(flags & MDBX_EXCLUSIVE)) return ERROR_NOT_CAPABLE /* workaround for Wine */; diff --git a/src/osal.h b/src/osal.h index 484bbab8..06f58c60 100644 --- a/src/osal.h +++ b/src/osal.h @@ -481,6 +481,7 @@ MDBX_INTERNAL int osal_resume_threads_after_remap(mdbx_handle_array_t *array); MDBX_INTERNAL int osal_msync(const osal_mmap_t *map, size_t offset, size_t length, enum osal_syncmode_bits mode_bits); MDBX_INTERNAL int osal_check_fs_rdonly(mdbx_filehandle_t handle, const pathchar_t *pathname, int err); MDBX_INTERNAL int osal_check_fs_incore(mdbx_filehandle_t handle); +MDBX_INTERNAL int osal_check_fs_local(mdbx_filehandle_t handle, int flags); MDBX_MAYBE_UNUSED static inline uint32_t osal_getpid(void) { STATIC_ASSERT(sizeof(mdbx_pid_t) <= sizeof(uint32_t)); From b55a41f6041ea11145a0bf309f269ad5224536ba Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=9B=D0=B5=D0=BE=D0=BD=D0=B8=D0=B4=20=D0=AE=D1=80=D1=8C?= =?UTF-8?q?=D0=B5=D0=B2=20=28Leonid=20Yuriev=29?= Date: Wed, 9 Apr 2025 22:18:13 +0300 Subject: [PATCH 16/52] =?UTF-8?q?mdbx:=20=D0=B4=D0=BE=D0=BF=D0=BE=D0=BB?= =?UTF-8?q?=D0=BD=D0=B5=D0=BD=D0=B8=D0=B5=20ChangeLog.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ChangeLog.md | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/ChangeLog.md b/ChangeLog.md index 414c65ba..8ae6f3f5 100644 --- a/ChangeLog.md +++ b/ChangeLog.md @@ -12,10 +12,11 @@ and [by Yandex](https://translated.turbopages.org/proxy_u/ru-en.en/https/libmdbx - [Erigon](https://erigon.tech/) за спонсорство. - [Илье Михееву](https://t.me/IlyaMkhv) и команде [Erigon](https://github.com/erigontech) за сообщения о проблеме и тестирование. + - [Алексею Костюку (aka Keller)](https://t.me/keller18306) за сообщения о проблеме копирования на NFS. Исправления: - - Устраненен регресс при использовании курсоров для DBI=0 в читающих транзакциях. + - Устранён регресс при использовании курсоров для DBI=0 в читающих транзакциях. В результате рефакторинга и ряда оптимизаций для завершения/гашения курсоров в читающих и пишущих транзакций стал использоваться общий код. @@ -30,13 +31,24 @@ and [by Yandex](https://translated.turbopages.org/proxy_u/ru-en.en/https/libmdbx отсоединялись или закрывались до завершения читающей транзакции, то ошибка не имела шансов на проявление. + - Устранён регресс в виде ошибки `EAGAIN` при копировании БД на NFS и CIFS/SMB. + + При доработках/развитии API в функции копирования был добавлен захват + файловой блокировки посредством как `fcntl()`, так и `flock()`. Однако, + в зависимости от версии локального ядра, версии удалённого сервера NFS и + опций монтирования, это могло приводить к возврату POSIX-ошибки `EAGAIN` + (`11` на большинстве платформ, включая Linux). + + Прочие доработки: + - Во избежание потенциальных проблем отключено использование `copy_file_range()` на ядрах Linux 5.3 - 5.18. + + - Вброс `std::invalid_argument` теперь производится явным сообщением `MDBX_EINVAL`. + - Уточнен тип адреса для пожертвований. Ethereum/ERC-20 позволяет перечислять не только ETH, но и другие валюты/токены, в том числе USDC. - - Вброс `std::invalid_argument` теперь производится явным сообщением `MDBX_EINVAL`. - - Дополнен тест курсоров extra/cursor-closing. - В `NOTICE` обновлена информация о Github. From 4691c0b5c83c1edabedb0c682b9ff9d21a21a511 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=9B=D0=B5=D0=BE=D0=BD=D0=B8=D0=B4=20=D0=AE=D1=80=D1=8C?= =?UTF-8?q?=D0=B5=D0=B2=20=28Leonid=20Yuriev=29?= Date: Thu, 10 Apr 2025 11:35:43 +0300 Subject: [PATCH 17/52] =?UTF-8?q?mdbx:=20=D0=B8=D1=81=D0=BF=D1=80=D0=B0?= =?UTF-8?q?=D0=B2=D0=BB=D0=B5=D0=BD=D0=B8=D0=B5=20=D0=BE=D1=88=D0=B8=D0=B1?= =?UTF-8?q?=D0=BE=D0=BA=20merge/rebase.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/api-cursor.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/api-cursor.c b/src/api-cursor.c index 4a506b41..e5cc0592 100644 --- a/src/api-cursor.c +++ b/src/api-cursor.c @@ -245,9 +245,8 @@ int mdbx_txn_release_all_cursors_ex(const MDBX_txn *txn, bool unbind, size_t *co MDBX_cursor *bk = mc->backup; mc->next = bk->next; mc->backup = bk->backup; - mc->backup = nullptr; + bk->backup = nullptr; bk->signature = 0; - bk = bk->next; osal_free(bk); } else { mc->signature = cur_signature_ready4dispose; From f35c1fe5bccb9c16f879ccf73f9ca235d0b70dbe Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=9B=D0=B5=D0=BE=D0=BD=D0=B8=D0=B4=20=D0=AE=D1=80=D1=8C?= =?UTF-8?q?=D0=B5=D0=B2=20=28Leonid=20Yuriev=29?= Date: Thu, 10 Apr 2025 11:40:17 +0300 Subject: [PATCH 18/52] =?UTF-8?q?mdbx:=20=D0=B8=D1=81=D0=BF=D1=80=D0=B0?= =?UTF-8?q?=D0=B2=D0=BB=D0=B5=D0=BD=D0=B8=D0=B5=20=D0=BD=D0=B5=D0=B2=D0=B5?= =?UTF-8?q?=D1=80=D0=BD=D0=BE=D0=B9=20assert-=D0=BF=D1=80=D0=BE=D0=B2?= =?UTF-8?q?=D0=B5=D1=80=D0=BA=D0=B8=20=D0=B8=20=D0=BC=D0=B8=D0=BA=D1=80?= =?UTF-8?q?=D0=BE=D0=BE=D0=BF=D1=82=D0=B8=D0=BC=D0=B8=D0=B7=D0=B0=D1=86?= =?UTF-8?q?=D0=B8=D1=8F.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit В пути фиксации вложенных транзакций, условие в assert-проверке не было корректным для случая, когда таблица уже существовала и её дескриптор был открыт, использовался в завершаемой вложенной транзакции, но не использовался в родительской. Это исправление недочета также передаёт уже загруженное из БД кешируемое состояние таблицы в родительскую транзакцию. --- src/txn-nested.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/txn-nested.c b/src/txn-nested.c index 09cd87aa..dcd89c7a 100644 --- a/src/txn-nested.c +++ b/src/txn-nested.c @@ -560,15 +560,16 @@ int txn_nested_join(MDBX_txn *txn, struct commit_timestamp *ts) { /* Update parent's DBs array */ eASSERT(env, parent->n_dbi == txn->n_dbi); TXN_FOREACH_DBI_ALL(txn, dbi) { - if (txn->dbi_state[dbi] & (DBI_CREAT | DBI_FRESH | DBI_DIRTY)) { + if (txn->dbi_state[dbi] != (parent->dbi_state[dbi] & ~(DBI_FRESH | DBI_CREAT | DBI_DIRTY))) { + eASSERT(env, (txn->dbi_state[dbi] & (DBI_CREAT | DBI_FRESH | DBI_DIRTY)) != 0 || + (txn->dbi_state[dbi] | DBI_STALE) == + (parent->dbi_state[dbi] & ~(DBI_FRESH | DBI_CREAT | DBI_DIRTY))); parent->dbs[dbi] = txn->dbs[dbi]; /* preserve parent's status */ const uint8_t state = txn->dbi_state[dbi] | (parent->dbi_state[dbi] & (DBI_CREAT | DBI_FRESH | DBI_DIRTY)); DEBUG("dbi %zu dbi-state %s 0x%02x -> 0x%02x", dbi, (parent->dbi_state[dbi] != state) ? "update" : "still", parent->dbi_state[dbi], state); parent->dbi_state[dbi] = state; - } else { - eASSERT(env, txn->dbi_state[dbi] == (parent->dbi_state[dbi] & ~(DBI_FRESH | DBI_CREAT | DBI_DIRTY))); } } From a04053ee98c729af3dce121990eb1f6631a91beb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=9B=D0=B5=D0=BE=D0=BD=D0=B8=D0=B4=20=D0=AE=D1=80=D1=8C?= =?UTF-8?q?=D0=B5=D0=B2=20=28Leonid=20Yuriev=29?= Date: Thu, 10 Apr 2025 12:10:12 +0300 Subject: [PATCH 19/52] =?UTF-8?q?mdbx:=20=D0=B2=D0=BE=D0=B7=D0=B2=D1=80?= =?UTF-8?q?=D0=B0=D1=82=20`MDBX=5FEINVAL`=20=D0=B8=D0=B7=20`mdbx=5Fcursor?= =?UTF-8?q?=5Fbind()`=20=D0=BF=D1=80=D0=B8=20=D0=BD=D0=B5=D0=B2=D0=BE?= =?UTF-8?q?=D0=B7=D0=BC=D0=BE=D0=B6=D0=BD=D0=BE=D1=81=D1=82=D0=B8=20=D0=BE?= =?UTF-8?q?=D1=82=D0=B2=D1=8F=D0=B7=D0=BA=D0=B8=20=D0=BA=D1=83=D1=80=D1=81?= =?UTF-8?q?=D0=BE=D1=80=D0=B0=20=D0=BE=D1=82=20=D0=B5=D0=B3=D0=BE=20=D1=82?= =?UTF-8?q?=D0=B5=D0=BA=D1=83=D1=89=D0=B5=D0=B9=20=D1=82=D1=80=D0=B0=D0=BD?= =?UTF-8?q?=D0=B7=D0=B0=D0=BA=D1=86=D0=B8=D0=B8.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/api-cursor.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/api-cursor.c b/src/api-cursor.c index e5cc0592..bb53023d 100644 --- a/src/api-cursor.c +++ b/src/api-cursor.c @@ -63,7 +63,7 @@ int mdbx_cursor_bind(MDBX_txn *txn, MDBX_cursor *mc, MDBX_dbi dbi) { return MDBX_SUCCESS; rc = mdbx_cursor_unbind(mc); if (unlikely(rc != MDBX_SUCCESS)) - return rc; + return (rc == MDBX_BAD_TXN) ? MDBX_EINVAL : rc; } cASSERT(mc, mc->next == mc); From 5bd99d4da2a4c4a8904e6ae8160c668b5e9b4047 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=9B=D0=B5=D0=BE=D0=BD=D0=B8=D0=B4=20=D0=AE=D1=80=D1=8C?= =?UTF-8?q?=D0=B5=D0=B2=20=28Leonid=20Yuriev=29?= Date: Thu, 10 Apr 2025 12:14:08 +0300 Subject: [PATCH 20/52] =?UTF-8?q?mdbx:=20=D0=BF=D0=BE=D0=B4=D1=81=D0=BA?= =?UTF-8?q?=D0=B0=D0=B7=D0=BA=D0=B0=20=D0=B4=D0=BB=D1=8F=20Coverity=20?= =?UTF-8?q?=D0=B4=D0=BB=D1=8F=20=D0=BF=D0=BE=D0=B4=D0=B0=D0=B2=D0=BB=D0=B5?= =?UTF-8?q?=D0=BD=D0=B8=D1=8F=20=D0=BB=D0=BE=D0=B6=D0=BD=D0=BE-=D0=BF?= =?UTF-8?q?=D0=BE=D0=BB=D0=BE=D0=B6=D0=B8=D1=82=D0=B5=D0=BB=D1=8C=D0=BD?= =?UTF-8?q?=D1=8B=D1=85=20=D0=BF=D1=80=D0=B5=D0=B4=D1=83=D0=BF=D1=80=D0=B5?= =?UTF-8?q?=D0=B6=D0=B4=D0=B5=D0=BD=D0=B8=D0=B9.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/dbi.h | 1 + 1 file changed, 1 insertion(+) diff --git a/src/dbi.h b/src/dbi.h index f634ee19..69de4d08 100644 --- a/src/dbi.h +++ b/src/dbi.h @@ -53,6 +53,7 @@ static inline size_t dbi_bitmap_ctz(const MDBX_txn *txn, intptr_t bmi) { I = (I - 1) | (bitmap_chunk - 1); \ bitmap_item = TXN->dbi_sparse[(1 + I) / bitmap_chunk]; \ if (!bitmap_item) \ + /* coverity[const_overflow] */ \ I += bitmap_chunk; \ continue; \ } else if ((bitmap_item & 1) == 0) { \ From 2ceda89b055a749d649c67279ab114e11d86d569 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=9B=D0=B5=D0=BE=D0=BD=D0=B8=D0=B4=20=D0=AE=D1=80=D1=8C?= =?UTF-8?q?=D0=B5=D0=B2=20=28Leonid=20Yuriev=29?= Date: Thu, 10 Apr 2025 12:14:53 +0300 Subject: [PATCH 21/52] =?UTF-8?q?mdbx-tests:=20=D1=80=D0=B0=D1=81=D1=88?= =?UTF-8?q?=D0=B8=D1=80=D0=B5=D0=BD=D0=B8=D0=B5=20=D0=B8=20=D0=B4=D0=BE?= =?UTF-8?q?=D1=80=D0=B0=D0=B1=D0=BE=D1=82=D0=BA=D0=B0=20=D1=81=D1=86=D0=B5?= =?UTF-8?q?=D0=BD=D0=B0=D1=80=D0=B8=D1=8F=20extra/cursor-closing.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- test/extra/cursor_closing.c++ | 30 +++++++++++++++++++++++++++--- 1 file changed, 27 insertions(+), 3 deletions(-) diff --git a/test/extra/cursor_closing.c++ b/test/extra/cursor_closing.c++ index 4bd4b7ca..2a0184a6 100644 --- a/test/extra/cursor_closing.c++ +++ b/test/extra/cursor_closing.c++ @@ -172,9 +172,21 @@ mdbx::map_handle case1_cycle_dbi(std::deque &dbi) { void case1_read_cycle(mdbx::txn txn, std::deque &dbi, std::vector &pool, mdbx::cursor pre, bool nested = false) { - for (auto c : pool) - mdbx::cursor(c).bind(txn, case1_cycle_dbi(dbi)); - pre.bind(txn, case1_cycle_dbi(dbi)); + if (nested) { + for (auto c : pool) + try { + mdbx::cursor(c).bind(txn, case1_cycle_dbi(dbi)); + } catch (const std::invalid_argument &) { + } + try { + pre.bind(txn, case1_cycle_dbi(dbi)); + } catch (const std::invalid_argument &) { + } + } else { + for (auto c : pool) + mdbx::cursor(c).bind(txn, case1_cycle_dbi(dbi)); + pre.bind(txn, case1_cycle_dbi(dbi)); + } for (auto n = prng(3 + dbi.size()); n > 0; --n) { auto c = txn.open_cursor(dbi[prng(dbi.size())]); @@ -215,6 +227,16 @@ void case1_read_cycle(mdbx::txn txn, std::deque &dbi, std::vec switch (prng(nested ? 7 : 3)) { case 0: + if (pre.txn()) { + if (nested) + try { + pre.unbind(); + } catch (const std::invalid_argument &) { + return; + } + else + pre.unbind(); + } for (auto i = pool.begin(); i != pool.end();) if (mdbx_cursor_txn(*i)) i = pool.erase(i); @@ -253,6 +275,8 @@ void case1_write_cycle(mdbx::txn_managed txn, std::deque &dbi, if (prng(16) > 8) case1_write_cycle(txn.start_nested(), dbi, pool, pre, true); + case1_read_cycle(txn, dbi, pool, pre, nested); + if (flipcoin()) txn.commit(); else From 5d38add4059f73ae28d5fa74e0bb3afafee31e51 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=9B=D0=B5=D0=BE=D0=BD=D0=B8=D0=B4=20=D0=AE=D1=80=D1=8C?= =?UTF-8?q?=D0=B5=D0=B2=20=28Leonid=20Yuriev=29?= Date: Thu, 10 Apr 2025 16:33:10 +0300 Subject: [PATCH 22/52] =?UTF-8?q?mdbx:=20=D0=B8=D1=81=D0=BF=D1=80=D0=B0?= =?UTF-8?q?=D0=B2=D0=BB=D0=B5=D0=BD=D0=B8=D0=B5=20=D0=BE=D1=88=D0=B8=D0=B1?= =?UTF-8?q?=D0=BE=D0=BA=20merge/rebase=20(backport).?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/api-cursor.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/api-cursor.c b/src/api-cursor.c index ef905024..0ebee0cc 100644 --- a/src/api-cursor.c +++ b/src/api-cursor.c @@ -244,9 +244,8 @@ int mdbx_txn_release_all_cursors_ex(const MDBX_txn *txn, bool unbind, size_t *co MDBX_cursor *bk = mc->backup; mc->next = bk->next; mc->backup = bk->backup; - mc->backup = nullptr; + bk->backup = nullptr; bk->signature = 0; - bk = bk->next; osal_free(bk); } else { mc->signature = cur_signature_ready4dispose; From 0e3b093eb59baf7ef7a8c2569934f59c0d2b71e0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=9B=D0=B5=D0=BE=D0=BD=D0=B8=D0=B4=20=D0=AE=D1=80=D1=8C?= =?UTF-8?q?=D0=B5=D0=B2=20=28Leonid=20Yuriev=29?= Date: Thu, 10 Apr 2025 16:34:19 +0300 Subject: [PATCH 23/52] =?UTF-8?q?mdbx:=20=D0=B8=D1=81=D0=BF=D1=80=D0=B0?= =?UTF-8?q?=D0=B2=D0=BB=D0=B5=D0=BD=D0=B8=D0=B5=20=D0=BD=D0=B5=D0=B2=D0=B5?= =?UTF-8?q?=D1=80=D0=BD=D0=BE=D0=B9=20assert-=D0=BF=D1=80=D0=BE=D0=B2?= =?UTF-8?q?=D0=B5=D1=80=D0=BA=D0=B8=20=D0=B8=20=D0=BC=D0=B8=D0=BA=D1=80?= =?UTF-8?q?=D0=BE=D0=BE=D0=BF=D1=82=D0=B8=D0=BC=D0=B8=D0=B7=D0=B0=D1=86?= =?UTF-8?q?=D0=B8=D1=8F=20(backport).?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit В пути фиксации вложенных транзакций, условие в assert-проверке не было корректным для случая, когда таблица уже существовала и её дескриптор был открыт, использовался в завершаемой вложенной транзакции, но не использовался в родительской. Это исправление недочета также передаёт, уже загруженное из БД, кешируемое состояние таблицы в родительскую транзакцию. --- src/api-txn.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/api-txn.c b/src/api-txn.c index 474f32fd..6cf9fcd1 100644 --- a/src/api-txn.c +++ b/src/api-txn.c @@ -545,15 +545,16 @@ int mdbx_txn_commit_ex(MDBX_txn *txn, MDBX_commit_latency *latency) { /* Update parent's DBs array */ eASSERT(env, parent->n_dbi == txn->n_dbi); TXN_FOREACH_DBI_ALL(txn, dbi) { - if (txn->dbi_state[dbi] & (DBI_CREAT | DBI_FRESH | DBI_DIRTY)) { + if (txn->dbi_state[dbi] != (parent->dbi_state[dbi] & ~(DBI_FRESH | DBI_CREAT | DBI_DIRTY))) { + eASSERT(env, (txn->dbi_state[dbi] & (DBI_CREAT | DBI_FRESH | DBI_DIRTY)) != 0 || + (txn->dbi_state[dbi] | DBI_STALE) == + (parent->dbi_state[dbi] & ~(DBI_FRESH | DBI_CREAT | DBI_DIRTY))); parent->dbs[dbi] = txn->dbs[dbi]; /* preserve parent's status */ const uint8_t state = txn->dbi_state[dbi] | (parent->dbi_state[dbi] & (DBI_CREAT | DBI_FRESH | DBI_DIRTY)); DEBUG("dbi %zu dbi-state %s 0x%02x -> 0x%02x", dbi, (parent->dbi_state[dbi] != state) ? "update" : "still", parent->dbi_state[dbi], state); parent->dbi_state[dbi] = state; - } else { - eASSERT(env, txn->dbi_state[dbi] == (parent->dbi_state[dbi] & ~(DBI_FRESH | DBI_CREAT | DBI_DIRTY))); } } From 9540cabf5f3c9b273ff1cae72cc2e7703cd0757e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=9B=D0=B5=D0=BE=D0=BD=D0=B8=D0=B4=20=D0=AE=D1=80=D1=8C?= =?UTF-8?q?=D0=B5=D0=B2=20=28Leonid=20Yuriev=29?= Date: Thu, 10 Apr 2025 16:34:57 +0300 Subject: [PATCH 24/52] =?UTF-8?q?mdbx:=20=D0=B2=D0=BE=D0=B7=D0=B2=D1=80?= =?UTF-8?q?=D0=B0=D1=82=20`MDBX=5FEINVAL`=20=D0=B8=D0=B7=20`mdbx=5Fcursor?= =?UTF-8?q?=5Fbind()`=20=D0=BF=D1=80=D0=B8=20=D0=BD=D0=B5=D0=B2=D0=BE?= =?UTF-8?q?=D0=B7=D0=BC=D0=BE=D0=B6=D0=BD=D0=BE=D1=81=D1=82=D0=B8=20=D0=BE?= =?UTF-8?q?=D1=82=D0=B2=D1=8F=D0=B7=D0=BA=D0=B8=20=D0=BA=D1=83=D1=80=D1=81?= =?UTF-8?q?=D0=BE=D1=80=D0=B0=20=D0=BE=D1=82=20=D0=B5=D0=B3=D0=BE=20=D1=82?= =?UTF-8?q?=D0=B5=D0=BA=D1=83=D1=89=D0=B5=D0=B9=20=D1=82=D1=80=D0=B0=D0=BD?= =?UTF-8?q?=D0=B7=D0=B0=D0=BA=D1=86=D0=B8=D0=B8=20(backport).?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/api-cursor.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/api-cursor.c b/src/api-cursor.c index 0ebee0cc..da68afb6 100644 --- a/src/api-cursor.c +++ b/src/api-cursor.c @@ -63,7 +63,7 @@ int mdbx_cursor_bind(MDBX_txn *txn, MDBX_cursor *mc, MDBX_dbi dbi) { return MDBX_SUCCESS; rc = mdbx_cursor_unbind(mc); if (unlikely(rc != MDBX_SUCCESS)) - return rc; + return (rc == MDBX_BAD_TXN) ? MDBX_EINVAL : rc; } cASSERT(mc, mc->next == mc); From a22c0c5c48944ed3dc099d49d862202afdb31c19 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=9B=D0=B5=D0=BE=D0=BD=D0=B8=D0=B4=20=D0=AE=D1=80=D1=8C?= =?UTF-8?q?=D0=B5=D0=B2=20=28Leonid=20Yuriev=29?= Date: Thu, 10 Apr 2025 16:35:53 +0300 Subject: [PATCH 25/52] =?UTF-8?q?mdbx:=20=D0=BF=D0=BE=D0=B4=D1=81=D0=BA?= =?UTF-8?q?=D0=B0=D0=B7=D0=BA=D0=B0=20=D0=B4=D0=BB=D1=8F=20Coverity=20?= =?UTF-8?q?=D0=B4=D0=BB=D1=8F=20=D0=BF=D0=BE=D0=B4=D0=B0=D0=B2=D0=BB=D0=B5?= =?UTF-8?q?=D0=BD=D0=B8=D1=8F=20=D0=BB=D0=BE=D0=B6=D0=BD=D0=BE-=D0=BF?= =?UTF-8?q?=D0=BE=D0=BB=D0=BE=D0=B6=D0=B8=D1=82=D0=B5=D0=BB=D1=8C=D0=BD?= =?UTF-8?q?=D1=8B=D1=85=20=D0=BF=D1=80=D0=B5=D0=B4=D1=83=D0=BF=D1=80=D0=B5?= =?UTF-8?q?=D0=B6=D0=B4=D0=B5=D0=BD=D0=B8=D0=B9=20(backport).?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/dbi.h | 1 + 1 file changed, 1 insertion(+) diff --git a/src/dbi.h b/src/dbi.h index 2dffd5f7..c71478d8 100644 --- a/src/dbi.h +++ b/src/dbi.h @@ -53,6 +53,7 @@ static inline size_t dbi_bitmap_ctz(const MDBX_txn *txn, intptr_t bmi) { I = (I - 1) | (bitmap_chunk - 1); \ bitmap_item = TXN->dbi_sparse[(1 + I) / bitmap_chunk]; \ if (!bitmap_item) \ + /* coverity[const_overflow] */ \ I += bitmap_chunk; \ continue; \ } else if ((bitmap_item & 1) == 0) { \ From 819551ce130b0fad8cc6e3aaf1e9de9d74689007 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=9B=D0=B5=D0=BE=D0=BD=D0=B8=D0=B4=20=D0=AE=D1=80=D1=8C?= =?UTF-8?q?=D0=B5=D0=B2=20=28Leonid=20Yuriev=29?= Date: Thu, 10 Apr 2025 16:37:42 +0300 Subject: [PATCH 26/52] =?UTF-8?q?mdbx-tests:=20=D1=80=D0=B0=D1=81=D1=88?= =?UTF-8?q?=D0=B8=D1=80=D0=B5=D0=BD=D0=B8=D0=B5=20=D0=B8=20=D0=B4=D0=BE?= =?UTF-8?q?=D1=80=D0=B0=D0=B1=D0=BE=D1=82=D0=BA=D0=B0=20=D1=81=D1=86=D0=B5?= =?UTF-8?q?=D0=BD=D0=B0=D1=80=D0=B8=D1=8F=20extra/cursor-closing=20(backpo?= =?UTF-8?q?rt).?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- test/extra/cursor_closing.c++ | 30 +++++++++++++++++++++++++++--- 1 file changed, 27 insertions(+), 3 deletions(-) diff --git a/test/extra/cursor_closing.c++ b/test/extra/cursor_closing.c++ index 4bd4b7ca..2a0184a6 100644 --- a/test/extra/cursor_closing.c++ +++ b/test/extra/cursor_closing.c++ @@ -172,9 +172,21 @@ mdbx::map_handle case1_cycle_dbi(std::deque &dbi) { void case1_read_cycle(mdbx::txn txn, std::deque &dbi, std::vector &pool, mdbx::cursor pre, bool nested = false) { - for (auto c : pool) - mdbx::cursor(c).bind(txn, case1_cycle_dbi(dbi)); - pre.bind(txn, case1_cycle_dbi(dbi)); + if (nested) { + for (auto c : pool) + try { + mdbx::cursor(c).bind(txn, case1_cycle_dbi(dbi)); + } catch (const std::invalid_argument &) { + } + try { + pre.bind(txn, case1_cycle_dbi(dbi)); + } catch (const std::invalid_argument &) { + } + } else { + for (auto c : pool) + mdbx::cursor(c).bind(txn, case1_cycle_dbi(dbi)); + pre.bind(txn, case1_cycle_dbi(dbi)); + } for (auto n = prng(3 + dbi.size()); n > 0; --n) { auto c = txn.open_cursor(dbi[prng(dbi.size())]); @@ -215,6 +227,16 @@ void case1_read_cycle(mdbx::txn txn, std::deque &dbi, std::vec switch (prng(nested ? 7 : 3)) { case 0: + if (pre.txn()) { + if (nested) + try { + pre.unbind(); + } catch (const std::invalid_argument &) { + return; + } + else + pre.unbind(); + } for (auto i = pool.begin(); i != pool.end();) if (mdbx_cursor_txn(*i)) i = pool.erase(i); @@ -253,6 +275,8 @@ void case1_write_cycle(mdbx::txn_managed txn, std::deque &dbi, if (prng(16) > 8) case1_write_cycle(txn.start_nested(), dbi, pool, pre, true); + case1_read_cycle(txn, dbi, pool, pre, nested); + if (flipcoin()) txn.commit(); else From 214fa153e2bbe30e0df1ad65cc3e726f7121f32e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=9B=D0=B5=D0=BE=D0=BD=D0=B8=D0=B4=20=D0=AE=D1=80=D1=8C?= =?UTF-8?q?=D0=B5=D0=B2=20=28Leonid=20Yuriev=29?= Date: Thu, 10 Apr 2025 16:54:13 +0300 Subject: [PATCH 27/52] =?UTF-8?q?mdbx:=20=D0=B4=D0=BE=D0=BF=D0=BE=D0=BB?= =?UTF-8?q?=D0=BD=D0=B5=D0=BD=D0=B8=D0=B5=20ChangeLog.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ChangeLog.md | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/ChangeLog.md b/ChangeLog.md index 8ae6f3f5..0d8ffe43 100644 --- a/ChangeLog.md +++ b/ChangeLog.md @@ -4,7 +4,7 @@ ChangeLog English version [by liar Google](https://libmdbx-dqdkfa-ru.translate.goog/md__change_log.html?_x_tr_sl=ru&_x_tr_tl=en) and [by Yandex](https://translated.turbopages.org/proxy_u/ru-en.en/https/libmdbx.dqdkfa.ru/md__change_log.html). -## v0.13.6 в процессе накопления изменений +## v0.13.6 в процессе накопления изменений, выпуск запланирован на вторую половину апреля. Поддерживающий выпуск стабильной ветки с исправлением обнаруженных ошибок и устранением недочётов. @@ -39,6 +39,17 @@ and [by Yandex](https://translated.turbopages.org/proxy_u/ru-en.en/https/libmdbx опций монтирования, это могло приводить к возврату POSIX-ошибки `EAGAIN` (`11` на большинстве платформ, включая Linux). + - Устранена ошибка merge/rebase внутри `mdbx_txn_release_all_cursors_ex()`, + что могло приводить к последующим неожиданным ошибкам `MDBX_EBADSIGN` и утечкам памяти. + Для проверки сценария дополнен соответствующий тест. + + - Исправлена assert-проверка в пути завершения вложенных транзакций. + Для проверки сценария дополнен соответствующий тест. + +Изменение поведения: + + - При невозможности отвязки курсора от его текущей транзакции функция `mdbx_cursor_bind()` + теперь возвращает `MDBX_EINVAL` вместо `MDBX_BAD_TXN`. Прочие доработки: From f6ce9381af50a4891206b9f772fbb73e0fd9894e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=9B=D0=B5=D0=BE=D0=BD=D0=B8=D0=B4=20=D0=AE=D1=80=D1=8C?= =?UTF-8?q?=D0=B5=D0=B2=20=28Leonid=20Yuriev=29?= Date: Fri, 18 Apr 2025 10:47:10 +0300 Subject: [PATCH 28/52] =?UTF-8?q?mdbx-tests:=20=D0=BE=D0=B1=D0=BD=D1=83?= =?UTF-8?q?=D0=BB=D0=B5=D0=BD=D0=B8=D0=B5=20pid=20=D0=BD=D0=B0=20=D0=B2?= =?UTF-8?q?=D1=85=D0=BE=D0=B4=D0=B5=20=D0=B2=20`osal=5Factor=5Fpoll()`.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- test/osal-unix.c++ | 1 + 1 file changed, 1 insertion(+) diff --git a/test/osal-unix.c++ b/test/osal-unix.c++ index b7233d03..dd58b827 100644 --- a/test/osal-unix.c++ +++ b/test/osal-unix.c++ @@ -510,6 +510,7 @@ int osal_actor_poll(mdbx_pid_t &pid, unsigned timeout) { options |= WCONTINUED; #endif + pid = 0; while (sigalarm_tail == sigalarm_head) { int status; pid = waitpid(0, &status, options); From 0f505c1377d6a529aca6d3e071ee6af554d2d0c9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=9B=D0=B5=D0=BE=D0=BD=D0=B8=D0=B4=20=D0=AE=D1=80=D1=8C?= =?UTF-8?q?=D0=B5=D0=B2=20=28Leonid=20Yuriev=29?= Date: Fri, 18 Apr 2025 10:49:00 +0300 Subject: [PATCH 29/52] =?UTF-8?q?mdbx:=20=D0=BF=D0=B5=D1=80=D0=B5=D1=83?= =?UTF-8?q?=D0=BF=D0=BE=D1=80=D1=8F=D0=B4=D0=BE=D1=87=D0=B8=D0=B2=D0=B0?= =?UTF-8?q?=D0=BD=D0=B8=D0=B5=20=D0=B0=D1=82=D1=80=D0=B8=D0=B1=D1=83=D1=82?= =?UTF-8?q?=D0=BE=D0=B2=20=D0=B4=D0=BB=D1=8F=20=D1=81=D0=BE=D0=B2=D0=BC?= =?UTF-8?q?=D0=B5=D1=81=D1=82=D0=B8=D0=BC=D0=BE=D1=81=D1=82=D0=B8=20=D1=81?= =?UTF-8?q?=20GCC-15=20=D0=B2=20=D1=80=D0=B5=D0=B6=D0=B8=D0=BC=D0=B5=20C23?= =?UTF-8?q?.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/chk.c | 4 ++-- src/osal.c | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/chk.c b/src/chk.c index 7ea451c7..e444ff85 100644 --- a/src/chk.c +++ b/src/chk.c @@ -159,12 +159,12 @@ __cold static MDBX_chk_line_t *MDBX_PRINTF_ARGS(2, 3) chk_print(MDBX_chk_line_t return line; } -__cold MDBX_MAYBE_UNUSED static void chk_println_va(MDBX_chk_scope_t *const scope, enum MDBX_chk_severity severity, +MDBX_MAYBE_UNUSED __cold static void chk_println_va(MDBX_chk_scope_t *const scope, enum MDBX_chk_severity severity, const char *fmt, va_list args) { chk_line_end(chk_print_va(chk_line_begin(scope, severity), fmt, args)); } -__cold MDBX_MAYBE_UNUSED static void chk_println(MDBX_chk_scope_t *const scope, enum MDBX_chk_severity severity, +MDBX_MAYBE_UNUSED __cold static void chk_println(MDBX_chk_scope_t *const scope, enum MDBX_chk_severity severity, const char *fmt, ...) { va_list args; va_start(args, fmt); diff --git a/src/osal.c b/src/osal.c index d7500142..58f30162 100644 --- a/src/osal.c +++ b/src/osal.c @@ -2856,7 +2856,7 @@ __cold static LSTATUS mdbx_RegGetValue(HKEY hKey, LPCSTR lpSubKey, LPCSTR lpValu } #endif -__cold MDBX_MAYBE_UNUSED static bool bootid_parse_uuid(bin128_t *s, const void *p, const size_t n) { +MDBX_MAYBE_UNUSED __cold static bool bootid_parse_uuid(bin128_t *s, const void *p, const size_t n) { if (n > 31) { unsigned bits = 0; for (unsigned i = 0; i < n; ++i) /* try parse an UUID in text form */ { From 0d7d4db3f16013463b53a8e0117c76c144a7ca2a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=9B=D0=B5=D0=BE=D0=BD=D0=B8=D0=B4=20=D0=AE=D1=80=D1=8C?= =?UTF-8?q?=D0=B5=D0=B2=20=28Leonid=20Yuriev=29?= Date: Fri, 18 Apr 2025 13:00:49 +0300 Subject: [PATCH 30/52] =?UTF-8?q?mdbx:=20=D0=BF=D0=BE=D0=BD=D0=B8=D0=B6?= =?UTF-8?q?=D0=B5=D0=BD=D0=B8=D0=B5=20=D1=83=D1=80=D0=BE=D0=B2=D0=BD=D1=8F?= =?UTF-8?q?=20=D0=BE=D1=82=D0=BB=D0=B0=D0=B4=D0=BE=D1=87=D0=BD=D0=BE=D0=B3?= =?UTF-8?q?=D0=BE=20=D0=BB=D0=BE=D0=B3=D0=B8=D1=80=D0=BE=D0=B2=D0=B0=D0=BD?= =?UTF-8?q?=D0=B8=D1=8F=20lru-reduce.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/dpl.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/dpl.c b/src/dpl.c index 79ea4684..41d35797 100644 --- a/src/dpl.c +++ b/src/dpl.c @@ -395,7 +395,7 @@ __cold bool dpl_check(MDBX_txn *txn) { /*----------------------------------------------------------------------------*/ __noinline void dpl_lru_reduce(MDBX_txn *txn) { - NOTICE("lru-reduce %u -> %u", txn->wr.dirtylru, txn->wr.dirtylru >> 1); + VERBOSE("lru-reduce %u -> %u", txn->wr.dirtylru, txn->wr.dirtylru >> 1); tASSERT(txn, (txn->flags & (MDBX_TXN_RDONLY | MDBX_WRITEMAP)) == 0); do { txn->wr.dirtylru >>= 1; From 6d6a19e3c3f9d2b8b13324ca798b623e6a28b0fc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=9B=D0=B5=D0=BE=D0=BD=D0=B8=D0=B4=20=D0=AE=D1=80=D1=8C?= =?UTF-8?q?=D0=B5=D0=B2=20=28Leonid=20Yuriev=29?= Date: Fri, 18 Apr 2025 13:02:14 +0300 Subject: [PATCH 31/52] =?UTF-8?q?mdbx-tests:=20=D0=B2=D1=8B=D0=B2=D0=BE?= =?UTF-8?q?=D0=B4=20=D0=B8=D0=BD=D1=84=D0=BE=D1=80=D0=BC=D0=B0=D1=86=D0=B8?= =?UTF-8?q?=D0=B8=20=D0=BE=20salt/seed=20=D0=B2=20extra/cursor-closing.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- test/extra/cursor_closing.c++ | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/test/extra/cursor_closing.c++ b/test/extra/cursor_closing.c++ index 2a0184a6..5cfbc09b 100644 --- a/test/extra/cursor_closing.c++ +++ b/test/extra/cursor_closing.c++ @@ -107,6 +107,7 @@ bool case0(mdbx::env env) { * 4. Ждем завершения фоновых потоков. * 5. Закрываем оставшиеся курсоры и закрываем БД. */ +size_t global_seed = size_t(std::chrono::high_resolution_clock::now().time_since_epoch().count()); thread_local size_t salt; static size_t prng() { @@ -284,7 +285,12 @@ void case1_write_cycle(mdbx::txn_managed txn, std::deque &dbi, } bool case1_thread(mdbx::env env, std::deque dbi, mdbx::cursor pre) { - salt = size_t(std::chrono::high_resolution_clock::now().time_since_epoch().count()); + mdbx::error::success_or_throw(mdbx_txn_lock(env, false)); + std::hash hasher; + salt = global_seed ^ hasher(std::this_thread::get_id()); + std::cout << "thread " << std::this_thread::get_id() << ", salt " << salt << std::endl << std::flush; + mdbx_txn_unlock(env); + std::vector pool; for (auto loop = 0; loop < 333 / RELIEF_FACTOR; ++loop) { for (auto read = 0; read < 333 / RELIEF_FACTOR; ++read) { From a71cefc288d9d9286f8bdd5a8bbd7bd37fc448b9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=9B=D0=B5=D0=BE=D0=BD=D0=B8=D0=B4=20=D0=AE=D1=80=D1=8C?= =?UTF-8?q?=D0=B5=D0=B2=20=28Leonid=20Yuriev=29?= Date: Fri, 18 Apr 2025 13:12:52 +0300 Subject: [PATCH 32/52] =?UTF-8?q?mdbx:=20=D0=BF=D1=80=D0=B5=D0=B4=D0=BE?= =?UTF-8?q?=D1=82=D0=B2=D1=80=D0=B0=D1=89=D0=B5=D0=BD=D0=B8=D0=B5=20=D0=B2?= =?UTF-8?q?=D0=BE=D0=B7=D0=B2=D1=80=D0=B0=D1=82=D0=B0=20=D0=BD=D0=B5=D0=BE?= =?UTF-8?q?=D0=B6=D0=B8=D0=B4=D0=B0=D0=BD=D0=BD=D0=BE=D0=B9=20=D0=BE=D1=88?= =?UTF-8?q?=D0=B8=D0=B1=D0=BA=D0=B8=20`MDBX=5FBUSY`=20=D0=B8=D0=B7=20`mdbx?= =?UTF-8?q?=5Ftxn=5Flock(dont=5Fwait=3Dfalse)`.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/api-extra.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/api-extra.c b/src/api-extra.c index 32ad4bfd..9175c9cd 100644 --- a/src/api-extra.c +++ b/src/api-extra.c @@ -140,7 +140,7 @@ int mdbx_txn_lock(MDBX_env *env, bool dont_wait) { if (unlikely(env->flags & MDBX_RDONLY)) return LOG_IFERR(MDBX_EACCESS); - if (unlikely(env->basal_txn->owner || (env->basal_txn->flags & MDBX_TXN_FINISHED) == 0)) + if (dont_wait && unlikely(env->basal_txn->owner || (env->basal_txn->flags & MDBX_TXN_FINISHED) == 0)) return LOG_IFERR(MDBX_BUSY); return LOG_IFERR(lck_txn_lock(env, dont_wait)); From b5503b56702f9c53a516402a0b681474c9d0960f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=9B=D0=B5=D0=BE=D0=BD=D0=B8=D0=B4=20=D0=AE=D1=80=D1=8C?= =?UTF-8?q?=D0=B5=D0=B2=20=28Leonid=20Yuriev=29?= Date: Fri, 18 Apr 2025 13:29:34 +0300 Subject: [PATCH 33/52] =?UTF-8?q?mdbx:=20=D0=B8=D1=81=D0=BF=D1=80=D0=B0?= =?UTF-8?q?=D0=B2=D0=BB=D0=B5=D0=BD=D0=B8=D0=B5=20=D1=84=D0=BE=D1=80=D0=BC?= =?UTF-8?q?=D0=B0=D1=82=D0=B8=D1=80=D0=BE=D0=B2=D0=B0=D0=BD=D0=B8=D1=8F=20?= =?UTF-8?q?(=D0=BA=D0=BE=D1=81=D0=BC=D0=B5=D1=82=D0=B8=D0=BA=D0=B0).?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/txn-nested.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/txn-nested.c b/src/txn-nested.c index dcd89c7a..f5edfb37 100644 --- a/src/txn-nested.c +++ b/src/txn-nested.c @@ -561,9 +561,9 @@ int txn_nested_join(MDBX_txn *txn, struct commit_timestamp *ts) { eASSERT(env, parent->n_dbi == txn->n_dbi); TXN_FOREACH_DBI_ALL(txn, dbi) { if (txn->dbi_state[dbi] != (parent->dbi_state[dbi] & ~(DBI_FRESH | DBI_CREAT | DBI_DIRTY))) { - eASSERT(env, (txn->dbi_state[dbi] & (DBI_CREAT | DBI_FRESH | DBI_DIRTY)) != 0 || - (txn->dbi_state[dbi] | DBI_STALE) == - (parent->dbi_state[dbi] & ~(DBI_FRESH | DBI_CREAT | DBI_DIRTY))); + eASSERT(env, + (txn->dbi_state[dbi] & (DBI_CREAT | DBI_FRESH | DBI_DIRTY)) != 0 || + (txn->dbi_state[dbi] | DBI_STALE) == (parent->dbi_state[dbi] & ~(DBI_FRESH | DBI_CREAT | DBI_DIRTY))); parent->dbs[dbi] = txn->dbs[dbi]; /* preserve parent's status */ const uint8_t state = txn->dbi_state[dbi] | (parent->dbi_state[dbi] & (DBI_CREAT | DBI_FRESH | DBI_DIRTY)); From 270cf399aaad7c30d0f61e4bbad3b46a8490cfa0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=9B=D0=B5=D0=BE=D0=BD=D0=B8=D0=B4=20=D0=AE=D1=80=D1=8C?= =?UTF-8?q?=D0=B5=D0=B2=20=28Leonid=20Yuriev=29?= Date: Sat, 19 Apr 2025 18:12:26 +0300 Subject: [PATCH 34/52] =?UTF-8?q?mdbx:=20=D1=83=D0=BF=D1=80=D0=BE=D1=89?= =?UTF-8?q?=D0=B5=D0=BD=D0=B8=D0=B5=20=D0=BE=D1=87=D0=B8=D1=81=D1=82=D0=BA?= =?UTF-8?q?=D0=B8=20`MDBX=5FTXN=5FHAS=5FCHILD`.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/txn-nested.c | 7 ++----- src/txn.c | 3 +++ 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/txn-nested.c b/src/txn-nested.c index f5edfb37..c6c728f1 100644 --- a/src/txn-nested.c +++ b/src/txn-nested.c @@ -326,7 +326,6 @@ static void txn_merge(MDBX_txn *const parent, MDBX_txn *const txn, const size_t tASSERT(parent, dpl_check(parent)); } - parent->flags &= ~MDBX_TXN_HAS_CHILD; if (parent->wr.spilled.list) { assert(pnl_check_allocated(parent->wr.spilled.list, (size_t)parent->geo.first_unallocated << 1)); if (MDBX_PNL_GETSIZE(parent->wr.spilled.list)) @@ -459,9 +458,6 @@ void txn_nested_abort(MDBX_txn *nested) { parent->wr.retired_pages = nested->wr.retired_pages; } - parent->wr.dirtylru = nested->wr.dirtylru; - parent->nested = nullptr; - parent->flags &= ~MDBX_TXN_HAS_CHILD; tASSERT(parent, dpl_check(parent)); tASSERT(parent, audit_ex(parent, 0, false) == 0); dpl_release_shadows(nested); @@ -581,9 +577,10 @@ int txn_nested_join(MDBX_txn *txn, struct commit_timestamp *ts) { ts->sync = /* no sync */ ts->write; } txn_merge(parent, txn, parent_retired_len); + tASSERT(parent, parent->flags & MDBX_TXN_HAS_CHILD); + parent->flags -= MDBX_TXN_HAS_CHILD; env->txn = parent; parent->nested = nullptr; - parent->flags &= ~MDBX_TXN_HAS_CHILD; tASSERT(parent, dpl_check(parent)); #if MDBX_ENABLE_REFUND diff --git a/src/txn.c b/src/txn.c index 5d553595..321e9a52 100644 --- a/src/txn.c +++ b/src/txn.c @@ -352,7 +352,10 @@ int txn_end(MDBX_txn *txn, unsigned mode) { tASSERT(txn, pnl_check_allocated(txn->wr.repnl, txn->geo.first_unallocated - MDBX_ENABLE_REFUND)); tASSERT(txn, memcmp(&txn->wr.troika, &parent->wr.troika, sizeof(troika_t)) == 0); tASSERT(txn, mode & TXN_END_FREE); + tASSERT(parent, parent->flags & MDBX_TXN_HAS_CHILD); env->txn = parent; + parent->nested = nullptr; + parent->flags -= MDBX_TXN_HAS_CHILD; const pgno_t nested_now = txn->geo.now, nested_upper = txn->geo.upper; txn_nested_abort(txn); From 89de43293dac87dd8dcb118dad7198f6b97c5a15 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=9B=D0=B5=D0=BE=D0=BD=D0=B8=D0=B4=20=D0=AE=D1=80=D1=8C?= =?UTF-8?q?=D0=B5=D0=B2=20=28Leonid=20Yuriev=29?= Date: Sat, 19 Apr 2025 18:25:22 +0300 Subject: [PATCH 35/52] =?UTF-8?q?mdbx:=20=D0=B8=D1=81=D0=BF=D1=80=D0=B0?= =?UTF-8?q?=D0=B2=D0=BB=D0=B5=D0=BD=D0=B8=D0=B5=20=D0=B2=D0=BE=D0=B7=D0=B2?= =?UTF-8?q?=D1=80=D0=B0=D1=82=D0=B0=20`MDBX=5FBAD=5FTXN`=20=D0=B2=D0=BC?= =?UTF-8?q?=D0=B5=D1=81=D1=82=D0=BE=20`MDBX=5FEINVAL`=20=D0=B8=D0=B7=20`md?= =?UTF-8?q?bx=5Fcursor=5Funbind()`=20=D0=B2=20=D0=BE=D1=81=D0=BE=D0=B1?= =?UTF-8?q?=D1=8B=D1=85=20=D1=81=D0=BB=D1=83=D1=87=D0=B0=D1=8F=D1=85.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/api-cursor.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/src/api-cursor.c b/src/api-cursor.c index bb53023d..fb5a2807 100644 --- a/src/api-cursor.c +++ b/src/api-cursor.c @@ -89,8 +89,16 @@ int mdbx_cursor_unbind(MDBX_cursor *mc) { return LOG_IFERR(MDBX_EINVAL); int rc = check_txn(mc->txn, MDBX_TXN_FINISHED | MDBX_TXN_HAS_CHILD); - if (unlikely(rc != MDBX_SUCCESS)) + if (unlikely(rc != MDBX_SUCCESS)) { + for (const MDBX_txn *txn = mc->txn; rc == MDBX_BAD_TXN && check_txn(txn, MDBX_TXN_FINISHED) == MDBX_SUCCESS; + txn = txn->nested) + if (dbi_state(txn, cursor_dbi(mc)) == 0) + /* специальный случай: курсор прикреплён к родительской транзакции, но соответствующий dbi-дескриптор ещё + * не использовался во вложенной транзакции, т.е. курсор ещё не импортирован в дочернюю транзакцию и не имеет + * связанного сохранённого состояния (поэтому mc→backup равен nullptr). */ + rc = MDBX_EINVAL; return LOG_IFERR(rc); + } if (unlikely(!mc->txn || mc->txn->signature != txn_signature)) { ERROR("Wrong cursor's transaction %p 0x%x", __Wpedantic_format_voidptr(mc->txn), mc->txn ? mc->txn->signature : 0); From dc747483dddd0092cf756c6d013cf4b6ff524d27 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=9B=D0=B5=D0=BE=D0=BD=D0=B8=D0=B4=20=D0=AE=D1=80=D1=8C?= =?UTF-8?q?=D0=B5=D0=B2=20=28Leonid=20Yuriev=29?= Date: Sat, 19 Apr 2025 20:02:09 +0300 Subject: [PATCH 36/52] =?UTF-8?q?mdbx-tests:=20=D0=BF=D1=80=D0=B8=D0=B2?= =?UTF-8?q?=D1=8F=D0=B7=D0=BA=D0=B0=20=D0=BA=D0=BE=D0=BB-=D0=B2=D0=B0=20?= =?UTF-8?q?=D0=BF=D0=BE=D1=82=D0=BE=D0=BA=D0=BE=D0=B2/=D0=BF=D1=80=D0=BE?= =?UTF-8?q?=D0=B2=D0=B5=D1=80=D0=BE=D0=BA=20=D0=BA=20=D0=BA=D0=BE=D0=BB-?= =?UTF-8?q?=D0=B2=D1=83=20=D0=BF=D1=80=D0=BE=D1=86=D0=B5=D1=81=D1=81=D0=BE?= =?UTF-8?q?=D1=80=D0=BE=D0=B2=20=D0=B2=20extra/cursor-closing.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- test/extra/cursor_closing.c++ | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/test/extra/cursor_closing.c++ b/test/extra/cursor_closing.c++ index 5cfbc09b..8ea177e4 100644 --- a/test/extra/cursor_closing.c++ +++ b/test/extra/cursor_closing.c++ @@ -318,11 +318,11 @@ bool case1(mdbx::env env) { std::deque dbi; std::vector cursors; #if defined(__cpp_lib_latch) && __cpp_lib_latch >= 201907L - static const auto N = 10; + static const auto N = std::thread::hardware_concurrency(); #else - static const auto N = 3; + static const auto N = 3u; #endif - for (auto t = 0; t < N; ++t) { + for (auto t = 0u; t < N; ++t) { auto txn = env.start_write(); auto table = txn.create_map(std::to_string(t), mdbx::key_mode::ordinal, mdbx::value_mode::multi_samelength); auto cursor = txn.open_cursor(table); @@ -337,7 +337,7 @@ bool case1(mdbx::env env) { #if defined(__cpp_lib_latch) && __cpp_lib_latch >= 201907L std::latch s(1); std::vector threads; - for (auto t = 1; t < N; ++t) { + for (auto t = 1u; t < cursors.size(); ++t) { case1_cycle_dbi(dbi); threads.push_back(std::thread([&, t]() { s.wait(); From 6b5515908b6e70f0fa82557b9db6cff14afeb527 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=9B=D0=B5=D0=BE=D0=BD=D0=B8=D0=B4=20=D0=AE=D1=80=D1=8C?= =?UTF-8?q?=D0=B5=D0=B2=20=28Leonid=20Yuriev=29?= Date: Sat, 19 Apr 2025 23:42:34 +0300 Subject: [PATCH 37/52] =?UTF-8?q?mdbx:=20=D0=BF=D1=80=D0=B5=D0=B4=D0=BE?= =?UTF-8?q?=D1=82=D0=B2=D1=80=D0=B0=D1=89=D0=B5=D0=BD=D0=B8=D0=B5=20=D0=B2?= =?UTF-8?q?=D0=BE=D0=B7=D0=B2=D1=80=D0=B0=D1=82=D0=B0=20=D0=BD=D0=B5=D0=BE?= =?UTF-8?q?=D0=B6=D0=B8=D0=B4=D0=B0=D0=BD=D0=BD=D0=BE=D0=B9=20=D0=BE=D1=88?= =?UTF-8?q?=D0=B8=D0=B1=D0=BA=D0=B8=20`MDBX=5FBUSY`=20=D0=B8=D0=B7=20`mdbx?= =?UTF-8?q?=5Ftxn=5Flock(dont=5Fwait=3Dfalse)`=20(backport).?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/api-extra.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/api-extra.c b/src/api-extra.c index 32ad4bfd..9175c9cd 100644 --- a/src/api-extra.c +++ b/src/api-extra.c @@ -140,7 +140,7 @@ int mdbx_txn_lock(MDBX_env *env, bool dont_wait) { if (unlikely(env->flags & MDBX_RDONLY)) return LOG_IFERR(MDBX_EACCESS); - if (unlikely(env->basal_txn->owner || (env->basal_txn->flags & MDBX_TXN_FINISHED) == 0)) + if (dont_wait && unlikely(env->basal_txn->owner || (env->basal_txn->flags & MDBX_TXN_FINISHED) == 0)) return LOG_IFERR(MDBX_BUSY); return LOG_IFERR(lck_txn_lock(env, dont_wait)); From 76a588f91b01e38abed26f3feba9a358ee8be8bc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=9B=D0=B5=D0=BE=D0=BD=D0=B8=D0=B4=20=D0=AE=D1=80=D1=8C?= =?UTF-8?q?=D0=B5=D0=B2=20=28Leonid=20Yuriev=29?= Date: Sat, 19 Apr 2025 23:42:59 +0300 Subject: [PATCH 38/52] =?UTF-8?q?mdbx:=20=D0=B8=D1=81=D0=BF=D1=80=D0=B0?= =?UTF-8?q?=D0=B2=D0=BB=D0=B5=D0=BD=D0=B8=D0=B5=20=D0=B2=D0=BE=D0=B7=D0=B2?= =?UTF-8?q?=D1=80=D0=B0=D1=82=D0=B0=20`MDBX=5FBAD=5FTXN`=20=D0=B2=D0=BC?= =?UTF-8?q?=D0=B5=D1=81=D1=82=D0=BE=20`MDBX=5FEINVAL`=20=D0=B8=D0=B7=20`md?= =?UTF-8?q?bx=5Fcursor=5Funbind()`=20=D0=B2=20=D0=BE=D1=81=D0=BE=D0=B1?= =?UTF-8?q?=D1=8B=D1=85=20=D1=81=D0=BB=D1=83=D1=87=D0=B0=D1=8F=D1=85=20(ba?= =?UTF-8?q?ckport).?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/api-cursor.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/src/api-cursor.c b/src/api-cursor.c index da68afb6..9e902ee5 100644 --- a/src/api-cursor.c +++ b/src/api-cursor.c @@ -88,8 +88,16 @@ int mdbx_cursor_unbind(MDBX_cursor *mc) { return LOG_IFERR(MDBX_EINVAL); int rc = check_txn(mc->txn, MDBX_TXN_FINISHED | MDBX_TXN_HAS_CHILD); - if (unlikely(rc != MDBX_SUCCESS)) + if (unlikely(rc != MDBX_SUCCESS)) { + for (const MDBX_txn *txn = mc->txn; rc == MDBX_BAD_TXN && check_txn(txn, MDBX_TXN_FINISHED) == MDBX_SUCCESS; + txn = txn->nested) + if (dbi_state(txn, cursor_dbi(mc)) == 0) + /* специальный случай: курсор прикреплён к родительской транзакции, но соответствующий dbi-дескриптор ещё + * не использовался во вложенной транзакции, т.е. курсор ещё не импортирован в дочернюю транзакцию и не имеет + * связанного сохранённого состояния (поэтому mc→backup равен nullptr). */ + rc = MDBX_EINVAL; return LOG_IFERR(rc); + } if (unlikely(!mc->txn || mc->txn->signature != txn_signature)) { ERROR("Wrong cursor's transaction %p 0x%x", __Wpedantic_format_voidptr(mc->txn), mc->txn ? mc->txn->signature : 0); From 679c1eb939121b60d861058ab976e85e9acba046 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=9B=D0=B5=D0=BE=D0=BD=D0=B8=D0=B4=20=D0=AE=D1=80=D1=8C?= =?UTF-8?q?=D0=B5=D0=B2=20=28Leonid=20Yuriev=29?= Date: Sat, 19 Apr 2025 23:43:43 +0300 Subject: [PATCH 39/52] =?UTF-8?q?mdbx-tests:=20=D0=BE=D0=B1=D0=BD=D1=83?= =?UTF-8?q?=D0=BB=D0=B5=D0=BD=D0=B8=D0=B5=20pid=20=D0=BD=D0=B0=20=D0=B2?= =?UTF-8?q?=D1=85=D0=BE=D0=B4=D0=B5=20=D0=B2=20`osal=5Factor=5Fpoll()`=20(?= =?UTF-8?q?backport).?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- test/osal-unix.c++ | 1 + 1 file changed, 1 insertion(+) diff --git a/test/osal-unix.c++ b/test/osal-unix.c++ index b7233d03..dd58b827 100644 --- a/test/osal-unix.c++ +++ b/test/osal-unix.c++ @@ -510,6 +510,7 @@ int osal_actor_poll(mdbx_pid_t &pid, unsigned timeout) { options |= WCONTINUED; #endif + pid = 0; while (sigalarm_tail == sigalarm_head) { int status; pid = waitpid(0, &status, options); From 5548ef20f6379b5259856259b618aea99c3f4efb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=9B=D0=B5=D0=BE=D0=BD=D0=B8=D0=B4=20=D0=AE=D1=80=D1=8C?= =?UTF-8?q?=D0=B5=D0=B2=20=28Leonid=20Yuriev=29?= Date: Sat, 19 Apr 2025 23:44:07 +0300 Subject: [PATCH 40/52] =?UTF-8?q?mdbx:=20=D0=BF=D0=B5=D1=80=D0=B5=D1=83?= =?UTF-8?q?=D0=BF=D0=BE=D1=80=D1=8F=D0=B4=D0=BE=D1=87=D0=B8=D0=B2=D0=B0?= =?UTF-8?q?=D0=BD=D0=B8=D0=B5=20=D0=B0=D1=82=D1=80=D0=B8=D0=B1=D1=83=D1=82?= =?UTF-8?q?=D0=BE=D0=B2=20=D0=B4=D0=BB=D1=8F=20=D1=81=D0=BE=D0=B2=D0=BC?= =?UTF-8?q?=D0=B5=D1=81=D1=82=D0=B8=D0=BC=D0=BE=D1=81=D1=82=D0=B8=20=D1=81?= =?UTF-8?q?=20GCC-15=20=D0=B2=20=D1=80=D0=B5=D0=B6=D0=B8=D0=BC=D0=B5=20C23?= =?UTF-8?q?=20(backport).?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/osal.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/osal.c b/src/osal.c index 0ba44b61..66ea39b6 100644 --- a/src/osal.c +++ b/src/osal.c @@ -2856,7 +2856,7 @@ __cold static LSTATUS mdbx_RegGetValue(HKEY hKey, LPCSTR lpSubKey, LPCSTR lpValu } #endif -__cold MDBX_MAYBE_UNUSED static bool bootid_parse_uuid(bin128_t *s, const void *p, const size_t n) { +MDBX_MAYBE_UNUSED __cold static bool bootid_parse_uuid(bin128_t *s, const void *p, const size_t n) { if (n > 31) { unsigned bits = 0; for (unsigned i = 0; i < n; ++i) /* try parse an UUID in text form */ { From 668a1e42e3f47750c2f3963919c5e070a7167aa9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=9B=D0=B5=D0=BE=D0=BD=D0=B8=D0=B4=20=D0=AE=D1=80=D1=8C?= =?UTF-8?q?=D0=B5=D0=B2=20=28Leonid=20Yuriev=29?= Date: Sat, 19 Apr 2025 23:52:19 +0300 Subject: [PATCH 41/52] =?UTF-8?q?mdbx:=20=D0=B4=D0=BE=D0=BF=D0=BE=D0=BB?= =?UTF-8?q?=D0=BD=D0=B5=D0=BD=D0=B8=D0=B5=20ChangeLog.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ChangeLog.md | 43 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 43 insertions(+) diff --git a/ChangeLog.md b/ChangeLog.md index a4911bfb..1d1fa6df 100644 --- a/ChangeLog.md +++ b/ChangeLog.md @@ -17,6 +17,8 @@ and [by Yandex](https://translated.turbopages.org/proxy_u/ru-en.en/https/libmdbx - [Виктору Логунову](https://t.me/vl_username) за сообщение об опечатки в имени переменной в Conan-рецепте. - [Илье Михееву](https://t.me/IlyaMkhv) за сообщение о лишнем/ненужном предупреждении несоответствия файла БД новому размеру. - [maxc0d3r](https://gitflic.ru/user/maxc0d3r) for bug reporting and testing. + - [Алексею Костюку (aka Keller)](https://t.me/keller18306) за сообщения о проблеме копирования на NFS. + Новое: @@ -75,8 +77,13 @@ and [by Yandex](https://translated.turbopages.org/proxy_u/ru-en.en/https/libmdbx - В C++ API отменён вброс исключения при запросе транзакции у отсоединённого курсора посредством вывоза `mdbx::cursor::txn()`. + - При невозможности отвязки курсора от его текущей транзакции функция `mdbx_cursor_bind()` + теперь возвращает `MDBX_EINVAL` вместо `MDBX_BAD_TXN`. + Исправления: + - Для совместимости с GCC 15.x в режиме C23 изменен порядок указания атрибутов функций. + - Устранён регресс допускающий SIGSEGV в операциях обновления после вытеснения/spilling страниц в больших транзакциях. Ошибка присутствует в выпусках v0.13.1, v0.13.2, v0.13.3 и оставалась незамеченной из-за специфических условий и низкой вероятности проявления. Более подробная информация в описании коммита `cb8eec6d11cdab4f7d3cf87913e8009149dcf60b`. @@ -130,6 +137,38 @@ and [by Yandex](https://translated.turbopages.org/proxy_u/ru-en.en/https/libmdbx - В C++ API добавлена упущенная проверка `__cpp_concepts >= 202002` для использования концептов C++. + - Устранён регресс при использовании курсоров для DBI=0 в читающих транзакциях. + + В результате рефакторинга и ряда оптимизаций для завершения/гашения + курсоров в читающих и пишущих транзакций стал использоваться общий код. + Причем за основу, был взят соответствующий фрагмент относящийся к + пишущим транзакциям, в которых пользователю не позволяется + использоваться курсоры для DBI=0 и поэтому эта итераций пропускалась. + + В результате, при завершении читающих транзакциях, курсоры связанные с + DBI=0 не завершались должным образом, а при их повторном использовании + или явном закрытии после завершения читающей транзакции происходило + обращение к уже освобожденной памяти. Если же такие курсоры + отсоединялись или закрывались до завершения читающей транзакции, то + ошибка не имела шансов на проявление. + + - Устранён регресс в виде ошибки `EAGAIN` при копировании БД на NFS и CIFS/SMB. + + При доработках/развитии API в функции копирования был добавлен захват + файловой блокировки посредством как `fcntl()`, так и `flock()`. Однако, + в зависимости от версии локального ядра, версии удалённого сервера NFS и + опций монтирования, это могло приводить к возврату POSIX-ошибки `EAGAIN` + (`11` на большинстве платформ, включая Linux). + + - Устранена ошибка merge/rebase внутри `mdbx_txn_release_all_cursors_ex()`, + что могло приводить к последующим неожиданным ошибкам `MDBX_EBADSIGN` и утечкам памяти. + Для проверки сценария дополнен соответствующий тест. + + - Исправлена assert-проверка в пути завершения вложенных транзакций. + Для проверки сценария дополнен соответствующий тест. + + - Устранена возможность возврата неожиданной ошибки `MDBX_BUSY` из `mdbx_txn_lock(dont_wait=false)`. + Прочие доработки: - Существенный рефакторинг с реструктуризацией кода, переименованием внутренних структур, их полей и внутренних функций. @@ -155,6 +194,10 @@ and [by Yandex](https://translated.turbopages.org/proxy_u/ru-en.en/https/libmdbx - Отключено использование C23 `[[атрибутов]]` для версий CLANG меньше 20. + - Во избежание потенциальных проблем отключено использование `copy_file_range()` на ядрах Linux 5.3 - 5.18. + + - Вброс `std::invalid_argument` теперь производится явным сообщением `MDBX_EINVAL`. + -------------------------------------------------------------------------------- From ab2f661c9768ce4b831ada99f7c43d6ede33e062 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=9B=D0=B5=D0=BE=D0=BD=D0=B8=D0=B4=20=D0=AE=D1=80=D1=8C?= =?UTF-8?q?=D0=B5=D0=B2=20=28Leonid=20Yuriev=29?= Date: Sun, 20 Apr 2025 00:01:59 +0300 Subject: [PATCH 42/52] =?UTF-8?q?mdbx:=20=D0=B4=D0=BE=D0=BF=D0=BE=D0=BB?= =?UTF-8?q?=D0=BD=D0=B5=D0=BD=D0=B8=D0=B5=20ChangeLog.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ChangeLog.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/ChangeLog.md b/ChangeLog.md index 0d8ffe43..92cb3916 100644 --- a/ChangeLog.md +++ b/ChangeLog.md @@ -46,6 +46,10 @@ and [by Yandex](https://translated.turbopages.org/proxy_u/ru-en.en/https/libmdbx - Исправлена assert-проверка в пути завершения вложенных транзакций. Для проверки сценария дополнен соответствующий тест. + - Устранена возможность возврата неожиданной ошибки `MDBX_BUSY` из `mdbx_txn_lock(dont_wait=false)`. + + - Для совместимости с GCC 15.x в режиме C23 изменен порядок указания атрибутов функций. + Изменение поведения: - При невозможности отвязки курсора от его текущей транзакции функция `mdbx_cursor_bind()` From 072103ab67f6e789a9616c9f1dc3af1c2bf68ef1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=9B=D0=B5=D0=BE=D0=BD=D0=B8=D0=B4=20=D0=AE=D1=80=D1=8C?= =?UTF-8?q?=D0=B5=D0=B2=20=28Leonid=20Yuriev=29?= Date: Sun, 20 Apr 2025 00:45:16 +0300 Subject: [PATCH 43/52] =?UTF-8?q?mdbx-tests:=20=D0=B8=D1=81=D0=BF=D1=80?= =?UTF-8?q?=D0=B0=D0=B2=D0=BB=D0=B5=D0=BD=D0=B8=D0=B5=20extra/cursor-closi?= =?UTF-8?q?ng=20=D0=B4=D0=BB=D1=8F=20=D1=81=D1=82=D0=B0=D1=80=D1=8B=D1=85?= =?UTF-8?q?=20=D1=81=D1=82=D0=B0=D0=BD=D0=B4=D0=B0=D1=80=D1=82=D0=BE=D0=B2?= =?UTF-8?q?=20C++.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- test/extra/cursor_closing.c++ | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/test/extra/cursor_closing.c++ b/test/extra/cursor_closing.c++ index 8ea177e4..df8278ce 100644 --- a/test/extra/cursor_closing.c++ +++ b/test/extra/cursor_closing.c++ @@ -285,11 +285,15 @@ void case1_write_cycle(mdbx::txn_managed txn, std::deque &dbi, } bool case1_thread(mdbx::env env, std::deque dbi, mdbx::cursor pre) { +#if defined(__cpp_lib_latch) && __cpp_lib_latch >= 201907L mdbx::error::success_or_throw(mdbx_txn_lock(env, false)); std::hash hasher; salt = global_seed ^ hasher(std::this_thread::get_id()); std::cout << "thread " << std::this_thread::get_id() << ", salt " << salt << std::endl << std::flush; mdbx_txn_unlock(env); +#else + salt = global_seed; +#endif std::vector pool; for (auto loop = 0; loop < 333 / RELIEF_FACTOR; ++loop) { From 576fc94fef0ddb750b3f207fcd240ec700290856 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=9B=D0=B5=D0=BE=D0=BD=D0=B8=D0=B4=20=D0=AE=D1=80=D1=8C?= =?UTF-8?q?=D0=B5=D0=B2=20=28Leonid=20Yuriev=29?= Date: Sun, 20 Apr 2025 22:48:23 +0300 Subject: [PATCH 44/52] =?UTF-8?q?mdbx:=20=D0=B8=D1=81=D0=BF=D1=80=D0=B0?= =?UTF-8?q?=D0=B2=D0=BB=D0=B5=D0=BD=D0=B8=D0=B5=20=D0=BE=D0=BF=D0=B5=D1=87?= =?UTF-8?q?=D0=B0=D1=82=D0=BA=D0=B8=20=D0=B2=20=D0=BB=D0=BE=D0=B3=D0=B8?= =?UTF-8?q?=D1=80=D0=BE=D0=B2=D0=B0=D0=BD=D0=B8=D0=B8=20(=D0=BA=D0=BE?= =?UTF-8?q?=D1=81=D0=BC=D0=B5=D1=82=D0=B8=D0=BA=D0=B0).?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/dxb.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/dxb.c b/src/dxb.c index 37ddcaa7..e18e28d0 100644 --- a/src/dxb.c +++ b/src/dxb.c @@ -1157,7 +1157,7 @@ int dxb_sync_locked(MDBX_env *env, unsigned flags, meta_t *const pending, troika if (!head.is_steady && meta_is_steady(pending)) target = (meta_t *)head.ptr_c; else { - NOTICE("skip update meta%" PRIaPGNO " for txn#%" PRIaTXN "since it is already steady", + NOTICE("skip update meta%" PRIaPGNO " for txn#%" PRIaTXN ", since it is already steady", data_page(head.ptr_c)->pgno, head.txnid); return MDBX_SUCCESS; } From b6f918aa1c230f622647b271798b70d3850a7cac Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=9B=D0=B5=D0=BE=D0=BD=D0=B8=D0=B4=20=D0=AE=D1=80=D1=8C?= =?UTF-8?q?=D0=B5=D0=B2=20=28Leonid=20Yuriev=29?= Date: Tue, 22 Apr 2025 11:17:39 +0300 Subject: [PATCH 45/52] =?UTF-8?q?mdbx:=20=D0=B8=D1=81=D0=BF=D1=80=D0=B0?= =?UTF-8?q?=D0=B2=D0=BB=D0=B5=D0=BD=D0=B8=D0=B5=20=D0=BE=D0=BF=D0=B5=D1=87?= =?UTF-8?q?=D0=B0=D1=82=D0=BA=D0=B8=20=D0=B2=20=D0=BB=D0=BE=D0=B3=D0=B8?= =?UTF-8?q?=D1=80=D0=BE=D0=B2=D0=B0=D0=BD=D0=B8=D0=B8=20(backport).?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/dxb.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/dxb.c b/src/dxb.c index b6a353ce..200b19e2 100644 --- a/src/dxb.c +++ b/src/dxb.c @@ -1157,7 +1157,7 @@ int dxb_sync_locked(MDBX_env *env, unsigned flags, meta_t *const pending, troika if (!head.is_steady && meta_is_steady(pending)) target = (meta_t *)head.ptr_c; else { - NOTICE("skip update meta%" PRIaPGNO " for txn#%" PRIaTXN "since it is already steady", + NOTICE("skip update meta%" PRIaPGNO " for txn#%" PRIaTXN ", since it is already steady", data_page(head.ptr_c)->pgno, head.txnid); return MDBX_SUCCESS; } From a971c76afffbb2ce0aa6151f4683b94fe10dc843 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=9B=D0=B5=D0=BE=D0=BD=D0=B8=D0=B4=20=D0=AE=D1=80=D1=8C?= =?UTF-8?q?=D0=B5=D0=B2=20=28Leonid=20Yuriev=29?= Date: Tue, 22 Apr 2025 11:53:23 +0300 Subject: [PATCH 46/52] =?UTF-8?q?v0.13.6=20"=D0=91=D1=83=D0=B7=D0=B8=D0=BD?= =?UTF-8?q?=D0=B0".?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Поддерживающий выпуск стабильной ветки с исправлением обнаруженных ошибок и устранением недочётов, в память о погибшем украинском историке и писателе [Алесе Бузине](https://ru.ruwiki.ru/wiki/Бузина,_Олесь_Алексеевич). За перечнем доработок и изменений обращайтесь к [ChangeLog](https://libmdbx.dqdkfa.ru/md__change_log.html). git diff' stat: 15 files changed, 194 insertions(+), 36 deletions(-). Signed-off-by: Леонид Юрьев (Leonid Yuriev) --- ChangeLog.md | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/ChangeLog.md b/ChangeLog.md index 92cb3916..6fe74e2a 100644 --- a/ChangeLog.md +++ b/ChangeLog.md @@ -4,9 +4,10 @@ ChangeLog English version [by liar Google](https://libmdbx-dqdkfa-ru.translate.goog/md__change_log.html?_x_tr_sl=ru&_x_tr_tl=en) and [by Yandex](https://translated.turbopages.org/proxy_u/ru-en.en/https/libmdbx.dqdkfa.ru/md__change_log.html). -## v0.13.6 в процессе накопления изменений, выпуск запланирован на вторую половину апреля. +## v0.13.6 "Бузина" от 2025-04-22. -Поддерживающий выпуск стабильной ветки с исправлением обнаруженных ошибок и устранением недочётов. +Поддерживающий выпуск стабильной ветки с исправлением обнаруженных ошибок и устранением недочётов, +в память о погибшем украинском историке и писателе [Алесе Бузине](https://ru.ruwiki.ru/wiki/Бузина,_Олесь_Алексеевич). Благодарности: @@ -16,10 +17,10 @@ and [by Yandex](https://translated.turbopages.org/proxy_u/ru-en.en/https/libmdbx Исправления: - - Устранён регресс при использовании курсоров для DBI=0 в читающих транзакциях. + - Устранён регресс при использовании курсоров для DBI=0 (aka GC/FreeDB) в читающих транзакциях. В результате рефакторинга и ряда оптимизаций для завершения/гашения - курсоров в читающих и пишущих транзакций стал использоваться общий код. + курсоров в читающих и пишущих транзакций, стал использоваться общий код. Причем за основу, был взят соответствующий фрагмент относящийся к пишущим транзакциям, в которых пользователю не позволяется использоваться курсоры для DBI=0 и поэтому эта итераций пропускалась. From f4384800b5c1e934032fbe836dd48f5db8db4d01 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=9B=D0=B5=D0=BE=D0=BD=D0=B8=D0=B4=20=D0=AE=D1=80=D1=8C?= =?UTF-8?q?=D0=B5=D0=B2=20=28Leonid=20Yuriev=29?= Date: Tue, 22 Apr 2025 13:10:30 +0300 Subject: [PATCH 47/52] =?UTF-8?q?mdbx:=20=D0=BE=D0=B1=D0=BD=D0=BE=D0=B2?= =?UTF-8?q?=D0=BB=D0=B5=D0=BD=D0=B8=D0=B5=20ChangeLog.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ChangeLog.md | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/ChangeLog.md b/ChangeLog.md index 6fe74e2a..87da4b98 100644 --- a/ChangeLog.md +++ b/ChangeLog.md @@ -4,6 +4,14 @@ ChangeLog English version [by liar Google](https://libmdbx-dqdkfa-ru.translate.goog/md__change_log.html?_x_tr_sl=ru&_x_tr_tl=en) and [by Yandex](https://translated.turbopages.org/proxy_u/ru-en.en/https/libmdbx.dqdkfa.ru/md__change_log.html). +## v0.13.7 в процессе накопления изменений, выпуск запланирован на конец мая. + +Поддерживающий выпуск стабильной ветки с исправлением обнаруженных ошибок и устранением недочётов. + + +-------------------------------------------------------------------------------- + + ## v0.13.6 "Бузина" от 2025-04-22. Поддерживающий выпуск стабильной ветки с исправлением обнаруженных ошибок и устранением недочётов, @@ -19,7 +27,7 @@ and [by Yandex](https://translated.turbopages.org/proxy_u/ru-en.en/https/libmdbx - Устранён регресс при использовании курсоров для DBI=0 (aka GC/FreeDB) в читающих транзакциях. - В результате рефакторинга и ряда оптимизаций для завершения/гашения + После рефакторинга и ряда оптимизаций для завершения/гашения курсоров в читающих и пишущих транзакций, стал использоваться общий код. Причем за основу, был взят соответствующий фрагмент относящийся к пишущим транзакциям, в которых пользователю не позволяется From 5c44dd201caf759f1e6576868a17f39086f0ca83 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=9B=D0=B5=D0=BE=D0=BD=D0=B8=D0=B4=20=D0=AE=D1=80=D1=8C?= =?UTF-8?q?=D0=B5=D0=B2=20=28Leonid=20Yuriev=29?= Date: Tue, 22 Apr 2025 14:43:37 +0300 Subject: [PATCH 48/52] =?UTF-8?q?mdbx:=20=D0=BE=D0=B1=D0=BD=D0=BE=D0=B2?= =?UTF-8?q?=D0=BB=D0=B5=D0=BD=D0=B8=D0=B5=20=D0=BF=D0=B0=D1=82=D1=87=D0=B0?= =?UTF-8?q?=20=D0=B4=D0=BB=D1=8F=20=D1=81=D1=82=D0=B0=D1=80=D1=8B=D1=85=20?= =?UTF-8?q?=D0=B2=D0=B5=D1=80=D1=81=D0=B8=D0=B9=20buildroot.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...-libmdbx-new-package-library-database.patch | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/packages/buildroot/0001-package-libmdbx-new-package-library-database.patch b/packages/buildroot/0001-package-libmdbx-new-package-library-database.patch index 2ccb2846..65aab19e 100644 --- a/packages/buildroot/0001-package-libmdbx-new-package-library-database.patch +++ b/packages/buildroot/0001-package-libmdbx-new-package-library-database.patch @@ -1,7 +1,7 @@ -From 49256dcd050fd0ee67860b7bc544dabe088d08e9 Mon Sep 17 00:00:00 2001 +From 349c08cf21b66ecea851340133a1b845c25675f7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=9B=D0=B5=D0=BE=D0=BD=D0=B8=D0=B4=20=D0=AE=D1=80=D1=8C?= =?UTF-8?q?=D0=B5=D0=B2=20=28Leonid=20Yuriev=29?= -Date: Fri, 14 Feb 2025 21:34:25 +0300 +Date: Tue, 22 Apr 2025 14:38:49 +0300 Subject: [PATCH] package/libmdbx: new package (library/database). MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 @@ -15,7 +15,7 @@ This patch adds libmdbx: in terms of reliability, features and performance. - more information at https://libmdbx.dqdkfa.ru -The 0.13.4 "Sigma Boy" is stable release of _libmdbx_ branch with new superior features. +The 0.13.6 "Бузина" (Elderberry) is stable release of _libmdbx_ branch with new superior features. The complete ChangeLog: https://gitflic.ru/project/erthink/libmdbx/blob?file=ChangeLog.md @@ -110,19 +110,19 @@ index 0000000000..a9a4ac45c5 + !BR2_TOOLCHAIN_GCC_AT_LEAST_4_4 diff --git a/package/libmdbx/libmdbx.hash b/package/libmdbx/libmdbx.hash new file mode 100644 -index 0000000000..202937e7be +index 0000000000..ae5266716b --- /dev/null +++ b/package/libmdbx/libmdbx.hash @@ -0,0 +1,6 @@ +# Hashes from: https://libmdbx.dqdkfa.ru/release/SHA256SUMS -+sha256 86df30ca2231c9b3ad71424bb829dca9041947f5539d4295030c653d4982c1be libmdbx-amalgamated-0.13.4.tar.xz ++sha256 57db987de6f7ccc66a66ae28a7bda9f9fbb48ac5fb9279bcca92fd5de13075d1 libmdbx-amalgamated-0.13.6.tar.xz + +# Locally calculated +sha256 0d542e0c8804e39aa7f37eb00da5a762149dc682d7829451287e11b938e94594 LICENSE -+sha256 699a62986b6c8d31124646dffd4b15872c7d3bc5eecea5994edb1f5195df49d1 NOTICE ++sha256 651f71b46c6bb0046d2122df7f9def9cb24f4dc28c5b11cef059f66565cda30f NOTICE diff --git a/package/libmdbx/libmdbx.mk b/package/libmdbx/libmdbx.mk new file mode 100644 -index 0000000000..a8a6f3dbdf +index 0000000000..571757262e --- /dev/null +++ b/package/libmdbx/libmdbx.mk @@ -0,0 +1,42 @@ @@ -132,7 +132,7 @@ index 0000000000..a8a6f3dbdf +# +################################################################################ + -+LIBMDBX_VERSION = 0.13.4 ++LIBMDBX_VERSION = 0.13.6 +LIBMDBX_SOURCE = libmdbx-amalgamated-$(LIBMDBX_VERSION).tar.xz +LIBMDBX_SITE = https://libmdbx.dqdkfa.ru/release +LIBMDBX_SUPPORTS_IN_SOURCE_BUILD = NO @@ -169,5 +169,5 @@ index 0000000000..a8a6f3dbdf + +$(eval $(cmake-package)) -- -2.48.1 +2.49.0 From 7db9c40fe04290bb8b8c4dc10050ccfe3142dc9b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=9B=D0=B5=D0=BE=D0=BD=D0=B8=D0=B4=20=D0=AE=D1=80=D1=8C?= =?UTF-8?q?=D0=B5=D0=B2=20=28Leonid=20Yuriev=29?= Date: Wed, 23 Apr 2025 23:00:27 +0300 Subject: [PATCH 49/52] =?UTF-8?q?mdbx-tests:=20=D1=83=D1=81=D1=82=D0=B0?= =?UTF-8?q?=D0=BD=D0=BE=D0=B2=D0=BA=D0=B0=20max-dbi=20=D0=B4=D0=BB=D1=8F?= =?UTF-8?q?=20extra/cursor-closing.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- test/extra/cursor_closing.c++ | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/test/extra/cursor_closing.c++ b/test/extra/cursor_closing.c++ index df8278ce..fe234d7a 100644 --- a/test/extra/cursor_closing.c++ +++ b/test/extra/cursor_closing.c++ @@ -23,7 +23,13 @@ #define RELIEF_FACTOR 1 #endif -#define NN (1000 / RELIEF_FACTOR) +static const auto NN = 1000u / RELIEF_FACTOR; + +#if defined(__cpp_lib_latch) && __cpp_lib_latch >= 201907L +static const auto N = std::min(17u, std::thread::hardware_concurrency()); +#else +static const auto N = 3u; +#endif static void logger_nofmt(MDBX_log_level_t loglevel, const char *function, int line, const char *msg, unsigned length) noexcept { @@ -263,7 +269,7 @@ void case1_write_cycle(mdbx::txn_managed txn, std::deque &dbi, pre.unbind(); if (!pre.txn()) pre.bind(txn, dbi[prng(dbi.size())]); - for (auto i = 0; i < NN; ++i) { + for (auto i = 0u; i < NN; ++i) { auto k = mdbx::default_buffer::wrap(prng(NN)); auto v = mdbx::default_buffer::wrap(prng(NN)); if (pre.find_multivalue(k, v, false)) @@ -321,11 +327,6 @@ bool case1(mdbx::env env) { bool ok = true; std::deque dbi; std::vector cursors; -#if defined(__cpp_lib_latch) && __cpp_lib_latch >= 201907L - static const auto N = std::thread::hardware_concurrency(); -#else - static const auto N = 3u; -#endif for (auto t = 0u; t < N; ++t) { auto txn = env.start_write(); auto table = txn.create_map(std::to_string(t), mdbx::key_mode::ordinal, mdbx::value_mode::multi_samelength); @@ -392,7 +393,7 @@ int doit() { mdbx::env::remove(db_filename); mdbx::env_managed env(db_filename, mdbx::env_managed::create_parameters(), - mdbx::env::operate_parameters(42, 0, mdbx::env::nested_transactions)); + mdbx::env::operate_parameters(N + 2, 0, mdbx::env::nested_transactions)); bool ok = case0(env); ok = case1(env) && ok; From 6627d14edf1eddb4da1765f1c5c503003ce01d77 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=9B=D0=B5=D0=BE=D0=BD=D0=B8=D0=B4=20=D0=AE=D1=80=D1=8C?= =?UTF-8?q?=D0=B5=D0=B2=20=28Leonid=20Yuriev=29?= Date: Wed, 23 Apr 2025 23:26:57 +0300 Subject: [PATCH 50/52] =?UTF-8?q?mdbx:=20=D1=83=D0=BF=D1=80=D0=BE=D1=89?= =?UTF-8?q?=D0=B5=D0=BD=D0=B8=D0=B5=20=D1=81=D1=82=D0=B0=D1=80=D1=82=D0=B0?= =?UTF-8?q?=20=D1=82=D1=80=D0=B0=D0=BD=D0=B7=D0=B0=D0=BA=D1=86=D0=B8=D0=B9?= =?UTF-8?q?=20=D0=B8=20=D0=B8=D1=81=D0=BF=D1=80=D0=B0=D0=B2=D0=BB=D0=B5?= =?UTF-8?q?=D0=BD=D0=B8=D0=B5=20=D0=B2=D0=BE=D0=B7=D0=BC=D0=BE=D0=B6=D0=BD?= =?UTF-8?q?=D0=BE=D1=81=D1=82=D0=B8=20double-free=20=D0=BF=D1=80=D0=B8=20?= =?UTF-8?q?=D0=BE=D1=88=D0=B8=D0=B1=D0=BA=D0=B5=20=D1=81=D0=BE=D0=B7=D0=B4?= =?UTF-8?q?=D0=B0=D0=BD=D0=B8=D1=8F=20=D0=B2=D0=BB=D0=BE=D0=B6=D0=B5=D0=BD?= =?UTF-8?q?=D0=BD=D0=BE=D0=B9=20=D1=82=D1=80=D0=B0=D0=BD=D0=B7=D0=B0=D0=BA?= =?UTF-8?q?=D1=86=D0=B8=D0=B8.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/api-txn.c | 51 ++++++++++++++++++++++++------------------------ src/txn-nested.c | 47 ++++++++++++++++++++------------------------ 2 files changed, 47 insertions(+), 51 deletions(-) diff --git a/src/api-txn.c b/src/api-txn.c index 04feabea..847d8f9e 100644 --- a/src/api-txn.c +++ b/src/api-txn.c @@ -235,9 +235,11 @@ int mdbx_txn_begin_ex(MDBX_env *env, MDBX_txn *parent, MDBX_txn_flags_t flags, M flags |= parent->flags & (txn_rw_begin_flags | MDBX_TXN_SPILLS | MDBX_NOSTICKYTHREADS | MDBX_WRITEMAP); rc = txn_nested_create(parent, flags); txn = parent->nested; - if (unlikely(rc != MDBX_SUCCESS)) - txn_end(txn, TXN_END_FAIL_BEGIN_NESTED); - else if (AUDIT_ENABLED() && ASSERT_ENABLED()) { + if (unlikely(rc != MDBX_SUCCESS)) { + int err = txn_end(txn, TXN_END_FAIL_BEGIN_NESTED); + return err ? err : rc; + } + if (AUDIT_ENABLED() && ASSERT_ENABLED()) { txn->signature = txn_signature; tASSERT(txn, audit_ex(txn, 0, false) == 0); } @@ -249,31 +251,30 @@ int mdbx_txn_begin_ex(MDBX_env *env, MDBX_txn *parent, MDBX_txn_flags_t flags, M return LOG_IFERR(MDBX_ENOMEM); } rc = txn_renew(txn, flags); - } - - if (unlikely(rc != MDBX_SUCCESS)) { - if (txn != env->basal_txn) - osal_free(txn); - } else { - if (flags & (MDBX_TXN_RDONLY_PREPARE - MDBX_TXN_RDONLY)) - eASSERT(env, txn->flags == (MDBX_TXN_RDONLY | MDBX_TXN_FINISHED)); - else if (flags & MDBX_TXN_RDONLY) - eASSERT(env, (txn->flags & ~(MDBX_NOSTICKYTHREADS | MDBX_TXN_RDONLY | MDBX_WRITEMAP | - /* Win32: SRWL flag */ txn_shrink_allowed)) == 0); - else { - eASSERT(env, (txn->flags & ~(MDBX_NOSTICKYTHREADS | MDBX_WRITEMAP | txn_shrink_allowed | txn_may_have_cursors | - MDBX_NOMETASYNC | MDBX_SAFE_NOSYNC | MDBX_TXN_SPILLS)) == 0); - assert(!txn->wr.spilled.list && !txn->wr.spilled.least_removed); + if (unlikely(rc != MDBX_SUCCESS)) { + if (txn != env->basal_txn) + osal_free(txn); + return LOG_IFERR(rc); } - txn->signature = txn_signature; - txn->userctx = context; - *ret = txn; - DEBUG("begin txn %" PRIaTXN "%c %p on env %p, root page %" PRIaPGNO "/%" PRIaPGNO, txn->txnid, - (flags & MDBX_TXN_RDONLY) ? 'r' : 'w', (void *)txn, (void *)env, txn->dbs[MAIN_DBI].root, - txn->dbs[FREE_DBI].root); } - return LOG_IFERR(rc); + if (flags & (MDBX_TXN_RDONLY_PREPARE - MDBX_TXN_RDONLY)) + eASSERT(env, txn->flags == (MDBX_TXN_RDONLY | MDBX_TXN_FINISHED)); + else if (flags & MDBX_TXN_RDONLY) + eASSERT(env, (txn->flags & ~(MDBX_NOSTICKYTHREADS | MDBX_TXN_RDONLY | MDBX_WRITEMAP | + /* Win32: SRWL flag */ txn_shrink_allowed)) == 0); + else { + eASSERT(env, (txn->flags & ~(MDBX_NOSTICKYTHREADS | MDBX_WRITEMAP | txn_shrink_allowed | txn_may_have_cursors | + MDBX_NOMETASYNC | MDBX_SAFE_NOSYNC | MDBX_TXN_SPILLS)) == 0); + assert(!txn->wr.spilled.list && !txn->wr.spilled.least_removed); + } + txn->signature = txn_signature; + txn->userctx = context; + *ret = txn; + DEBUG("begin txn %" PRIaTXN "%c %p on env %p, root page %" PRIaPGNO "/%" PRIaPGNO, txn->txnid, + (flags & MDBX_TXN_RDONLY) ? 'r' : 'w', (void *)txn, (void *)env, txn->dbs[MAIN_DBI].root, + txn->dbs[FREE_DBI].root); + return MDBX_SUCCESS; } static void latency_gcprof(MDBX_commit_latency *latency, const MDBX_txn *txn) { diff --git a/src/txn-nested.c b/src/txn-nested.c index c6c728f1..57a04de7 100644 --- a/src/txn-nested.c +++ b/src/txn-nested.c @@ -348,25 +348,30 @@ int txn_nested_create(MDBX_txn *parent, const MDBX_txn_flags_t flags) { return LOG_IFERR(MDBX_ENOMEM); tASSERT(parent, dpl_check(parent)); + txn->txnid = parent->txnid; + txn->front_txnid = parent->front_txnid + 1; + txn->canary = parent->canary; + parent->flags |= MDBX_TXN_HAS_CHILD; + parent->nested = txn; + txn->parent = parent; + txn->env->txn = txn; + txn->owner = parent->owner; + txn->wr.troika = parent->wr.troika; + #if MDBX_ENABLE_DBI_SPARSE txn->dbi_sparse = parent->dbi_sparse; #endif /* MDBX_ENABLE_DBI_SPARSE */ txn->dbi_seqs = parent->dbi_seqs; txn->geo = parent->geo; + int err = dpl_alloc(txn); - if (likely(err == MDBX_SUCCESS)) { - const size_t len = MDBX_PNL_GETSIZE(parent->wr.repnl) + parent->wr.loose_count; - txn->wr.repnl = pnl_alloc((len > MDBX_PNL_INITIAL) ? len : MDBX_PNL_INITIAL); - if (unlikely(!txn->wr.repnl)) - err = MDBX_ENOMEM; - } - if (unlikely(err != MDBX_SUCCESS)) { - failed: - pnl_free(txn->wr.repnl); - dpl_free(txn); - osal_free(txn); + if (unlikely(err != MDBX_SUCCESS)) return LOG_IFERR(err); - } + + const size_t len = MDBX_PNL_GETSIZE(parent->wr.repnl) + parent->wr.loose_count; + txn->wr.repnl = pnl_alloc((len > MDBX_PNL_INITIAL) ? len : MDBX_PNL_INITIAL); + if (unlikely(!txn->wr.repnl)) + return LOG_IFERR(MDBX_ENOMEM); /* Move loose pages to reclaimed list */ if (parent->wr.loose_count) { @@ -375,7 +380,7 @@ int txn_nested_create(MDBX_txn *parent, const MDBX_txn_flags_t flags) { tASSERT(parent, lp->flags == P_LOOSE); err = pnl_insert_span(&parent->wr.repnl, lp->pgno, 1); if (unlikely(err != MDBX_SUCCESS)) - goto failed; + return LOG_IFERR(err); MDBX_ASAN_UNPOISON_MEMORY_REGION(&page_next(lp), sizeof(page_t *)); VALGRIND_MAKE_MEM_DEFINED(&page_next(lp), sizeof(page_t *)); parent->wr.loose_pages = page_next(lp); @@ -388,6 +393,9 @@ int txn_nested_create(MDBX_txn *parent, const MDBX_txn_flags_t flags) { #endif /* MDBX_ENABLE_REFUND */ tASSERT(parent, dpl_check(parent)); } +#if MDBX_ENABLE_REFUND + txn->wr.loose_refund_wl = 0; +#endif /* MDBX_ENABLE_REFUND */ txn->wr.dirtyroom = parent->wr.dirtyroom; txn->wr.dirtylru = parent->wr.dirtylru; @@ -412,18 +420,6 @@ int txn_nested_create(MDBX_txn *parent, const MDBX_txn_flags_t flags) { txn->wr.retired_pages = parent->wr.retired_pages; parent->wr.retired_pages = (void *)(intptr_t)MDBX_PNL_GETSIZE(parent->wr.retired_pages); - txn->txnid = parent->txnid; - txn->front_txnid = parent->front_txnid + 1; -#if MDBX_ENABLE_REFUND - txn->wr.loose_refund_wl = 0; -#endif /* MDBX_ENABLE_REFUND */ - txn->canary = parent->canary; - parent->flags |= MDBX_TXN_HAS_CHILD; - parent->nested = txn; - txn->parent = parent; - txn->owner = parent->owner; - txn->wr.troika = parent->wr.troika; - txn->cursors[FREE_DBI] = nullptr; txn->cursors[MAIN_DBI] = nullptr; txn->dbi_state[FREE_DBI] = parent->dbi_state[FREE_DBI] & ~(DBI_FRESH | DBI_CREAT | DBI_DIRTY); @@ -435,7 +431,6 @@ int txn_nested_create(MDBX_txn *parent, const MDBX_txn_flags_t flags) { (parent->parent ? parent->parent->wr.dirtyroom : parent->env->options.dp_limit)); tASSERT(txn, txn->wr.dirtyroom + txn->wr.dirtylist->length == (txn->parent ? txn->parent->wr.dirtyroom : txn->env->options.dp_limit)); - parent->env->txn = txn; tASSERT(parent, parent->cursors[FREE_DBI] == nullptr); return txn_shadow_cursors(parent, MAIN_DBI); } From 1c7a5e18feea46003c0878e4e80b7e7d4dbdefeb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=9B=D0=B5=D0=BE=D0=BD=D0=B8=D0=B4=20=D0=AE=D1=80=D1=8C?= =?UTF-8?q?=D0=B5=D0=B2=20=28Leonid=20Yuriev=29?= Date: Thu, 24 Apr 2025 11:15:55 +0300 Subject: [PATCH 51/52] =?UTF-8?q?mdbx:=20=D0=BF=D0=BE=D0=B4=D1=81=D0=BA?= =?UTF-8?q?=D0=B0=D0=B7=D0=BA=D0=B8=20=D0=B4=D0=BB=D1=8F=20coverity.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/dpl.c | 2 ++ src/dxb.c | 1 + src/txn-basal.c | 1 + src/txn-nested.c | 1 + 4 files changed, 5 insertions(+) diff --git a/src/dpl.c b/src/dpl.c index 41d35797..c48f8553 100644 --- a/src/dpl.c +++ b/src/dpl.c @@ -65,6 +65,8 @@ int dpl_alloc(MDBX_txn *txn) { unlikely(!dpl_reserve(txn, wanna))) return MDBX_ENOMEM; + /* LY: wr.dirtylist не может быть nullptr, так как либо уже выделен, либо будет выделен в dpl_reserve(). */ + /* coverity[var_deref_model] */ dpl_clear(txn->wr.dirtylist); return MDBX_SUCCESS; } diff --git a/src/dxb.c b/src/dxb.c index e18e28d0..e65323ff 100644 --- a/src/dxb.c +++ b/src/dxb.c @@ -1290,6 +1290,7 @@ int dxb_sync_locked(MDBX_env *env, unsigned flags, meta_t *const pending, troika } uint64_t timestamp = 0; + /* coverity[array_null] */ while ("workaround for https://libmdbx.dqdkfa.ru/dead-github/issues/269") { rc = coherency_check_written(env, pending->unsafe_txnid, target, bytes2pgno(env, ptr_dist(target, env->dxb_mmap.base)), ×tamp); diff --git a/src/txn-basal.c b/src/txn-basal.c index 26506872..41afc209 100644 --- a/src/txn-basal.c +++ b/src/txn-basal.c @@ -95,6 +95,7 @@ int txn_basal_start(MDBX_txn *txn, unsigned flags) { txn->wr.troika = meta_tap(env); const meta_ptr_t head = meta_recent(env, &txn->wr.troika); uint64_t timestamp = 0; + /* coverity[array_null] */ while ("workaround for https://libmdbx.dqdkfa.ru/dead-github/issues/269") { int err = coherency_fetch_head(txn, head, ×tamp); if (likely(err == MDBX_SUCCESS)) diff --git a/src/txn-nested.c b/src/txn-nested.c index 57a04de7..719e11ce 100644 --- a/src/txn-nested.c +++ b/src/txn-nested.c @@ -405,6 +405,7 @@ int txn_nested_create(MDBX_txn *parent, const MDBX_txn_flags_t flags) { tASSERT(txn, MDBX_PNL_ALLOCLEN(txn->wr.repnl) >= MDBX_PNL_GETSIZE(parent->wr.repnl)); memcpy(txn->wr.repnl, parent->wr.repnl, MDBX_PNL_SIZEOF(parent->wr.repnl)); + /* coverity[assignment_where_comparison_intended] */ tASSERT(txn, pnl_check_allocated(txn->wr.repnl, (txn->geo.first_unallocated /* LY: intentional assignment here, only for assertion */ = parent->geo.first_unallocated) - From 33385518600a7abb775747a76b8fed60926155b4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=9B=D0=B5=D0=BE=D0=BD=D0=B8=D0=B4=20=D0=AE=D1=80=D1=8C?= =?UTF-8?q?=D0=B5=D0=B2=20=28Leonid=20Yuriev=29?= Date: Thu, 24 Apr 2025 23:26:22 +0300 Subject: [PATCH 52/52] =?UTF-8?q?mdbx:=20=D1=80=D0=B5=D1=84=D0=B0=D0=BA?= =?UTF-8?q?=D1=82=D0=BE=D1=80=D0=B8=D0=BD=D0=B3=20=D0=BC=D0=B0=D0=BA=D1=80?= =?UTF-8?q?=D0=BE=D1=81=D0=B0=20`TXN=5FFOREACH=5FDBI=5FFROM`=20=D1=81=20?= =?UTF-8?q?=D0=B2=D1=8B=D0=B4=D0=B5=D0=BB=D0=B5=D0=BD=D0=B8=D0=B5=D0=BC=20?= =?UTF-8?q?=D1=84=D1=83=D0=BD=D0=BA=D1=86=D0=B8=D0=B8=20`dbi=5Fforeach=5Fs?= =?UTF-8?q?tep()`.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/cursor.c | 1 + src/dbi.h | 41 +++++++++++++++++++++++------------------ 2 files changed, 24 insertions(+), 18 deletions(-) diff --git a/src/cursor.c b/src/cursor.c index 9cc24f59..92c59025 100644 --- a/src/cursor.c +++ b/src/cursor.c @@ -1726,6 +1726,7 @@ __hot csr_t cursor_seek(MDBX_cursor *mc, MDBX_val *key, MDBX_val *data, MDBX_cur csr_t ret; ret.exact = false; + /* coverity[logical_vs_bitwise] */ if (unlikely(key->iov_len < mc->clc->k.lmin || (key->iov_len > mc->clc->k.lmax && (mc->clc->k.lmin == mc->clc->k.lmax || MDBX_DEBUG || MDBX_FORCE_ASSERTIONS)))) { diff --git a/src/dbi.h b/src/dbi.h index 69de4d08..8e6cf4a9 100644 --- a/src/dbi.h +++ b/src/dbi.h @@ -43,30 +43,35 @@ static inline size_t dbi_bitmap_ctz(const MDBX_txn *txn, intptr_t bmi) { return dbi_bitmap_ctz_fallback(txn, bmi); } +static inline bool dbi_foreach_step(const MDBX_txn *const txn, size_t *bitmap_item, size_t *dbi) { + const size_t bitmap_chunk = CHAR_BIT * sizeof(txn->dbi_sparse[0]); + if (*bitmap_item & 1) { + *bitmap_item >>= 1; + return txn->dbi_state[*dbi] != 0; + } + if (*bitmap_item) { + size_t bitmap_skip = dbi_bitmap_ctz(txn, *bitmap_item); + *bitmap_item >>= bitmap_skip; + *dbi += bitmap_skip - 1; + } else { + *dbi = (*dbi - 1) | (bitmap_chunk - 1); + *bitmap_item = txn->dbi_sparse[(1 + *dbi) / bitmap_chunk]; + if (*bitmap_item == 0) + *dbi += bitmap_chunk; + } + return false; +} + /* LY: Макрос целенаправленно сделан с одним циклом, чтобы сохранить возможность * использования оператора break */ #define TXN_FOREACH_DBI_FROM(TXN, I, FROM) \ - for (size_t bitmap_chunk = CHAR_BIT * sizeof(TXN->dbi_sparse[0]), bitmap_item = TXN->dbi_sparse[0] >> FROM, \ - I = FROM; \ - I < TXN->n_dbi; ++I) \ - if (bitmap_item == 0) { \ - I = (I - 1) | (bitmap_chunk - 1); \ - bitmap_item = TXN->dbi_sparse[(1 + I) / bitmap_chunk]; \ - if (!bitmap_item) \ - /* coverity[const_overflow] */ \ - I += bitmap_chunk; \ - continue; \ - } else if ((bitmap_item & 1) == 0) { \ - size_t bitmap_skip = dbi_bitmap_ctz(txn, bitmap_item); \ - bitmap_item >>= bitmap_skip; \ - I += bitmap_skip - 1; \ - continue; \ - } else if (bitmap_item >>= 1, TXN->dbi_state[I]) + for (size_t bitmap_item = TXN->dbi_sparse[0] >> FROM, I = FROM; I < TXN->n_dbi; ++I) \ + if (dbi_foreach_step(TXN, &bitmap_item, &I)) #else -#define TXN_FOREACH_DBI_FROM(TXN, I, SKIP) \ - for (size_t I = SKIP; I < TXN->n_dbi; ++I) \ +#define TXN_FOREACH_DBI_FROM(TXN, I, FROM) \ + for (size_t I = FROM; I < TXN->n_dbi; ++I) \ if (TXN->dbi_state[I]) #endif /* MDBX_ENABLE_DBI_SPARSE */