Поддерживающий выпуск стабильной ветки с исправлением обнаруженных ошибок и устранением недочётов.
За перечнем доработок и изменений обращайтесь к [ChangeLog](https://libmdbx.dqdkfa.ru/md__change_log.html).
git diff' stat: 49 files changed, 2106 insertions(+), 1135 deletions(-)
Signed-off-by: Леонид Юрьев (Leonid Yuriev) <leo@yuriev.ru>
Пакетная вставка значений посредством операции `MDBX_MULTIPLE` могла
приводить к падениям и повреждению структуры БД. Ошибка оставалось не
замеченной из-за специфических условий проявления, которые не
реализовались в тестах.
Проблема присутствовала во всех выпусках начиная с v0.13.1, но
соответствующая ошибка не связана с конкретным коммита в истории, а
является следствием нескольких доработок (шагов рефакторинга), которые
суммарно привели к регрессу.
Технически ошибка обусловлена не-обнулением переменной, которая не
обнулялась в некотором пути выполнения и исходно не требовала обнуления,
но такое обнуление потребовалось после ряда этапов оптимизации кода и
рефакторинга.
Основным условием проявления является пакетная вставка multi-значений в
dupsort-таблицу с фиксированным размером значений, при котором набор
значений соответствующий обновляемом ключу, перестаёт помещаться на
вложенной странице и преобразуется/выносится во вложенное дерево
страниц. Если такой вынос/преобразование происходило до исчерпания
переданного набора значений, то при следующей итерации повторно
производились действия соответствующие выносу данных в отдельное дерево
страниц. Что могла приводить как к разыменованию неверных указателей
(повреждению содержимого памяти) и/или к повреждению содержимого страниц
образующих структуру БД.
Исправление свелось к добавлению одной строчки кода, но также были
расширены тесты для покрытия соответствующих сценариев.
Проблема была в том, что в случаях фиксированного размера значений
clc.lmin/clc.lmax устанавливались в env->kvs[], а затем корректировались
по актуальному размеру данных в БД. Поэтому при конкурентном вызове из
разных потоков, один поток мог выполнять инициализацию, а второй
прочитать временные/промежуточные значения lmin/lmax.
В результате, при конкурентном старте транзакций в разных потоках при
использовании только-что открытого dbi-хендла, проверка допустимости
длины значения могла заканчиваться ложной ошибкой MDBX_BAD_VALSIZE.
Теоретически до этого коммита могла быть некоторая неувязка:
- при открытии БД с размером страницы 4K на Windows (где размер секции кратен 64K) в режиме read-only,
- после того как БД использовалась на POSIX (где размер отображения кратен размеру системной страницы).
Ранее ошибка могла возвращаться со стороны системы (например INVALID_PARAMETER) и по ней крайне сложно было понять в чем дело.
Теперь же будет логирование ошибки и возврат MDBX_WANNA_RECOVERY.
Переработка 05cdf9d202b14ac09c801c7893e65271fa27f378. У предыдущего
варианта был недостаток, при необходимости выдачи предупреждения
и открытии БД с изменением геометрии, предупреждение не выдавалось,
что может затруднять анализ/разбор проблемных ситуаций.
При сборке посредством GCC >= 11.4 больше не возникает предупреждений:
lto-wrapper: warning: using serial compilation of # LTRANS jobs
lto-wrapper: note: see the ‘-flto’ option documentation for more information
Однако, использование auto-режима не является оптимальным решением, так
как при параллельной сборке посредством make или ninja, каждая уже
запущенная ветвь компиляции породит потоки ещё для каждого ядра ЦПУ.
Таким образом реальная нагрузка может расти квадратично, т.е. чем больше
у вас ядер -- тем хуже и при 96 ядрах может работать 9216 потоков сборки.
Тем не менее, использование `job-server` в CMake пока не возможно, а при
сборке libmdbx не так много работы чтобы чтобы обрушить систему нагрузкой.