Питання 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) — зміни вносяться в копію сторінки, при commit-і вказувач перемикається.

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]]