libmdbx 0.14.1 "Горналь"

Леонид Юрьев обновлён 3 недели назад v0.14.1 a13147d Пре-релиз
0
Описание

Первый выпуск в новом кусте/линейке версий с добавлением функционала, расширением API и внутренними переработками.

For translation to other languages please try Yandex or liar Google.

git diff' stat: 166 files changed, 9467 insertions(+), 5597 deletions(-)

Благодарности:

  • Erigon за спонсорство.
  • Alain Picard for support Java bindings 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.
  • Alex Sharov за сообщение об ошибках и тестирование.
  • Виктору Логунову за сообщение об опечатки в имени переменной в C-рецепте.
  • Илье Михееву за сообщение о лишнем/ненужном предупреждении несоответствия файла БД новому размеру.
  • maxc0d3r for bug reporting and testing.
  • Алексею Костюку (aka Keller) за сообщения о проблеме копирования на NFS.

Новое:

  • Переработан код обновления GC и возврата страниц при фиксации транзакций.

    Возникающая при этом задача алгоритмически сложна, так как список возвращаемых страниц находится в рекурсивной зависимости от самой процедуры возврата и связанных с этим операций, а прямые решения во многих случаях приводят к многократному росту накладных расходов. Поэтому исторически эта часть кода была запутанным наслоением «сдержек и противовесов», что создавало препятствие для развития. В ходе этой доработки, унаследованный из LMDB код связанный с обновлением GC, был полностью заменен вместе со всеми базирующимися на нём заплатками.

    Новая реализация использует контейнеры идентификаторов (aka RKL), комбинирующие внутри списки элементов и непрерывные интервалы, что позволяет предельно сократить накладные расходы и упросить реализацию остальных алгоритмов. Основывается новая реализация на простом прагматичном подходе «резервирования со взвешенным запасом». Для подавляющего подмножества сценариев этого достаточно для однопроходного обновления GC, с общей сложностью от O(1) для мелких транзакций, до O(log(N)) для огромных. При этом реализованный еще в 0.12.1 подход «Big Foot» (дробление больших списков retired-страниц) полностью избавляет GC от потребности в последовательностях смежных/соседствующих страниц и одновременно позволяет работать новому коду обновления GC только по самому простому и быстрому пути.

    Чуть более подробно, включая пояснения более сложных случаев/алгоритмов, см ChangeLog.

  • Добавлена опция сборки MDBX_NOSUCCESS_PURE_COMMIT предназначенная для отладки кода пользователя. По-умолчанию опция выключена и при фиксации пустых транзакции возвращается MDBX_SUCCESS. При включении опции, фиксация пишущих транзакций без каких-либо изменений считается нештатным поведением, с возвратом из mdbx_txn_commit() кода MDBX_RESULT_TRUE вместо MDBX_SUCCESS. Таким образом, у пользователя появляется возможность легко диагностировать лишние/ненужные транзакции записи.

  • Добавлена опция сборки MDBX_ENABLE_NON_READ_EXPORT позволяющая использовать в режиме чтения-записи БД расположенных в файловых системах экспортированных через NFS. По-умолчанию опция выключена и при открытии в неэксклюзивном режиме чтения-записи БД расположенных в файловых системах доступных извне по NFS будет возвращаться ошибка MDBX_EREMOTE. Включение опции позволяет открывать БД в описанных выше ситуациях, но риск чтения неверных данных на удалённой стороне ложится на пользователя.

  • Добавлена операция MDBX_SEEK_AND_GET_MULTIPLE в API курсора, позволяющая за одну операцию выполнить позиционирование курсора на конкретное значение и начать чтение multi-значений в пакетном режиме.

  • В chk-функционал добавлена гистограмма количества multi-значений/дубликатов. При использовании утилиты mdbx_chk, для получения соответствующей (и массы другой) информации, достаточно увеличить детализацию несколько раз использовав опцию -v.

  • В политику управления выделением для mdbx::buffer добавлен параметр inplace_storage_size_rounding. Одновременно с этим переработан внутренний union-тип mdbx::buffer::silo::bin для возможности увеличения без пенальти встроенного в экземпляр буфера места под данные.

  • Добавлена опция -c (c) для включения компактного режима в mdbx_dump, также поддержка таких дампов в mdbx_load. В таких дампах значение ключей сохраняются однократно (не повторяются), что может существенно уменьшать результирующий объём для таблиц с multi-значениями (aka dupsort). Однако, компактные дампы не совместимы с форматом ожидаемым/поддерживаемым в Berkeley Database и LMDB.

  • В API добавлена функция mdbx_cursor_close2() возвращающая код ошибки.

  • Для закрытия или отсоединения всех курсоров с получением их количества в API добавлена функция mdbx_txn_release_all_cursors_ex().

  • Добавлены методы mdbx::cursor::put_multiple_samelength(), mdbx::cursor::seek_multiple_samelength(), mdbx::cursor_managed::withdraw_handle().

Изменение поведения:

  • Теперь при вставке данных в dupsort-таблицу CoW копирование целевых страниц выполняется после проверки отсутствия добавляемого значения среди уже присутствующих multi-значений (aka дубликатов). В результате вставка уже присутствующих “дубликатов” не приводит к каким-либо изменениям в БД и принципиально увеличивает производительность в таких сценариях. В текущем понимании, добавленная проверка не приводит к заметному увеличению накладных расходов и, как следствие, не приводит к снижению производительности в сценариях с обычным/регулярным обновлением и/или вставкой данных.

  • Использование системного кода ошибки EREMOTEIO (“Remote I/O error”) вместо ENOTBLK (“Block device required”) в качестве MDBX_EREMOTE для индикации ошибочной ситуации открытия БД расположенной на сетевом носителе.

  • Функция mdbx_txn_release_all_cursors() возвращает только код ошибки, не смешивая его с количеством обработанных/закрытых курсоров. Для аналогичных действий с получением количества закрытых курсоров в API добавлена функция mdbx_txn_release_all_cursors_ex().

  • Поддержка пустого набора данных в put-операции MDBX_MULTIPLE ради упрощения пользовательского кода, какой-либо модификации данных в БД при этом не происходит.

  • Для основных вариантов использования шаблона mdbx::buffer<> теперь явно инстанцируются внутри библиотеки, одновременно соответствующие специализации шаблона помечены как external для предотвращения повторного инстанцирования в пользовательском коде.

  • Запрещена отвязка/открепление курсоров во вложенных транзакциях, т.е. вызовы mdbx_cursor_unbind() и mdbx_txn_release_all_cursors(unbind=true) для курсоров открытых в одной из родительских транзакций. Причина в том, что в случае отмены вложенной транзакции возникает неконструктивная неопределенность — следует ли восстанавливать состояние курсоров. Если не восстанавливать, то получается что вложенная транзакция может поломать родительскую, сделав её продолжение невозможным. Если восстанавливать, то также следует «воскрешать» закрытые курсоры, что неизбежно приведет к путанице, утечкам памяти и использованию после освобождения.

  • В C++ API отменён вброс исключения при запросе транзакции у отсоединённого курсора посредством вывоза mdbx::cursor::txn().

  • При невозможности отвязки курсора от его текущей транзакции функция mdbx_cursor_bind() теперь возвращает MDBX_EINVAL вместо MDBX_BAD_TXN.

Загрузки:


За информацией о предыдущих версиях обращайтесь к тегам git и ChangeLog.