Проблема была в том, что в случаях фиксированного размера значений
clc.lmin/clc.lmax устанавливались в env->kvs[], а затем корректировались
по актуальному размеру данных в БД. Поэтому при конкурентном вызове из
разных потоков, один поток мог выполнять инициализацию, а второй
прочитать временные/промежуточные значения lmin/lmax.
В результате, при конкурентном старте транзакций в разных потоках при
использовании только-что открытого dbi-хендла, проверка допустимости
длины значения могла заканчиваться ложной ошибкой MDBX_BAD_VALSIZE.
По недосмотру в выпусках остался предварительный/черновой вариант
функции mdbx_txn_release_all_cursors(), который смешивает в возвращаемом
значении информацию об ошибке/успехе и количество обработанных курсоров.
За-за чего невозможно отличить одно от другого, например ошибку EPERM на
Linux от одного успешно закрытого курсора.
Теперь mdbx_txn_release_all_cursors() возвращает только код ошибки,
а для получения кол-ва закрытых курсоров в API добавлена функция mdbx_txn_release_all_cursors_ex().
Некая проблема была в том, что при высоком уровне логирования в логгер
также отправлялись неизбежные MDBX_NOTFOND при достижении конца
интегрируемых данных. В свою очередь, chk-логика формирования отчета
подсчитывала эти сообщения как ошибки при проверке БД...
Теоретически до этого коммита могла быть некоторая неувязка:
- при открытии БД с размером страницы 4K на Windows (где размер секции кратен 64K) в режиме read-only,
- после того как БД использовалась на POSIX (где размер отображения кратен размеру системной страницы).
Ранее ошибка могла возвращаться со стороны системы (например INVALID_PARAMETER) и по ней крайне сложно было понять в чем дело.
Теперь же будет логирование ошибки и возврат MDBX_WANNA_RECOVERY.
Переработка 05cdf9d202b14ac09c801c7893e65271fa27f378. У предыдущего
варианта был недостаток, при необходимости выдачи предупреждения
и открытии БД с изменением геометрии, предупреждение не выдавалось,
что может затруднять анализ/разбор проблемных ситуаций.
Изменение геометрии (увеличение размера) больших БД может быть не
возможно после их открытия вследствие системных ограничений (отсутствия
свободного адресного пространства).
Поэтому API предусматривает возможность запросить изменение
геометрии/размера БД перед её открытием. В этом сценарии ранее могло
выдаваться лишнее/ненужное предупреждение о несоответствии файла БД
новому размеру. Теперь этот недостаток исправлен.
Спасибо Илье Михееву (Erigon) за сообщение об этом недочете.
Ошибка внесена коммитом `a6f7d74a32a3cbcc310916a624a31302dbebfa07` от
2024-03-07 и присутствует в выпусках v0.13.1, v0.13.2, v0.13.3. Проблема
оставалась незамеченной из-за специфических условий и низкой вероятности
проявления.
Суть ошибки:
- функция cursor_touch() подготавливает стек страниц курсора к внесению
изменений, при этом все страницы в стеке (от корневой до листовой
в текущей позиции курсора) должны стать доступными для модификации.
- микрооптимизация добавленная коммитом пропускала обход стека, если
корневая страница уже доступна для модификации, но это
допустимо/корректно только при отсутствии в стеке вытесненных/spilled
страниц.
- если же складывалась ситуация когда в стека была вытесненная
некорневая страница, то она так и оставалась недоступной для записи и
при попытке её изменения возникал SIGSEGV.
При переделке курсоров было пропущено отрицание в условии, при оценке
кол-ва страниц, которые могут потребоваться для выполнения операции.
В текущем понимании ошибка не приводила к каким-либо проблемам, ибо
оценка делает по верхней границе с существенным запасом, а в худшем
случае это могло приводить к прерыванию транзакции из-за достижения
ограничения на кол-во грязных страниц.