Перейти к содержанию

Change Data Capture — CDC

Раздел 01 · Уровни и общие гарантии

Тип материала: архитектурный разбор. Схемы и примеры иллюстративные, если не указано иное.

Уровень: интеграция изменений source storage. Проверка источников: 2026-11-02.

1. Назначение и решаемая проблема

CDC переносит изменения из authoritative storage в другие системы, не заставляя бизнес-приложение независимо записывать каждую копию. Сценарии: актуализация search index, analytical ingestion, cache invalidation и миграция данных.

CDC фиксирует наблюдаемые изменения данных, а не обязательно бизнес-намерение. Из UPDATE status='settled' не всегда известны причина, quote version и предыдущие решения. Для semantic domain events можно читать специально спроектированный outbox.

2. Принцип работы

Log-based CDC читает committed changes из WAL/binlog/redo или другого поддержанного механизма и сохраняет progress. Initial snapshot даёт baseline существующих строк; coordinated transition к log обеспечивает непрерывность.

Polling по updated_at и trigger-based CDC — другие варианты с отдельными рисками: timestamp ties, deletes, transactional load. Конкретный connector определяет snapshot locks, transaction metadata, before images и restart guarantees. Нельзя приписать всем CDC одинаковый protocol.

3. Архитектурная схема

flowchart TB
    T["OLTP transactions"] --> D["Source tables"]
    T --> L["Committed transaction log"]
    D --> S["Coordinated snapshot"]
    L --> C["CDC connector и durable progress"]
    S --> C
    C --> K["Change topics и schemas"]
    K --> A["Idempotent applier"]
    A --> V["Target tables / search"]
    D -. "Контрольный snapshot" .-> R["Reconciliation"]
    V --> R

4. Walkthrough движения данных

  1. Connector получает согласованный baseline и log position согласно собственному snapshot protocol. Обычный SELECT всех строк плюс «читать log с текущего момента» не является доказанным bootstrap.
  2. Snapshot records маркируются как baseline/read, а не как новые финансовые операции. Sink upsert-ит state по primary key.
  3. Пока snapshot идёт, source продолжает transactions. Connector координирует их с baseline; отдельные режимы допускают duplicates.
  4. Live update/delete сопровождаются source metadata и схемой. Sink учитывает ordering в рамках выбранного key и не воскрешает удалённую строку устаревшим snapshot.
  5. Multi-row source transaction может попасть в несколько topics. Если target должен видеть её атомарно, consumer буферизует/координирует transaction boundary по поддержанной metadata либо использует другую replication strategy.
  6. После restart чтение продолжается с durable position; target dedup/upsert должен выдерживать повтор delivery.
  7. Сверка сверяет key ranges/checksums/versions на сопоставимом source cutoff, не произвольные snapshots разных моментов.

5. Технологии реализации

Debezium + Kafka Connect, database-native replication, Oracle GoldenGate или managed CDC — варианты с разными возможностями. Для PostgreSQL в статье рассматривается контракт Debezium 3.3 и логическое декодирование; deployment/failover capability нужно сверять с версией PostgreSQL и hosting.

Нужны source permissions, replication identity, slot/log retention policy, schema management и target applier. Подключение Schema Registry не доказывает, что новое поле имеет прежний смысл.

6. Консистентность и гарантии обработки

Source transaction commit не равен target commit. Source может иметь serializable transaction, а analytical projection — eventual и даже временно частичную multi-table видимость. Порядок source log не гарантирует глобальный порядок после partitioning и parallel sinks.

FACT: документация Debezium 3.3 предупреждает о возможных duplicate records для отдельных snapshot/restart сценариев. PostgreSQL connector. Поэтому conservative applier design обязан выдерживать повторения. Exactly-once connector-to-broker, если поддержан и правильно настроен, не доказывает external business effect.

Source position нужно интерпретировать по connector contract: один timestamp или один LSN без event/transaction context не универсальный уникальный ID всех изменений.

7. Отказы и восстановление

