Теоретически до этого коммита могла быть некоторая неувязка:
- при открытии БД с размером страницы 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.
При переделке курсоров было пропущено отрицание в условии, при оценке
кол-ва страниц, которые могут потребоваться для выполнения операции.
В текущем понимании ошибка не приводила к каким-либо проблемам, ибо
оценка делает по верхней границе с существенным запасом, а в худшем
случае это могло приводить к прерыванию транзакции из-за достижения
ограничения на кол-во грязных страниц.
На штатную работу это никак не влияет, но немного облегчит разбор
ситуаций когда глобальный конструктор не вызывается, либо делается
попытка вызвать его дважды (из-за ошибок rtc/libc, etc).
Ранее проверка внутри cursor_seek() не позволяла искать ключи длиннее чем можно поместить в таблицу,
что при поиске/позиционировании не является ошибкой для ключей переменного размера.