libmdbx 0.12.3 (Акула)

Леонид Юрьев обновлён 2 года назад v0.12.3 f1fdb88 Релиз
0
Описание

Выпуск с существенными доработками и новой функциональностью в память о закрытом open-source проекте “Акула”.

Добавлена prefault-запись, переделан контроль “некогерентностиunified page/buffer cache, изменена тактика слияния страниц и т.д. Стало ещё быстрее, в некоторых сценариях вдвое.

20 files changed, 4504 insertions(+), 2924 deletions(-)
Signed-off-by: Леонид Юрьев (Leonid Yuriev) <leo@yuriev.ru>

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

  • Alex Sharov и команде Erigon за тестирование.
  • Simon Leier за сообщение о сбоях и тестирование.

Новое:

  • Использование адреса https://libmdbx.dqdkfa.ru/dead-github для отсылки к сохранённым в web.archive.org копиям ресурсов, уничтоженных администрацией Github.

  • Реализована prefault-запись при выделении страниц для read-write отображений. Это приводит к кратному снижению системных издержек и существенному увеличению производительности в соответствующих сценариях использования, когда:

    • размер БД и объём данных существенно больше ОЗУ;
    • используется режим MDBX_WRITEMAP;
    • не-мелкие транзакции (по ходу транзакции выделяется многие сотни или тысячи страниц).

    В режиме MDBX_WRITEMAP выделение/переиспользование страниц приводит к page-fault и чтению страницы с диска, даже если содержимое страницы не нужно (будет перезаписано). Это является следствием работы подсистемы виртуальной памяти, а штатный способ лечения через MADV_REMOVE работает не на всех ФС и обычно дороже получаемой экономии.

    Теперь в libmdbx используется “упреждающая запись” таких страниц, которая на системах с unified page cache приводит к “вталкиванию” данных, устраняя необходимость чтения с диска при обращении к такой странице памяти.

    Новый функционал работает в согласованности с автоматическим управлением read-ahead и кэшем статуса присутствия страниц в ОЗУ, посредством mincore().

  • Добавлена опция MDBX_opt_prefault_write_enable для возможности принудительного включения/выключения prefault-записи.

  • Реализован динамический выбор между сквозной записью на диск и обычной записью с последующим fdatasync() управляемый опцией MDBX_opt_writethrough_threshold.

    В долговечных (durable) режимах данные на диск могут быть сброшены двумя способами:

    • сквозной записью через файловый дескриптор открытый с O_DSYNC;
    • обычной записью с последующим вызовом fdatasync().

    Первый способ выгоднее при записи малого количества страниц и/или если канал взаимодействия с диском/носителем имеет близкую к нулю задержку. Второй способ выгоднее если требуется записать много страниц и/или канал взаимодействия имеет весомую задержку (датацентры, облака). Добавленная опция MDBX_opt_writethrough_threshold позволяет во время выполнения задать порог для динамического выбора способа записи в зависимости от объема и конкретных условия использования.

  • Автоматическая установка MDBX_opt_rp_augment_limit в зависимости от размера БД.

  • Запрещение разного режима MDBX_WRITEMAP между процессами в режимах с отложенной/ленивой записью, так как в этом случае невозможно обеспечить сброс данных на диск во всех случаях на всех поддерживаемых платформах.

  • Добавлена опция сборки MDBX_MMAP_USE_MS_ASYNC позволяющая отключить использование системного вызова msync(MS_ASYNC), в использовании которого нет необходимости на подавляющем большинстве актуальных ОС. По-умолчанию MDBX_MMAP_USE_MS_ASYNC=0 (выключено) на Linux и других системах с unified page cache. Такое поведение (без использования msync(MS_ASYNC)) соответствует неизменяемой (hardcoded) логике LMDB. В результате, в простых/наивных бенчмарках, libmdbx опережает LMDB примерно также как при реальном применении.

    На всякий случай стоит еще раз отметить/напомнить, что на Windows предположительно libmdbx будет отставать от LMDB в сценариях с множеством мелких транзакций, так как libmdbx осознанно использует на Windows файловые блокировки, которые медленные (плохо реализованы в ядре ОС), но позволяют застраховать пользователей от массы неверных действий приводящих к повреждению БД.

  • Поддержка не-печатных имен для subDb.

  • Добавлен явный выбор tls_model("local-dynamic") для обхода проблемы relocation R_X86_64_TPOFF32 against FOO cannot be used with -shared из-за ошибки в CLANG приводящей к использованию неверного режима ls_model.

  • Изменение тактики слияния страниц при удалении. Теперь слияние выполняется преимущественно с уже измененной/грязной страницей. Если же справа и слева обе страницы с одинаковым статусом, то с наименее заполненной, как прежде. В сценариях с массивным удалением это позволяет увеличить производительность до 50%.

  • Добавлен контроль отсутствия LCK-файлов с альтернативным именованием.

Исправления (без корректировок новых функций):

  • Изменение размера отображения если это требуется для сброса данных на диск при вызове mdbx_env_sync() из параллельного потока выполнения вне работающей транзакции.

  • Исправление регресса после коммита db72763de049d6e4546f838277fe83b9081ad1de от 2022-10-08 в логике возврата грязных страниц в режиме MDBX_WRITEMAP, из-за чего освободившиеся страницы использовались не немедленно, а попадали в retired-список совершаемой транзакции и происходил необоснованный рост размера транзакции.

  • Устранение SIGSEGV или ошибочного вызова free() в ситуациях повторного открытия среды посредством mdbx_env_open().

  • Устранение ошибки совершенной в коммите fe20de136c22ed3bc4c6d3f673e79c106e824f60 от 2022-09-18, в результате чего на Linux в режиме MDBX_WRITEMAP никогда не вызывался msync(). Проблема существует только в релизе 0.12.2.

  • Добавление подсчета грязных страниц в MDBX_WRITEMAP для предоставления посредством mdbx_txn_info() актуальной информации об объеме изменений в процессе транзакций чтения-записи.

  • Исправление несущественной опечатки в условиях #if определения порядка байт.

  • Исправление сборки для случая MDBX_PNL_ASCENDING=1.

Ликвидация технических долгов и мелочи:

  • Доработка поддержки авто-слияния записей GC внутри page_alloc_slowpath().
  • Устранение несущественных предупреждений Coverity.
  • Использование единого курсора для поиска в GC.
  • Переработка внутренних флагов связанных с выделением страниц из GC.
  • Доработка подготовки резерва перед обновлением GC при включенном BigFoot.
  • Оптимизация pnl_merge() для случаев неперекрывающихся объединяемых списков.
  • Оптимизация поддержки отсортированного списка страниц в dpl_append().
  • Ускорение работы mdbx_chk при обработке пользовательских записей в @MAIN.
  • Переработка LRU-отметок для спиллинга.
  • Переработка контроля “некогерентности” Unified page cache для уменьшения накладных расходов.
  • Рефакторинг и микрооптимизация.

Загрузки:


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

Файлы
  • Нет файлов