Сбой Recovery Ограничение
Connector остановился, log сохранён Resume с durable progress Будут lag и возможные duplicates
Log удалён / slot invalidated Новый согласованный snapshot и reconciliation Исходную историю переходов snapshot не возвращает
Schema несовместима с sink Quarantine, version-aware migration, controlled resume Нельзя молча пропускать изменения
Target truncate, offsets сохранены Rebuild target по явной процедуре Продолжение с offset оставит прежние строки отсутствующими
Source failover Проверить continuity slot/position в конкретном setup Новый hostname не гарантирует непрерывность

CDC outage может удерживать WAL на source и угрожать primary disk. Alert по lag и retained log size нужен до исчерпания пространства.

8. Масштабирование и узкие места

Начальный snapshot нагружает source scans/I/O; continuous CDC — log decoding, network и target write amplification. Hot table/key, большое transaction и schema churn увеличивают lag. Увеличение sink parallelism не ускоряет single ordered transaction без изменения semantics.

Snapshot chunks и incremental режимы выбирать по connector documentation. Backfill rate ограничивать, сохраняя headroom OLTP. Retention рассчитывать на detection + outage + restore, а не только на обычный lag.

9. Преимущества и недостатки

Плюсы: меньше application integration changes, capture committed data, подходит для brownfield. Минусы: связь со storage schema, сложный bootstrap, permissions/log operations и необходимость target reconciliation.

CDC удобен как мост из legacy. Для публичного domain contract лучше преобразовать technical changes в owner-managed integration events; преобразование требует доменных знаний и может потерять смысл, если его нет в source.

10. Альтернативные решения

Application events через Outbox дают контролируемый semantic contract; CDC может быть relay этого outbox. Event Sourcing хранит authoritative facts с другой целью. Batch snapshot проще при допустимой freshness и небольшом source. Timestamp polling ограничен delete/ordering semantics.

Event Sourcing vs CDC показывает, когда оба механизма применяются одновременно.

11. Реальные примеры и границы подтверждения

FACT: Uber DBEvents (2019-03-14) описывает bootstrap и incremental ingestion в data lake. Uber.

FACT: BEC/Scoutz в slides Current London 2025 показывают DB2 CDC/outbox и отдельную data reconciliation, включая ручные изменения в source как причину расхождений. PDF, pages 32–34.

UNKNOWN: ни один из этих материалов не доказывает одну общую exactly-once гарантию для произвольного downstream sink.

12. Применение в FinTech и iGaming

FinTech: banking CDC из core OLTP в analytics, screening inputs и reporting, с masking/tokenization и строгим доступом к PII. Snapshot не трактуется как повторное проведение платежей.

iGaming: replication bet/market records для истории и аналитики. Corrected settlement должен сохранять business revision; CDC current state без истории не позволяет восстановить все финансовые последствия отмены payout.

13. Типичные ошибки проектирования

  • Стартовать snapshot и log независимо, не согласовав границу.
  • Принять snapshot row за команду повторного payout.
  • Доверять arrival order после repartitioning.
  • Удалить replication slot при incident без оценки recovery.
  • Использовать CDC table schema как неизменяемый публичный contract.
  • Считать совпавшее количество строк доказательством одинаковых данных.

14. Вопросы технического интервью с ответами

Почему snapshot не заменяет replay? Он восстанавливает состояние на срезе, но не обязательно последовательность переходов и side effects.

Как перенести multi-table atomicity? Нужна поддержанная transaction metadata и target-side protocol либо соответствующая replication technology. Parallel topics сами её не сохраняют.

Что делать после потери WAL? Оценить gap, восстановить baseline из source/backup и сверить target. Не объявлять отсутствие потерь на основании restart success.

15. Практическое упражнение

HYPOTHETICAL: во время snapshot строка a меняется v1→v2 и затем удаляется. Сконструируйте ошибочную последовательность «delete, затем старый snapshot v1» и корректный bootstrap protocol на уровне требований.

Критерий: target не содержит a после сходимости; duplicate update безопасен; потеря log зафиксирована как отдельный recovery scenario. Объясните, какие connector settings и source versions нужно будет проверить перед integration test.

Дополнительные источники

Debezium PostgreSQL 3.3; BEC slides; Uber DBEvents.