Завершающий выпуск архивной ветки с исправлением обнаруженных ошибок и устранением недочетов.
`git diff' stat: 14 commits, 7 files changed, 256 insertions(+), 103 deletions(-)`
Это последний/консервирующий выпуск куста стабильных версий 0.12.x, спустя более двух лет после выпуска 0.12.1.
Значимые исправления:
---------------------
- Исправлена обработка `MDBX_GET_MULTIPLE` в специальных случаях и одного значения у ключа в позиции курсора.
- Устранена ошибка неверной обработки попытки запуска вложенной читающей транзакции.
Теперь в таких ситуациях возвращается ошибка `MDBX_EINVAL`, так как вложенность
поддерживается только для транзакций чтения-записи.
Ошибка была внесена при рефакторинге, коммитом `2f2df1ee76ab137ee66d00af69a82a30dc0d6deb`
чуть более 5 лет назад и долго оставалось не замеченной.
- Поддержка получения boot_id при работе внутри LXC-контейнера.
Из LXC-контейнера не доступен файл хостовой системы `/proc/sys/kernel/random/boot_id`.
Вместо него, при каждом старте контейнера, создается и заполняется
случайными данными собственный boot_id смонтированный через bind из `tmpfs`.
https://github.com/lxc/lxc/issues/3027
Ранее этот подставной/замещенный boot_id отбраковывался внутри libmdbx,
так как файл располагается в `tmpfs`, а не в файловой системе `/proc`.
В результате boot_id для проверки целостности БД не был доступен.
Теперь при работе внутри LXC-контейнера такой bootid будет использоваться.
Однако, полноценно работающий контроль по boot_id не возможен, так как при
рестарте LXC-контейнера (но не хоста) boot_id будет меняться, хотя
данные в unified page cache сохраняются.
Таким образом, при рестарте LXC-контейнера без рестарта хоста, libmdbx придется
откатить состояние БД до крайней точки устойчивой фиксации, что повлечет
утрату данных пользователя в случаях когда они могли быть сохранены.
Однако, улучшить ситуацию пока не представляется возможным, как минимум
до доступности boot_id хостовой системы изнутри LXC-контейнера.
- Доработан контроль длины ключа внутри `cursor_set()`.
Ранее проверка внутри `cursor_set()` не позволяла искать ключи длиннее, чем можно поместить в таблицу.
Однако, при поиске/позиционировании это не является ошибкой для таблиц с ключами переменного размера.
- Теперь при попытке запуска вложенных транзакций в режиме `MDBX_WRITEMAP` производится
логирование и возврат ошибки `MDBX_INCOMPATIBLE`.
- Доработано использование `std::experimental::filesystem` для решения проблем со сборкой в старых компиляторах.
Более подробная информация и история предыдущих выпусков доступна в [ChangeLog](https://libmdbx.dqdkfa.ru/md__change_log.html).
Signed-off-by: Леонид Юрьев (Leonid Yuriev) <leo@yuriev.ru>
Из LXC-контейнера не доступен файл хостовой системы "/proc/sys/kernel/random/boot_id".
Вместо него, при каждом старте контейнера, создается и заполняется
случайными данными собственный boot_id смонтированный через bind из tmpfs.
https://github.com/lxc/lxc/issues/3027
Поэтому полноценный контроль по boot_id не возможен, так как при
рестарте LXC-контейнера (но не хоста) boot_id будет меняться, хотя
данные в unified page cache сохраняются.
Таким образом, при рестарте LXC-контейнера, libmdbx будет производить
откат БД до крайней точки устойчивой фиксации, что может приводить к
утрате данных пользователя в случаях когда они могли быть сохранены.
Однако, улучшить ситуацию пока не представляется возможным, как минимум
до доступности boot_id хостовой системы изнутри LXC-контейнера.
Этот коммит частично улучшает ситуацию тем, что позволяет использовать
фейковый/замещенный boot_id размещенный в файловой системе с типом tmpfs
при работе внутри LXC-контейнера.
Ранее проверка внутри cursor_set() не позволяла искать ключи длиннее чем можно поместить в таблицу,
что при поиске/позиционировании не является ошибкой для ключей переменного размера.
Поддерживающий выпуск с исправлением обнаруженных ошибок и устранением недочетов,
в память о советском ученом-энергетике Николае Антоновиче Доллежаль в день 125-летия со дня его рождения.
Это последний выпуск куста стабильных версий 0.12.x, спустя более двух
лет после выпуска 0.12.1. Последующие выпуски 0.12.x будут формироваться
только в случае существенных проблем/ошибок, вероятность чего близка к
нулю. Для всех проектов находящихся в стадии активной разраборки
рекомендуется использовать ветку `master`.
Значимые исправления:
---------------------
- Исправление упущенного `TXN_END_EOTDONE` при сбое старта читающей транзакции.
Упомянутый флажок отсутствовал в пути разрушения транзакции при ошибке
её запуска. Из-за чего делалась попытка разрушить курсоры, что приводило
к падению **отладочных сборок**, так как в них соответствующий массив
намеренно заполнен некорректными указателями.
- Устранение возможности `SIGSEGV` внутри `coherency_check()` после
изменения геометрии другим процессом с увеличением верхнего размера БД
и увеличением БД больше предыдущего лимита.
- Доработка `mdbx_close_dbi()` для возврата ошибки при попытке закрыть
dbi-дескриптор таблицы, созданной и/или измененной в ещё выполняющейся
транзакции. Такое преждевременное закрытие дескриптора является неверным
использованием API и нарушением контракта/предусловий сформулированных
в описании `mdbx_close_dbi()`. Однако, вместо возврата ошибки
выполнялось некорректное закрытие дескриптора, что могло приводить к
созданию таблицы с пустым именем, утечки страниц БД и/или нарушению
структуры b-tree (неверной ссылкой на корень таблицы).
Добавлен соответствующий тест `extra/early_close_dbi`.
Более подробная информация и история предыдущих выпусков доступна в [ChangeLog](https://libmdbx.dqdkfa.ru/md__change_log.html).
git diff' stat: 6 commits, 5 files changed, 239 insertions(+), 6 deletions(-)
Signed-off-by: Леонид Юрьев (Leonid Yuriev) <leo@yuriev.ru>
Падение происходило в случае когда:
- Некоторый процесс увеличивал размер БД с изменением геометрии (с
увеличением предельного размера БД и её отображения в ОЗУ), затем
задействовал страницу из добавленного сегмента в качестве корневой для
FreeDB/GC и/или MainDB и фиксировал транзакцию.
- Другой процесс, уже работавший с БД до изменения геометрии первым
процессом, запускал транзакцию чтения. Падение происходило при проверке
«когерентности» отображения страниц БД в ОЗУ, при проверке отметок
модификации внутри корневых страниц, так как в этом случае они были вне
границ текущего отображения БД в адресном пространстве этого процесса.
Похоже что в ходе какого-то рефакторинга потерялась соответствующая
проверка. Этот коммит добавляет такую проверку.
Упомянутый флажок отсутствовал в пути разрушения транзакции при ошибке
её запуска. Из-за чего делалась попытка разрушить курсоры, что приводило
к падению отладочных сборок, так как в них соответствующий массив
намеренно заполнен некорректными указателями.
Поддерживающий выпуск с исправлением обнаруженных ошибок и устранением недочетов,
в память об убитых в Крыму девочках 2 и 9 лет.
Лиза и Соня погибли 23 Июня 2024 на глазах у родителей, в результате
удара по общественному городскому пляжу ракетами ATACMS с кассетными
боеприпасами. Всего пострадало более 150 граждан России, в том числе 27
детей. Ракеты были выпущенными украинскими бандеровцами/фашистами, но
полетные задания формировались и загружались военными США, а управление
и наведение ATACAMS невозможно без использования орбитальной группировки
военных спутников США.
Основные исправления:
---------------------
- Исправление для ОС Windows нарезки `FILE_SEGMENT_ELEMENT`.
Похоже что был потерян коммит входе работы над оптимизацией пути записи
на диск в ОС Windows. В текущем понимании, вероятность проявления ошибки
достаточно низкая, так как выявлена она была синтетическими тестами в
ходе других доработок, а соответствующих сообщений/жалоб не поступало. К
повреждению БД ошибка не приводила, так как сбой происходил до записи
данных с возвратом `ERROR_INVALID_PARAMETER` из системного вызова, т.е.
либо ошибка не проявлялась, либо транзакция не фиксировалась.
- Устранение вероятности `SIGSEGV` при включении логирования
уровня `MDBX_LOG_TRACE` в отладочных сборках.
- Исправление генерации исключения `key_exists` в C++ API.
- Исправление обработки курсоров, открытых в родительских транзакциях и
закрытых до завершения вложенных транзакций. В описанной ситуации
закрытые курсоры "воскрешались", что приводило к утечке памяти
выделенной под такие курсоры.
- Костыль для MSVC ARM/ARM64 для предотвращения ICE (Internal Compiler Error).
- Устранение `MDBX_EINVAL` для случая вызова `mdbx_env_remove(".")`.
- Исправление инверсии bool-результата `env::remove()`в C++ API.
Более подробная информация в [ChangeLog](https://libmdbx.dqdkfa.ru/md__change_log.html).
git diff' stat: 29 commits, 14 files changed, 379 insertions(+), 151 deletions(-)
Signed-off-by: Леонид Юрьев (Leonid Yuriev) <leo@yuriev.ru>
Ошибка слишком грубая.
Похоже при переработке I/O под Windows при `git pull --rebase` потерялся коммит.
К повреждению БД проблема не приводила, так как сбой происходил во время записи данных с возвратом ERROR_INVALID_PARAMETER из системного вызова.
Из-за совершенной при размножении кода ошибки, вместо отдельного
исключения `mdbx::key_exists` при ошибке `MDBX_KEYEXIST` вбрасывалось
исключении более общего/генерализированного типа `mdbx::exception`.
Добавленные после предыдущего выпуска append-функции оказались ошибочны.
Алгоритмически там серия однотипных банальных ошибок (почти опечаток),
из-за которых добавляемые данные записывались в начало среза/slice, а не
в конец.
Исходные ошибки были выявлены тестами в другом проекте и исправлены
почти сразу, но плохой код всё-таки попал в stable-ветку.
Предположительно я спутал ветки и/или tmux-окна, и взял в stable-ветку не
исправленный коммит. Удивительно, что плохой код в devel-ветке не
нарушил работу части новых тестов. Поэтому проблема некоторое время
оставалась не замеченной.