Вопрос 1 · Раздел 11

Расшифруйте каждую букву ACID

Транзакция выполняется целиком или не выполняется вовсе. Либо все изменения сохраняются, ни одного.

Версии по языкам: English Russian Ukrainian

🟢 Junior Level

ACID — это набор из четырёх свойств, которые гарантируют надёжную обработку транзакций в базе данных.

A — Atomicity (Атомарность)

Транзакция выполняется целиком или не выполняется вовсе. Либо все изменения сохраняются, ни одного.

Пример: При переводе денег с одного счёта на другой должны произойти две операции: списание с первого счёта и зачисление на второй. Если вторая операция завершается с ошибкой — СУБД использует undo log (журнал старых значений), чтобы откатить первую операцию.

C — Consistency (Согласованность)

Транзакция переводит базу данных из одного корректного состояния в другое.

Корректное состояние = все ограничения (FOREIGN KEY, UNIQUE, CHECK, NOT NULL) выполнены. Если хотя бы одно нарушено — состояние некорректное, и СУБД откатит транзакцию.

Пример: Если в базе есть ограничение, что баланс не может быть отрицательным, транзакция не сможет записать отрицательный баланс.

I — Isolation (Изолированность)

Параллельные транзакции не должны влиять друг на друга. Каждая транзакция должна работать так, будто она одна.

Пример: Если два человека одновременно переводят деньги с одного счёта, результаты не должны перемешаться.

D — Durability (Долговечность)

После подтверждения транзакции (COMMIT) изменения сохраняются навсегда, даже если сервер внезапно выключится.


🟡 Middle Level

Как ACID реализуется на практике

Atomicity обеспечивается через логи транзакций:

  • Перед изменением данных СУБД записывает старые значения в undo log
  • Если транзакция отменяется (ROLLBACK), система восстанавливает данные из лога
  • Если происходит сбой питания, redo log помогает восстановить committed транзакции

Consistency работает на двух уровнях:

  • Database-level: FOREIGN KEY, UNIQUE, CHECK ограничения, типы данных
  • Application-level: Бизнес-правила, которые разработчик должен обеспечить сам (например, сумма переводов должна быть равна общей сумме)

Isolation реализуется через:

  • Pessimistic Locking: Явные блокировки строк (SELECT FOR UPDATE)
  • MVCC (Multi-Version Concurrency Control) — СУБД хранит несколько версий одной строки одновременно. Каждая версия привязана к ID транзакции, которая её создала. Благодаря этому читатели не блокируют писателей.

Durability обеспечивается через:

  • Write-Ahead Logging (WAL): Данные сначала пишутся в лог на диск, потом в файлы данных.

Зачем: если сервер упадёт после COMMIT, но до записи в основной файл данных, WAL позволит восстановить изменения при перезапуске.

  • fsync(): Гарантирует физическую запись на диск, а не в кэш ОС
  • Group Commit: Группировка нескольких подтверждений в одну дисковую операцию

Типичные ошибки

  • Путать Consistency (из ACID) с консистентностью в распределённых системах (CAP theorem)
  • Думать, что Isolation означает полное отсутствие влияния — на уровнях ниже Serializable аномалии возможны

🔴 Senior Level

Глубокое понимание механизмов реализации

Atomicity — Internal Implementation

  • Undo Log / Redo Log: В PostgreSQL используется WAL (Write-Ahead Log). Все изменения сначала записываются WAL, затем в data files. При crash recovery WAL replay восстанавливает committed транзакции через redo, а uncommitted откатываются через undo information, хранящееся в самих страницах (heap tuples).
  • Shadow Paging: Альтернативный подход (SQLite, Firebird) — изменения вносятся в копию страницы, при коммите указатель переключается.

Consistency — Beyond Constraints

  • В распределённых системах ACID-согласованность противопоставляется Eventual Consistency (CAP theorem)
  • Application-level invariants: БД не знает, что сумма переводов между счетами должна оставаться неизменной — это ответственность разработчика
  • Deferred constraints: PostgreSQL позволяет отложить проверку constraints до конца транзакции (DEFERRABLE)

