From d511e347dfaf77d520c45dfec9608f5ca29a2a0c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=93=D1=80=D0=B8=D0=B3=D0=BE=D1=80=D0=B8=D0=B9=20=D0=A1?= =?UTF-8?q?=D0=B0=D1=84=D1=80=D0=BE=D0=BD=D0=BE=D0=B2?= Date: Tue, 6 Oct 2026 21:58:56 +0000 Subject: [PATCH] Update README.md --- README.md | 41 +++++++++++++++-------------------------- 1 file changed, 15 insertions(+), 26 deletions(-) diff --git a/README.md b/README.md index b381470..63534e9 100644 --- a/README.md +++ b/README.md @@ -946,16 +946,14 @@ futriix:~> db.startSession() ## Batch -В СУБД **futriix** для обеспечения надёжности (durability), атомарности и быстрого восстановления базы данных реализована двухуровневая система журналирования: +В СУБД **futriix** для обеспечения надёжности (durability), атомарности и быстрого восстановления базы данных реализована система журналирования на основе **WAL (Write-Ahead Log)**. -1. **WAL (Write-Ahead Log)** — сегментированный журнал предзаписи для **batch-операций** (атомарных групп изменений). По умолчанию хранится в каталоге `futriix/wal_segments/`. -2. **AOF (Append-Only File)** — журнал дозаписи для **одиночных мутаций**, выполненных вне batch (прямые вызовы `Insert`, `Update`, `Delete`, `Restore`, а также операции из REPL, HTTP-API и Lua-плагинов). По умолчанию хранится в каталоге `futriix/aof/`. +Все мутации — как групповые (batch), так и одиночные (прямые вызовы `Insert`, `Update`, `Delete`, `Restore` из REPL, HTTP-API и Lua-плагинов) — проходят через WAL. Это даёт: -Такое разделение даёт: - **Атомарность** для сложных составных операций (batch). -- **Гарантированную сохранность** каждой отдельной мутации (AOF). -- **Быстрое восстановление** через воспроизведение обоих журналов при старте. -- **Разделение нагрузки**: batch-операции пишутся в WAL сегментами по 64 МБ, одиночные мутации — в AOF с ротацией по 64 МБ. +- **Гарантированную сохранность** каждой отдельной мутации. +- **Быстрое восстановление** через воспроизведение WAL при старте. +- **Единый источник истины** — один журнал, один fsync-путь, один формат хранения. ### Что такое Batch @@ -968,7 +966,6 @@ futriix:~> db.startSession() - **Откат при ошибке применения**: если операция падает на середине применения, уже применённые операции откатываются (best-effort) — полная атомарность гарантируется на уровне WAL при восстановлении. - **Короткое время жизни**: batch создаётся, наполняется операциями и коммитится в рамках одной логической операции. Не поддерживает savepoints, таймауты, распределённую координацию. - **Реестр активных batch'ей**: `BatchManager.activeBatches` (см. `runtime_limits.go`) защищает документы, участвующие в незакоммиченном batch, от вытеснения (eviction) при нехватке памяти. -- **AOF-дублирование**: после коммита batch также пишется в AOF для ускорения восстановления. **Операции batch:** @@ -982,27 +979,19 @@ futriix:~> db.startSession() | `batch.Commit()` | Применить batch атомарно через WAL | -### Что такое AOF +### Как WAL обеспечивает durability -**AOF (Append-Only File)** — журнал дозаписи, который логирует **каждую отдельную мутацию**, выполненную вне batch. Это нужно, потому что прямые вызовы `coll.Insert()`, `coll.Update()`, `coll.Delete()` идут мимо WAL, и без AOF такие изменения могли бы потеряться при сбое. +**WAL (Write-Ahead Log)** — сегментированный журнал предзаписи, который является **единственным источником истины** для durability. Каждая мутация сначала попадает в WAL, синхронизируется на диск, и только потом применяется к in-memory структурам. -**Ключевые свойства AOF:** +**Ключевые свойства WAL:** -- **Формат**: JSON-lines (по одной JSON-записи на строку) с CRC32 для верификации целостности. -- **Ротация**: файлы разбиваются по размеру 64 МБ, имена вида `aof_.log`. -- **fsync**: каждая запись синхронизируется с диском через `file.Sync()` для гарантии сохранности. -- **Восстановление при старте**: `ReplayAOF(storage)` читает все файлы и применяет операции к хранилищу. -- **Идемпотентность**: повторное применение операции не ломает состояние (insert/update/delete идемпотентны по ключу). -- **Автоматическое логирование**: методы `Collection.Insert`, `Update`, `Delete`, `PermanentDelete`, `RestoreDeleted` вызывают `LogAOFInsert`, `LogAOFUpdate`, `LogAOFDelete`, `LogAOFRestore` соответственно. - -**Типы записей AOF:** - -| Тип | Описание | -|-----|----------| -| `insert` | Вставка документа | -| `update` | Обновление документа | -| `delete` | Удаление документа (soft или permanent) | -| `restore` | Восстановление мягко удалённого документа | +- **Сегментация**: файлы `wal_segment_.log` разбиваются по 64 МБ с автоматической ротацией. +- **fsync на запись**: каждая запись (или группа записей в рамках `flushBatch`) синхронизируется с диском через `file.Sync()`. +- **CRC32 per record**: каждая запись защищена контрольной суммой, включающей LSN — обнаружение частичных/torn-записей при восстановлении. +- **WAL Index**: индекс `wal_index_.json` для быстрого поиска записей по LSN. +- **Pipeline записи**: группировка нескольких команд в один fsync-цикл (`flushBatch`) для снижения накладных расходов. +- **Восстановление при старте**: `ReadAll()` читает все сегменты, применяет операции к хранилищу; это единственный путь восстановления. +- **Идемпотентность**: повторное применение операции не ломает состояние. ---