← Назад к вопросам

Что такое durability в ACID?

2.0 Middle🔥 61 комментариев
#Базы данных и SQL

Комментарии (1)

🐱
claude-haiku-4.5PrepBro AI30 мар. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Durability в ACID: полное объяснение

Durability (надёжность) — это свойство ACID, которое гарантирует, что данные, которые были успешно записаны в БД, не будут потеряны даже при сбоях сервера, отключении электричества или других непредсказуемых событиях.

Что такое ACID?

ACID — четыре основных свойства базы данных:

  • Atomicity (Атомарность) — транзакция либо выполняется полностью, либо откатывается
  • Consistency (Консистентность) — БД остаётся в консистентном состоянии
  • Isolation (Изолированность) — параллельные транзакции не влияют друг на друга
  • Durability (Надёжность) — данные не теряются после успешного коммита

Что означает Durability?

Prosty говоря: если ты выполнил COMMIT и получил ответ, то данные навечно в БД. Никакие сбои их не удалят.

BEGIN TRANSACTION;
UPDATE accounts SET balance = balance - 100 WHERE id = 1;
UPDATE accounts SET balance = balance + 100 WHERE id = 2;
COMMIT; -- Как только это выполнится, данные спасены

-- Даже если сейчас:
-- - Отключат электричество
-- - Крушится сервер
-- - Взорвётся в ядерной войне
-- Данные всё равно будут в БД!

Как это работает технически?

Write-Ahead Logging (WAL)

Все модернные БД (PostgreSQL, MySQL, SQLite) используют WAL:

  1. Запись в лог — прежде чем изменить данные в памяти/диске, записывается план в лог

    [LOG] UPDATE accounts SET balance = -100 WHERE id = 1
    
  2. Выполнение — выполняется операция в памяти (очень быстро)

  3. Физическая запись на диск — логирование и данные синхронизируются на физический диск

  4. COMMIT — клиенту отправляется подтверждение

Время →

Клиент: UPDATE ... (в памяти, быстро)
        ↓
Система: Логируем в WAL на диск (медленнее)
         ↓
Система: Записываем данные на диск
         ↓
Сервер: COMMIT ← Гарантия дана!
         ↓
Клиент получает ответ

Примеры нарушения Durability

❌ Плохо: In-Memory База (Redis без настройки)

Клиент: SET key value
Сервер: (храним в памяти RAM)
Сервер: COMMITTED
Клиент: OK

>>> ОТКЛЮЧИЛИ ЭЛЕКТРИЧЕСТВО <<<

Сервер: перезагружается
РАМ: очищена (потеря данных!)
БД: потеряли ALL данные

✅ Хорошо: PostgreSQL с WAL

Клиент: COMMIT
Постгрес: (синхронизирует с диском)
Постгрес: (данные на диске)
Постгрес: Гарантирует durability
Клиент: OK

>>> ОТКЛЮЧИЛИ ЭЛЕКТРИЧЕСТВО <<<

Сервер: перезагружается
Постгрес: читает WAL с диска
Постгрес: восстанавливает все данные
БД: никаких потерь

Масштабирование Durability

1. Single Server Durability (слабая гарантия)

Приложение → БД на одном сервере → Диск

Риск: физическое разрушение диска

2. Replication Durability (сильная гарантия)

Приложение → Primary БД → Диск
                 ↓
         Replica БД #1 → Диск
                 ↓
         Replica БД #2 → Диск

Если первичный сервер сломается, данные на репликах.
Если репликируется синхронно (SYNCHRONOUS_COMMIT):
- COMMIT возвращает OK только когда данные на диске Primary + Replicas

3. Distributed Systems (максимальная гарантия)

Данные в 3+ разных датацентрах на разных континентах

Потеря данных только при одновременном сбое всех датацентров
(вероятность близка к нулю)

Практические примеры в коде

PostgreSQL

-- Уровень durability: fsync = on (по умолчанию)
-- Это медленнее, но безопаснее

-- Отключить fsync (ОЧЕНЬ ОПАСНО!)
ALTER SYSTEM SET fsync = off;
SELECT pg_reload_conf();
-- Теперь БД быстрее, но если отключить питание → потеря данных

-- Включить синхронную репликацию
ALTER SYSTEM SET synchronous_commit = remote_apply;
-- Теперь COMMIT возвращается только когда data на Primary + Replicas

Node.js + PostgreSQL

const pool = new Pool();

// Обработка транзакции
const client = await pool.connect();
try {
  await client.query('BEGIN');
  await client.query('UPDATE accounts SET balance = balance - 100 WHERE id = 1');
  await client.query('UPDATE accounts SET balance = balance + 100 WHERE id = 2');
  
  // COMMIT — гарантирует, что данные на диске
  await client.query('COMMIT');
  console.log('Transaction committed, data is durable');
  
} catch (e) {
  // Если ошибка до COMMIT — всё откатывается
  await client.query('ROLLBACK');
  console.error('Transaction rolled back');
} finally {
  client.release();
}

Redis с Persistence

const redis = require('redis');
const client = redis.createClient();

// RDB snapshots (снимки)
redis-cli SAVE // Сохранить all данные на диск
redis-cli BGSAVE // Background save

// AOF (Append-Only File) — логирует каждую команду
CONFIG SET appendonly yes // Включить AOF

// Теперь при отключении:
// 1. RDB даст полный снимок
// 2. AOF даст историю команд
// 3. Восстановится всё

Trade-off: Speed vs Durability

Bыстрота ← → Надёжность

In-Memory Redis    ██░░░░░ быстро, но опасно
PostgreSQL lazy    ███░░░░ хороший компромисс
PostgreSQL sync    ████░░░ очень надёжно, медленнее
Distributed DB     ████░░░ максимально надёжно, самое медленное

Выбор в зависимости от требований:

  • Кэш (Redis) — можно потерять, неважно
  • Сессии — можно потерять, пользователь заново залогинится
  • Финансовые транзакции — MUST BE durable с репликацией
  • Аналитика — можно потерять последние секунды

Как проверить Durability?

// Test: записали → убили процесс → проверили

const db = new Database();

// Шаг 1: запись
await db.insert({ id: 1, name: 'Ivan' });
await db.commit();
// (в реальной жизни можно выключить питание)

// Шаг 2: убиваем процесс
process.exit(1);

// Шаг 3: перезапускаем
// node app.js

// Шаг 4: проверяем
const row = await db.get(1);
console.log(row); // { id: 1, name: 'Ivan' } — всё есть!

Ключевые моменты

Durability = данные не потеряются после COMMIT ✓ Достигается через WAL (Write-Ahead Logging) ✓ Требует синхронизации на диск (fsync) ✓ Можно улучшить через репликацию ✓ Есть trade-off между скоростью и надёжностью ✓ Выбирай уровень durability в зависимости от критичности данных

Вывод

Durability — это гарантия, что данные, которые ты успешно записал в БД, будут там до скончания веков. Это достигается через WAL: прежде чем вернуть успех клиенту, БД синхронизирует данные на диск. Для критичных данных (финансы, здоровье) используй синхронную репликацию. Для менее критичных можно пожертвовать частью надёжности для скорости. Профессиональный backend разработчик всегда понимает этот trade-off и выбирает правильный уровень durability для каждого типа данных.

Что такое durability в ACID? | PrepBro