Выпуск высокопроизводительной встраиваемой СУБД libmdbx 0.11.7

Состоялся выпуск библиотеки libmdbx 0.11.7 (MDBX) с реализацией высокопроизводительной компактной встраиваемой базы данных класса ключ-значение. Код libmdbx распространяется под лицензией OpenLDAP Public License. Поддерживаются все актуальные операционные системы и архитектуры, а также российский Эльбрус 2000.

Релиз примечателен миграцией проекта на сервис GitFlic после того, как 15 апреля 2022 года администрация Github без каких-либо предупреждений и объяснения причин удалила libmdbx вместе с массой других проектов, одновременно заблокировав доступ многим разработчикам, связанным с компаниями, попавшими под санкции США. С точки зрения пользователей, все страницы, репозиторий и форки проекта внезапно превратились в страницу “404”, без возможности каких-либо коммуникаций и выяснения причин.

К сожалению утрачены почти все issues, в которых было много вопросов с подробными ответами, а также немало обсуждений. Утрата этой информации является единственным объективным ущербом, который администрацией GitHub удалось нанести проекту. Частично копии обсуждений остаются доступны в архиве archive.org.

Потеря отстроенных CI-сценариев и инфраструктуры (доступной для OpenSource-проектов бесплатно) заставила заняться ревизией, унификацией и устранением небольшого техдолга. Сейчас CI восстановлен почти в прежнем объёме, за исключением сборки и прогон-тестов для всех вариантов BSD и Solaris. Что характерно, после действий со стороны Github не поступило каких-либо разъяснений или уведомлений, не считая напоминания о необходимости оплаты и попыток списать деньги.

С момента прошлой новости о релизе libmdbx v0.11.3, помимо восстановления после дейсвтий GitHub, стоит отметить следующие доработки и исправления:

  • Добавлен обход обнаруженного эффекта/дефекта некогерентности в объединённом кэше страниц и буферов в ядре Linux.
    В системах где кэш страниц и буферов действительно объединён, ядру нет смысла тратить память под две копии данных при записи в уже отображённый в память файл. Поэтому записываемые данные становятся видимыми через отображение в памяти до завершения системного вызова write(), даже если данные ещё не записаны на диск.

    Суммарно другое поведение не рационально, ибо при отложенном слиянии всё равно придётся захватывать блокировки для списков страниц, копировать данные или корректировать PTE. Поэтому негласное правило когерентности действовало с 1989 года, когда в SRV4 появился unified buffer cache.
    Поэтому обнаружение странных сбоев в нагруженных сценариях эксплуатации libmdbx потребовало большой работы. Сначала по воспроизведению проблемы, потом по верификации гипотез и проверке доработок.

    Сейчас можно уверенно сказать что проблема достоверно идентифицирована, локализована и надёжно устранена, несмотря на всю сложность и специфичность сценария воспроизведения. Дополнительно работа механизма обхода была подтверждена одним из разработчиков Erigon (Ethereum), в его случае на отладочной сборке срабатывание защиты проявлялось в виде регресса из-за лишней assert-проверки.

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

  • Устранён регресс возникновения ошибки EXDEV (Cross-device link) при горячем копировании БД без компактификации на другую файловую систему, как через API, так и утилитой mdbx_copy.
  • Kris Zyp реализовал поддержку libmdbx в Deno. Kai Wetlesen оформил пакетирование RPM для Fedora.David Bouyssié реализовал привязки для Scala.
  • Поправлена обработка значения, задаваемого опцией MDBX_opt_rp_augment_limit при обработке огромных транзакций в больших БД. Ранее из-за ошибки могли производится лишние действия, что иногда сказывалось на производительности в реализациях Ethereum (Erigon/Akula/Silkworm) и проектах Binance Chain.
  • Исправлено масса недочётов, в том числе в C++ API. Устранено много проблем со сборкой в редких и экзотических конфигурациях. Полный перечень всех значимых доработок доступен в ChangeLog.
  • Суммарно внесено 185 изменений в 89 файлов, добавлено ≈3300 строк, удалено ≈4100. Удалено больше в основном из-за чистки от уже бесполезных технологических файлов связанных с Github и зависимых сервисов.

Исторически libmdbx является глубокой переработкой СУБД LMDB и превосходит своего прародителя по надёжности, набору возможностей и производительности. В сравнении с LMDB, в libmdbx большое внимание уделяется качеству кода, стабильной работе API, тестированию и автоматическим проверкам. Поставляется утилита проверки целостности структуры БД с некоторыми возможностями восстановления.

Технологически libmdbx предлагает ACID, строгую сериализацию изменений и неблокирующее чтение с линейным масштабированием по ядрам ЦПУ. Поддерживается автокомпактификация, автоматическое управление размером БД, оценка объёма выборок по диапазонам (range query estimation). С 2016 года проект финансируется компанией Positive Technologies и с 2017 года используется в её продуктах.

Для libmdbx предлагается развитое C++ API, а также поддерживаемые энтузиастами привязки к языкам Rust, Haskell, Python, NodeJS, Ruby, Go, Nim, Deno, Scala.

Release. Ссылка here.