Выпущена версия Vitastor 3.2.0
31.08.2026
Это корректирующий релиз, и большая часть исправлений внесена благодаря новому подходу к тестированию: хаос-тесту блочного хранилища, который теперь запускается в CI при каждом изменении.
Также спасибо Юрию Лунёву из MIND Software за другую часть исправлений.
Новые функции
Кроме хаос-теста и исправлений стабильности, в релиз также входит несколько новых функций:
- Онлайн-изменение размера для ublk, NBD, QEMU и VDUSE, плюс онлайн-расширение на ноде в CSI для
всех типов томов. То есть, размер подключённых устройств теперь меняется автоматически после
vitastor-cli modify --resize. - Хелперы монтирования VitastorFS
mount.vitastorfsиmount.vitastorblk— ФС теперь можно монтировать из/etc/fstab. - Теперь можно настраивать NFS
--readaheadв команде монтирования: увеличение ускоряет чтение в 2-3 раза. - Снова разрешено использование клиента без io_uring (опция
use_sync_send_recv) — при включённом RDMA это ничем не хуже по производительности. - Добавлен обработчик пути
/healthcheckв мониторе. - Серверы NBD, ublk и NFS теперь обрабатывают SIGINT и SIGTERM и завершаются плавно.
- В CSI теперь используются, а в документации VitastorFS предлагаются безопасные
опции монтирования
soft,sync. - В первую очередь это касается старого хранилища, однако: больше не допускаются ситуации,
в которых операции записи могут зависнуть навсегда из-за исчерпании места в журнале. Теперь
в таких случаях хранилище возвращает
EAGAIN, OSD обрабатывают эту ошибку, а обязанность повторить запрос возлагается на клиента. Исправление меняет логику обработки ошибок на стороне клиента, поэтому при использовании старого хранилища рекомендуется обновить клиентов.
Хаос-тестирование
Блочное хранилище теперь покрыто тестом в стиле DST (детерминистический симуляционный тест), управляемым сидом. Хранилище запускается в симулированной среде: io_uring отдаёт завершения не по порядку и со случайной задержкой, энергозависимый кэш диска при симулированном отключении питания теряет случайное подмножество своего содержимого, а записи, летевшие в этот момент, доезжают целиком, частично (рвутся по границе сектора) или не доезжают вовсе. Само хранилище при этом настоящее — журнал, метаданные, флашер, компактизация, контрольные суммы. Рядом ведётся модель записанных данных и после каждого отключения питания восстановленное состояние сверяется с ней, включая битмапы объектов.
Тест запускает обе реализации хранилища на одной и той же нагрузке в 24 конфигурациях: старое и
новое хранилище, серверные и десктопные диски (с конденсаторами и без), двухфазные (EC) и
мгновенные (реплицированные) записи, контрольные суммы выключены / включены с блоком 4 КБ / 16 КБ.
CI прогоняет 200 сидов на каждой сборке, по процессу на сид, и печатает список упавших сидов —
после чего любое падение можно чётко воспроизвести командой test_blockstore_chaos --seed N.
Для понимания масштаба: на хранилище из 3.1.0 текущий хаос-тест падает на 83 сидах из 200 без учёта утечек памяти и строгого запрета одновременной записи одного и того же сектора, а с их учётом - на 97 сидах из 200.
# конфигурация сломано/всего
8 v2 fsync=0 csum=16384 instant 4/9
9 v2 fsync=1 csum=none instant 1/8
10 v2 fsync=1 csum=4096 instant 1/8
12 v1 fsync=0 csum=none two-phase 8/8
13 v1 fsync=0 csum=4096 two-phase 8/8
14 v1 fsync=0 csum=16384 two-phase 8/8
15 v1 fsync=1 csum=none two-phase 8/8
16 v1 fsync=1 csum=4096 two-phase 8/8
17 v1 fsync=1 csum=16384 two-phase 8/8
18 v1 fsync=0 csum=none instant 8/8
19 v1 fsync=0 csum=4096 instant 8/8
20 v1 fsync=0 csum=16384 instant 8/8
21 v1 fsync=1 csum=none instant 1/8
22 v1 fsync=1 csum=4096 instant 3/8
23 v1 fsync=1 csum=16384 instant 8/8
Доминирующие проблемы:
- Старое хранилище: OSD аварийно завершается с
BUG: Unexpected dirty_entry ... unstable state during flush— на каждом сиде всех шести двухфазных (EC) конфигураций — или отказывается стартовать сFatal error (bug): big_write journal_entry was allocated over another object. - Новое хранилище: после отключения питания объект становится нечитаемым с ошибкой контрольной
суммы (
retval=-33), а в одном случае возвращается с данными другого объекта.
Теперь же все эти проблемы исправлены.
Нужно ли обновляться?
- Старое хранилище (
meta_format2, OSD, созданные до 3.0) — да, независимо от железа. Оно падало в хаос-тесте во всех конфигурациях, включая рекомендуемые. - Диски без конденсаторов, десктопные (
immediate_commit=none) — да. В обоих версиях хранилища исправлены значительные баги, связанные с SYNC, такие, как потеря подтверждённых данных при отключении питания. - Контрольные суммы с блоком больше 4 КБ (
csum_block_size) — да, и это касается обоих хранилищ. Чтения частично записанных блоков могли падать с ложной ошибкой контрольной суммы на совершенно целых данных, а у нового хранилища объект мог стать нечитаемым после отключения питания даже на серверных SSD. - Новое хранилище на серверных SSD с конденсаторами, чексуммы выключены или 4 КБ — обновление рекомендуется, но не срочно. Хаос-тест не поймал новое хранилище на падении в этой в конфигурации на 3.1.0, а исправления ниже для неё закрывают более редкие ситуации.
Исправления для конфигурации по умолчанию (серверные SSD, суммы выключены или 4 КБ)
Старое хранилище (meta_format 2):
- При перезапуске после обрыва журнала на записи, находящейся в начале блока, запись журнала продолжалась некорректно, так, что новые записи не учитывались при повторном быстром перезапуске OSD (раньше полного цикла записи всего журнала).
- Порядок нескольких одновременных записей в журнал учитывался некорректно, а значит, запись могла подтвердиться раньше успешного журналирования.
- Две записи одного и того же журнального сектора могли лететь одновременно. Теоретически устройство могло выполнить их в произвольном порядке и повредить журнал.
- Счётчики занятого места объектов и OSD могли уйти в минус после перезапуска.
- При остановке OSD метаданные грязной записи освобождались через free, не будучи указателем и портили кучу. Заодно исправлено несколько утечек памяти; тесты теперь гоняются с включённой проверкой на утечки (ранее в CI проверка была отключена).
- Чтения не работали вообще, вместо этого роняя OSD с ошибкой деления на ноль, при выключенных
контрольных суммах и при выключенном
inmemory_journal. - При выключенном
inmemory_journalнеизменённый журнальный сектор — или даже суперблок журнала — мог быть перезаписан некорректными данными, после чего OSD отказался бы стартовать.
Новое хранилище (meta_format 3):
- При отключении питания во время компактификации могли пропадать объекты с базовой записью типа big_intent, если их данные были мутированы, а метаданные не были обновлены. Для серверных SSD данная ситуация редка, но в теории возможна.
Исправления для дисков без конденсаторов (immediate_commit=none)
Старое хранилище:
- Исправлено несколько зависаний и падений вокруг удалений, откатов и синков — откат версии, под которой лежит более новая незасинканная запись, висел вечно; удаление могло уронить assert во флашере или при записи журнала; удаление одновременно с синком портило внутреннее состояние.
- Старое хранилище: накат журнала мог воскресить устаревшие записи удалённого объекта или отказаться стартовать с “big_write journal_entry was allocated over another object”.
Новое хранилище:
- SYNC мог вернуть успех, ничего не сбросив (#77, спасибо Changwei Ye). Если два клиента синкались одновременно, второй забирал счётчик первого и возвращался сразу, поэтому данные, подтверждённые как засинканные, могли потеряться при отключении питания.
- Запись могла потеряться, а более новая запись того же объекта — уцелеть, и объект оставался на версии, у которой нет предшественника, то есть содержал смесь двух версий. Теперь все ещё не зафиксированные на диске записи одного объекта записываются в тот же метаблок и не могут исчезнуть независимо.
- Объект мог пропасть целиком после перезапуска, если питание пропадало в середине его компактификации.
- Новые запросы записи могли просто зависнуть после перезапуска.
Исправления для блока контрольных сумм больше 4 КБ
Только старое хранилище:
- Чтения частично записанных больших записей сверяли контрольную сумму с данными на диске вместо явного нулевого дополнения, с которым сумма считалась — поэтому чтение могло упасть с ложной ошибкой суммы на целых данных. Без этого исправления падает каждый сид хаос-теста в затронутых конфигурациях.
- Два падения во время компактификации в
fill_partial_checksum_blocks(). - Падение в
read_bitmap()при чтении удалённой версии объекта. - Падения с
assert(fulfilled == read_op->len)вdequeue_read().
Прочие исправления
- PG теперь перепириваются при изменении
pg_minsize. - Исправлен скрипт
make-etcdс IPv4 и автоопределение пула вsnap-create(и то, и то сломано в 3.1.0). vitastor-ddтеперь определяет seekable-ввод и вывод, включая stdin/stdout.- В VitastorFS исправлены смещение cookie в READDIR, переполнение стека при длинном READDIR из кэша, добавлено ограничение размера кэша итераторов.
- Исправлено потенциальное падение при неполном приёме из сокета, в теории в редких
случаях возможном даже с используемым флагом
MSG_WAITALL. - Исправлено падение при инициализации RDMA-CM, когда RDMA-CM недоступен.
- Исправлено падение клиента при отсутствующей конфигурации пула или PG во время выполнения запроса.
- Конфигурации, в которых запись метаданных больше
meta_block_size, теперь отклоняются при инициализации OSD, а не приводят к делению на ноль вvitastor-disk. - Отклоняются вывернутые диапазоны в DESCRIBE; защищён поиск inode при чтении цепочек.
- Также отклоняется
WRITE_STABLEповерх нестабильногоWRITEв старом хранилище (неиспользуемый OSD и с неопределённым поведением). - Исправлено несколько замечаний UBSan и санитайзеров: отрицательные смещения на диске, арифметика с
нулевым указателем,
memsetнулевой длины по NULL, неинициализированная память. - Исправлен ряд краевых случаев в мессенджере: идентификаторы клиентов,
outbox_pushдля уже несуществующего клиента, некорректный начальныйEPOLLINв HTTP-клиенте.
Полный лог коммитов доступен по ссылке на релиз ниже.
Ссылки
- Git: https://git.yourcmc.ru/vitalif/vitastor/releases/tag/v3.2.0
- Инструкции по установке: https://vitastor.io/en/docs/installation/packages.html