Isolation — MVCC Deep Dive

  • PostgreSQL MVCC: Каждая строка хранит xmin и xmax — transaction IDs, которые определяют видимость. Читатели не блокируют писателей и наоборот.

Актуально для PostgreSQL 14-16. Детали реализации могут меняться между мажорными версиями.

  • PostgreSQL SSI (Serializable Snapshot Isolation): Начиная с 9.1, PostgreSQL использует SSI для Serializable уровня. Система отслеживает read/write dependencies и при обнаружении конфликта прерывает транзакцию с ошибкой serialization failure.
  • Trade-off: Идеальная изоляция (Serializable) обходится дорого. Большинство систем работают на Read Committed, допуская определённые аномалии.

Durability — Production Nuances

  • synchronous_commit = off в PostgreSQL повышает throughput, но создаёт риск потери ~0.5-1 сек данных при crash
  • fsync() overhead: На некоторых SSD/fsync может быть дорогим. Важно учитывать при benchmarking
  • Group Commit: Оптимизация, группирующая несколько транзакций в одну I/O операцию для снижения overhead
  • Battery-backed RAID controllers: В enterprise-средах аппаратные контроллеры с батареями гарантируют durability даже без fsync

Performance Trade-offs

  • Отключение synchronous_commit даёт 2-5x throughput, но с риском потери данных
  • MVCC требует хранения multiple row versions → table bloat → VACUUM overhead
  • Serializable уровень требует retry logic в приложении

Production Recommendations

  • Для большинства use cases: Read Committed + правильная обработка ошибок
  • Для финансовых транзакций: Serializable с retry logic
  • Мониторить txid exhaustion в PostgreSQL (32-bit transaction IDs)
  • Настраивать autovacuum aggressively для предотвращения bloat при высокой write нагрузке

🎯 Шпаргалка для интервью

Обязательно знать:

  • ACID = Atomicity, Consistency, Isolation, Durability — 4 свойства надёжных транзакций
  • Atomicity = всё или ничего, реализуется через undo/redo log
  • Consistency = переход из одного валидного состояния в другое (constraints + application invariants)
  • Isolation = параллельные транзакции не влияют друг на друга (MVCC, locks)
  • Durability = COMMIT = данные сохранены навсегда (WAL, fsync)
  • MVCC — ключевой механизм: PostgreSQL хранит xmin/xmax на каждую строку
  • Durability обеспечивается Write-Ahead Logging: сначала лог на диск, потом данные
  • На Serializable уровень в PostgreSQL используется SSI (Serializable Snapshot Isolation) с отслеживанием RW-dependencies

Частые уточняющие вопросы:

  • Чем Consistency в ACID отличается от Consistency в CAP? — ACID Consistency = constraints БД, CAP Consistency = все ноды видят одни данные
  • Что будет при сбое питания после COMMIT? — WAL replay восстановит данные при перезапуске
  • Почему PostgreSQL MVCC не требует блокировок при чтении? — Каждая строка имеет версии, привязанные к transaction ID
  • Что такое Deferred Constraints? — Constraints, проверка которых откладывается до COMMIT (DEFERRABLE в PostgreSQL)

Красные флаги (НЕ говорить):

  • “Consistency в ACID — это то же самое, что eventual consistency” — это разные концепции
  • “Isolation означает полное отсутствие влияния транзакций” — на уровнях ниже Serializable аномалии возможны
  • “Durability = данные сразу на диск” — сначала WAL, потом async flush в data files

Связанные темы:

  • [[2. Какие уровни изоляции транзакций существуют]]
  • [[11. Какой уровень изоляции по умолчанию в PostgreSQL]]
  • [[18. Что такое rollback в транзакциях]]
  • [[6. Что такое Serializable]]