libmdbx 0.12.3 (Акула)
Выпуск с существенными доработками и новой функциональностью в память о закрытом 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 для уменьшения накладных расходов.
- Рефакторинг и микрооптимизация.
Загрузки:
- 279K, libmdbx-amalgamated-0.12.3.zpaq, sha256sum:
3bf4967c3a2b81d01e73d91cb2b53890e3dd56169efda29e828f3441f27f41cc
- 374K, libmdbx-amalgamated-0.12.3.tar.xz, sha256sum:
6301f91e1fb821b994278ea0f920ecc7e3d2b8169d83ddfecad7f1413567659d
- 505K, libmdbx-amalgamated-0.12.3.tar.bz2, sha256sum:
b41499a6a555c033cec655ba2bd8d48938b1ff174a7a57e60b10baaeeec12a7f
- 771K, libmdbx-amalgamated-0.12.3.tar.gz, sha256sum:
3592491334a273a08b9681486cdc460a3121a3fce7a4465718ad1b5a50c83b83
- 783K, libmdbx-amalgamated-0_12_3.zip, sha256sum:
3fda1246e948524554a23851f1a44d28cf1ca4cea78b77527fdd40c000513d1b
За информацией о предыдущих версиях обращайтесь к тегам git и ChangeLog.