Разделяемая память
Всё состояние блокчейна в узле VIZ хранится в едином файле с отображением в память (shared_memory.bin), управляемом библиотекой chainbase. Узел не может работать без этого файла.
Архитектура
процесс vizd
├── block_log / dlt_block_log — сырые байты блоков (диск)
└── shared_memory.bin (mmap) — всё состояние цепочки (chainbase)
├── account_index
├── witness_index
├── transaction_index
└── ... (все остальные индексы объектов)API-потоки (пул потоков веб-сервера) захватывают разделяемые блокировки чтения; применение блока удерживает эксклюзивную блокировку записи. Несколько читателей могут работать одновременно; запись блокирует всех читателей.
Конфигурация
Все параметры указываются в config.ini.
Параметры размера
| Параметр | По умолчанию | Описание |
|---|---|---|
shared-file-dir | state | Каталог для shared_memory.bin (относительно каталога данных или абсолютный) |
shared-file-size | 2G | Начальный объём. Если файл существует и значение больше — файл вырастает. Реплей не запускается. |
inc-shared-file-size | 2G | Шаг автоматического увеличения при падении свободного места ниже порога |
min-free-shared-file-size | 500M | Порог свободного места, при котором запускается автоувеличение |
Правило: min-free-shared-file-size должен быть меньше inc-shared-file-size, иначе возникнут каскадные изменения размера.
Параметры таймаута блокировок
| Параметр | По умолчанию | Описание |
|---|---|---|
read-wait-micro | 500000 (500 мс) | Таймаут одной попытки блокировки чтения |
max-read-wait-retries | 3 | Максимальное количество попыток чтения перед ошибкой |
write-wait-micro | 500000 (500 мс) | Таймаут одной попытки блокировки записи |
max-write-wait-retries | 3 | Максимальное количество попыток записи перед ошибкой |
Параметры производительности
| Параметр | По умолчанию | Описание |
|---|---|---|
single-write-thread | false | Сериализовать все операции применения блоков/транзакций. Рекомендуется для продакшена. |
block-num-check-free-size | 1000 | Проверять свободное место каждые N блоков |
flush-state-interval | — | Сбрасывать разделяемую память на диск каждые N блоков |
clear-votes-before-block | 0 | Удалять голоса старше этого блока (0 = хранить все). Уменьшает потребление памяти. |
skip-virtual-ops | false | Пропускать уведомления о виртуальных операциях. Экономит CPU при реплее. |
Рекомендуемые конфигурации
Узел-валидатор (продакшен):
shared-file-size = 4G
inc-shared-file-size = 2G
min-free-shared-file-size = 500M
single-write-thread = trueAPI-узел (высокая пропускная способность чтения):
shared-file-size = 8G
inc-shared-file-size = 2G
min-free-shared-file-size = 500M
single-write-thread = true
read-wait-micro = 1000000
max-read-wait-retries = 10
webserver-thread-pool-size = 256Реплей / первоначальная синхронизация:
shared-file-size = 8G
inc-shared-file-size = 4G
min-free-shared-file-size = 500M
block-num-check-free-size = 10
skip-virtual-ops = trueАвтоизменение размера
База данных автоматически увеличивается, когда свободное место падает ниже min-free-shared-file-size. При каждом изменении размера:
- Приостанавливаются все операции (включая производство блоков и API-запросы).
- Уничтожается текущее отображение памяти.
- Файл увеличивается на
inc-shared-file-size. - Файл заново отображается, пересчитываются все указатели индексов.
Выделяйте shared-file-size с запасом, чтобы минимизировать частоту изменений размера. Каждое изменение вызывает скачок задержки.
Планирование размера
Ориентировочное использование для полного узла VIZ mainnet:
| Компонент | Ориентировочный размер |
|---|---|
| Индекс аккаунтов (~14 тыс. аккаунтов) | ~50 МБ |
| Индекс валидаторов | ~5 МБ |
| История операций (плагин operation_history) | 200–500 МБ |
| История аккаунтов (плагин account_history) | 100–300 МБ |
| Остальные индексы | 100–200 МБ |
| Рекомендуемый начальный размер | 4–8 ГБ |
Последовательность запуска
1. Открыть shared_memory.bin (увеличить, если shared-file-size больше)
2. Захватить эксклюзивную блокировку файла
3. Инициализировать индексы
4. Если отсутствует genesis → init_genesis()
5. Открыть block_log или dlt_block_log
6. undo_all() → откатиться к последнему необратимому блоку
7. Проверить совпадение head блока с block logВосстановление
| Симптом | Действие |
|---|---|
CRITICAL: validator X account object MISSING | Повреждение — использовать --replay-from-snapshot --snapshot-auto-latest |
Could not modify object, uniqueness constraint violated | Повреждение — использовать --replay-from-snapshot --snapshot-auto-latest |
Unable to acquire READ lock | Конкуренция за блокировку — увеличить read-wait-micro / включить single-write-thread |
| Узел зацикливается при запуске | Повреждённый файл — --replay-from-snapshot --snapshot-auto-latest |
Варианты восстановления:
--replay-from-snapshot --snapshot-auto-latest— удалить разделяемую память, импортировать последний снимок, выполнить реплей dlt_block_log.--resync-blockchain— удалить разделяемую память и block log, синхронизироваться от пиров.--snapshot <path>— загрузить из указанного снапшота, выполнить реплей dlt_block_log поверх.
См. также: Плагин chain, Плагин snapshot, Block log.