Перейти к содержанию
Learning Platform
Troubleshooting
Глоссарий

Глоссарий — Debezium CDC

Справочник ключевых терминов курса Debezium CDC.

5 категорий · 27 терминов

PostgreSQL

WAL

Write-Ahead Log
Термин

Журнал упреждающей записи — механизм ACID-гарантий в PostgreSQL. Все изменения сначала записываются в WAL, затем применяются к данным. Debezium читает WAL через логическую репликацию для захвата изменений без нагрузки на production базу.

Пример:
-- Просмотр текущей позиции WAL
SELECT pg_current_wal_lsn();
-- Результат: 0/16B9F08

-- Размер несинхронизированного WAL
SELECT pg_wal_lsn_diff(
  pg_current_wal_lsn(),
  confirmed_flush_lsn
) FROM pg_replication_slots
WHERE slot_name = 'debezium';
Подробнее в уроках:

LSN

Log Sequence Number
Термин

Уникальный идентификатор позиции в WAL. Используется для отслеживания прогресса репликации и определения лага. Формат: 16/3E8A0F00 где первая часть — номер файла WAL, вторая — смещение внутри файла.

Пример:
-- Текущий LSN
SELECT pg_current_wal_lsn();
-- Результат: 0/16B9F08

-- LSN в числовом формате (для расчёта лага)
SELECT pg_wal_lsn_diff('0/16B9F08', '0/16B9E00');
-- Результат: 264 байта
Подробнее в уроках:

Replication Slot

Слот репликации
Термин

Механизм PostgreSQL для отслеживания прогресса логической репликации. Слот гарантирует, что WAL-сегменты не будут удалены до тех пор, пока Debezium их не прочитает. КРИТИЧНО: неиспользуемые слоты приводят к переполнению диска.

Пример:
-- Просмотр активных слотов
SELECT slot_name, active, restart_lsn,
       confirmed_flush_lsn
FROM pg_replication_slots;

-- Создание слота для Debezium
SELECT pg_create_logical_replication_slot(
  'debezium',
  'pgoutput'
);

-- Удаление слота (потеря позиции!)
SELECT pg_drop_replication_slot('debezium');
Подробнее в уроках:

Logical Decoding

Логическое декодирование
Термин

Механизм PostgreSQL для извлечения изменений из WAL в читаемом формате. Logical decoding преобразует низкоуровневые WAL-записи в структурированные события (INSERT, UPDATE, DELETE) с именами таблиц и значениями полей. Debezium использует logical decoding через плагин pgoutput.

Пример:
-- Проверка доступных плагинов
SELECT * FROM pg_available_extensions
WHERE name = 'pgoutput';

-- Создание слота с плагином декодирования
SELECT pg_create_logical_replication_slot(
  'test_slot',
  'pgoutput'
);

-- Чтение изменений (для тестирования)
SELECT * FROM pg_logical_slot_peek_changes(
  'test_slot',
  NULL,
  NULL
);
Подробнее в уроках:

Publication

Публикация
Термин

Объект PostgreSQL, который определяет набор таблиц для логической репликации. Publication указывает, какие таблицы и операции (INSERT/UPDATE/DELETE) должны реплицироваться. Debezium автоматически создаёт publication для указанных таблиц.

Пример:
-- Создание publication для всех таблиц
CREATE PUBLICATION dbz_publication
FOR ALL TABLES;

-- Publication для конкретных таблиц
CREATE PUBLICATION dbz_publication
FOR TABLE customers, orders;

-- Только INSERT и UPDATE (без DELETE)
CREATE PUBLICATION dbz_publication
FOR TABLE customers
WITH (publish = 'insert, update');

-- Просмотр publications
SELECT * FROM pg_publication;
Подробнее в уроках:

pgoutput

Плагин pgoutput
Термин

Встроенный плагин PostgreSQL для logical decoding (с версии 10+). pgoutput — нативный плагин, который не требует отдельной установки, в отличие от decoderbufs (или discontinued wal2json). Debezium по умолчанию использует pgoutput для максимальной совместимости.

Пример:
-- PostgreSQL config для pgoutput
wal_level = logical
max_replication_slots = 4
max_wal_senders = 4

-- Connector config
{
  "plugin.name": "pgoutput",
  "publication.name": "dbz_publication"
}

-- Проверка использования pgoutput
SELECT slot_name, plugin
FROM pg_replication_slots;
-- Результат: debezium | pgoutput
Подробнее в уроках:

MySQL

Binlog

Binary Log
Термин

Бинарный лог MySQL, который записывает все изменения данных для репликации и восстановления. Debezium читает binlog для захвата CDC событий. Формат может быть STATEMENT, ROW или MIXED (только ROW поддерживается Debezium).

Пример:
-- Проверка включения binlog
SHOW VARIABLES LIKE 'log_bin';

-- Текущая позиция binlog
SHOW MASTER STATUS;

-- Список binlog файлов
SHOW BINARY LOGS;

-- Установка retention периода
SET GLOBAL expire_logs_days = 7;
SET GLOBAL binlog_expire_logs_seconds = 604800;
Подробнее в уроках:

GTID

Global Transaction Identifier
Термин

Глобальный идентификатор транзакции в MySQL. GTID упрощает репликацию и восстановление, делая позицию в binlog независимой от конкретного файла. Формат: server_uuid:transaction_id (например, 3E11FA47-71CA-11E1-9E33-C80AA9429562:23).

Пример:
-- Проверка включения GTID
SHOW VARIABLES LIKE 'gtid_mode';

-- Текущий executed GTID set
SHOW MASTER STATUS;

-- GTID purged (удаленные binlog)
SHOW GLOBAL VARIABLES LIKE 'gtid_purged';

server_id

Идентификатор сервера MySQL
Термин

Уникальный идентификатор MySQL сервера в топологии репликации. Каждый сервер (master, slave, Debezium) должен иметь уникальный server_id. Debezium использует server_id для идентификации себя как replica и для чтения binlog.

Пример:
-- Просмотр текущего server_id
SHOW VARIABLES LIKE 'server_id';

-- my.cnf конфигурация
[mysqld]
server-id = 1
log-bin = mysql-bin
binlog_format = ROW

-- Connector config
{
  "database.server.id": "184054",
  "database.hostname": "mysql",
  "database.port": "3306"
}

binlog_format

Формат binlog
Термин

Формат записи изменений в binlog. Может быть STATEMENT (SQL-запросы), ROW (изменённые строки) или MIXED. Debezium поддерживает ТОЛЬКО binlog_format=ROW, так как только ROW-формат содержит полные значения полей до и после изменения.

Пример:
-- Проверка формата binlog
SHOW VARIABLES LIKE 'binlog_format';

-- my.cnf конфигурация (обязательно для Debezium)
[mysqld]
binlog_format = ROW
binlog_row_image = FULL

-- Изменение в runtime (требует SUPER привилегии)
SET GLOBAL binlog_format = 'ROW';

binlog_row_image

Объём данных в ROW событии
Термин

Параметр MySQL, определяющий, какие колонки записываются в binlog при UPDATE. Может быть FULL (все колонки), MINIMAL (только PK и изменённые), NOBLOB (без BLOB/TEXT). Debezium требует FULL для получения complete before/after state.

Пример:
-- Проверка binlog_row_image
SHOW VARIABLES LIKE 'binlog_row_image';

-- my.cnf конфигурация
[mysqld]
binlog_row_image = FULL

-- MINIMAL (экономит место, но Debezium не увидит неизменённые поля)
binlog_row_image = MINIMAL

-- Пример события с FULL
UPDATE users SET email = '[email protected]' WHERE id = 1;
-- Binlog содержит: id, name, email (до и после)

Kafka

Topic

Топик Kafka
Термин

Категория или поток сообщений в Kafka. Debezium создаёт отдельный топик для каждой таблицы (по умолчанию формат: server_name.schema_name.table_name). Топики делятся на партиции для параллельной обработки.

Пример:
# Список топиков Debezium
kafka-topics --list --bootstrap-server localhost:9092 \
  | grep dbserver1

# Информация о топике
kafka-topics --describe \
  --topic dbserver1.inventory.customers \
  --bootstrap-server localhost:9092

# Чтение сообщений из топика
kafka-console-consumer \
  --bootstrap-server localhost:9092 \
  --topic dbserver1.inventory.customers \
  --from-beginning

Offset

Смещение Kafka
Термин

Уникальный последовательный идентификатор сообщения внутри партиции. Consumer отслеживает offset для управления позицией чтения. Debezium хранит свой offset отдельно для отслеживания прогресса репликации из базы данных.

Пример:
# Просмотр текущих offset consumer group
kafka-consumer-groups --describe \
  --group connect-cluster \
  --bootstrap-server localhost:9092

# Сброс offset для повторного чтения
kafka-consumer-groups --reset-offsets \
  --group connect-cluster \
  --topic dbserver1.inventory.customers \
  --to-earliest --execute
Подробнее в уроках:

Partition

Партиция Kafka
Термин

Физическое разделение топика для параллельной обработки и масштабирования. Каждая партиция — упорядоченный лог сообщений. Debezium по умолчанию использует primary key таблицы как ключ партиционирования для сохранения порядка событий одной записи.

Пример:
# Создание топика с 3 партициями
kafka-topics --create \
  --topic dbserver1.inventory.orders \
  --partitions 3 \
  --replication-factor 2 \
  --bootstrap-server localhost:9092

# Просмотр партиций топика
kafka-topics --describe \
  --topic dbserver1.inventory.orders \
  --bootstrap-server localhost:9092

# Connector config - партиционирование по user_id
{
  "transforms": "partitionByUser",
  "transforms.partitionByUser.type":
    "org.apache.kafka.connect.transforms.ValueToKey",
  "transforms.partitionByUser.fields": "user_id"
}

Consumer Group

Группа потребителей
Термин

Группа Kafka consumers, которые совместно читают сообщения из топика. Каждая партиция читается только одним consumer в группе, что обеспечивает параллельную обработку без дублирования. Kafka Connect создаёт consumer group для каждого коннектора.

Пример:
# Список consumer groups
kafka-consumer-groups --list \
  --bootstrap-server localhost:9092

# Детали группы (offset, lag)
kafka-consumer-groups --describe \
  --group connect-debezium-postgres \
  --bootstrap-server localhost:9092

# Результат:
# GROUP       TOPIC         PARTITION  OFFSET  LAG
# connect-... customers     0          1523    0
# connect-... customers     1          1498    0
# connect-... orders        0          5832    12
Подробнее в уроках:

Debezium

Snapshot

Снимок данных
Термин

Начальная полная копия данных из таблицы перед началом потоковой репликации. Debezium делает consistent snapshot без блокировки записей (через MVCC в PostgreSQL или с использованием LOCK TABLES в MySQL).

Пример:
// Connector config - snapshot mode
{
  "snapshot.mode": "initial",
  // Полный snapshot при первом запуске

  "snapshot.mode": "never",
  // Пропустить snapshot, только streaming

  "snapshot.mode": "schema_only",
  // Только структура таблиц, данные не копируются

  "snapshot.mode": "when_needed"
  // Snapshot если offset не найден
}
Подробнее в уроках:

Streaming

Потоковая репликация
Термин

Режим непрерывного чтения изменений из WAL (PostgreSQL) или binlog (MySQL). После завершения snapshot Debezium переключается в streaming mode и читает только новые изменения в реальном времени с минимальной задержкой.

Пример:
// Connector status - streaming phase
{
  "name": "inventory-connector",
  "connector": {
    "state": "RUNNING",
    "worker_id": "kafka-connect:8083"
  },
  "tasks": [{
    "id": 0,
    "state": "RUNNING",
    "worker_id": "kafka-connect:8083"
  }],
  "type": "source"
}
Подробнее в уроках:

Connector

Коннектор Debezium
Термин

Kafka Connect source connector, который интегрируется с конкретной базой данных (PostgreSQL, MySQL, MongoDB и др.). Коннектор читает изменения через нативные механизмы репликации и публикует события в Kafka.

Пример:
# Создание коннектора через REST API
curl -X POST http://localhost:8083/connectors \
  -H "Content-Type: application/json" \
  -d @postgres-connector.json

# Проверка статуса
curl http://localhost:8083/connectors/inventory-connector/status

# Удаление коннектора
curl -X DELETE \
  http://localhost:8083/connectors/inventory-connector
Подробнее в уроках:

SMT

Single Message Transform
Термин

Легковесные преобразования Kafka Connect, которые применяются к каждому событию перед записью в Kafka. SMT позволяют фильтровать поля, переименовывать топики, маршрутизировать события без написания отдельного приложения.

Пример:
// Connector config - фильтрация полей
{
  "transforms": "unwrap,addPrefix",

  // Debezium Unwrap - извлечь только 'after'
  "transforms.unwrap.type":
    "io.debezium.transforms.ExtractNewRecordState",
  "transforms.unwrap.drop.tombstones": false,

  // Добавить префикс к топику
  "transforms.addPrefix.type":
    "org.apache.kafka.connect.transforms.RegexRouter",
  "transforms.addPrefix.regex": "(.*)",
  "transforms.addPrefix.replacement": "cdc.$1"
}

Outbox Pattern

Паттерн Outbox
Термин

Микросервисный паттерн для надёжной публикации событий. При изменении entity приложение также вставляет событие в outbox таблицу в той же транзакции. Debezium читает outbox таблицу и публикует события в Kafka, гарантируя атомарность обновления и публикации.

Пример:
-- Outbox таблица
CREATE TABLE outbox (
  id UUID PRIMARY KEY,
  aggregatetype VARCHAR(255) NOT NULL,
  aggregateid VARCHAR(255) NOT NULL,
  type VARCHAR(255) NOT NULL,
  payload JSONB NOT NULL
);

-- Бизнес-логика (атомарная транзакция)
BEGIN;
  UPDATE orders SET status = 'PAID' WHERE id = 123;
  INSERT INTO outbox (id, aggregatetype, aggregateid, type, payload)
  VALUES (gen_random_uuid(), 'Order', '123', 'OrderPaid',
          '{"orderId": 123, "amount": 99.99}'::jsonb);
COMMIT;

// Debezium Outbox SMT
{
  "transforms": "outbox",
  "transforms.outbox.type":
    "io.debezium.transforms.outbox.EventRouter"
}

Heartbeat

События heartbeat
Термин

Периодические события, которые Debezium отправляет в Kafka даже при отсутствии изменений в базе данных. Heartbeat предотвращают удаление binlog/WAL на неактивных таблицах и позволяют отслеживать, что коннектор жив.

Пример:
// Connector config - heartbeat каждые 5 минут
{
  "heartbeat.interval.ms": 300000,
  "heartbeat.topics.prefix": "__debezium-heartbeat",

  // Heartbeat событие
  {
    "ts_ms": 1686500577691,
    "source": {
      "connector": "postgresql",
      "name": "dbserver1",
      "lsn": 33023704
    }
  }
}

// Проверка heartbeat топика
kafka-console-consumer \
  --topic __debezium-heartbeat.dbserver1 \
  --bootstrap-server localhost:9092
Подробнее в уроках:

Tombstone

Tombstone событие
Термин

Событие Kafka с null значением, которое используется для удаления ключа при log compaction. Debezium отправляет tombstone после DELETE события, чтобы при compaction топика запись была полностью удалена.

Пример:
// DELETE события от Debezium

// 1. DELETE событие (op='d')
{
  "before": {"id": 123, "name": "John"},
  "after": null,
  "op": "d"
}

// 2. Tombstone (следует сразу после)
{
  "key": {"id": 123},
  "value": null  // <- tombstone
}

// Connector config - управление tombstones
{
  "transforms": "unwrap",
  "transforms.unwrap.type":
    "io.debezium.transforms.ExtractNewRecordState",
  "transforms.unwrap.drop.tombstones": false
}

General CDC

CDC

Change Data Capture
Термин

Паттерн захвата изменений данных в реальном времени. Вместо опроса (polling) базы данных, CDC читает журналы транзакций (WAL, binlog) для получения событий INSERT, UPDATE, DELETE с минимальной задержкой и нагрузкой.

Пример:
// CDC Event Structure (Debezium JSON)
{
  "before": null,  // Состояние до изменения
  "after": {       // Новое состояние
    "id": 1001,
    "name": "John Doe",
    "email": "[email protected]"
  },
  "source": {
    "version": "3.4.0.Final",
    "connector": "postgresql",
    "name": "dbserver1",
    "ts_ms": 1486500577691,
    "db": "inventory",
    "schema": "public",
    "table": "customers",
    "lsn": 33023704
  },
  "op": "c",  // c=create, u=update, d=delete, r=read
  "ts_ms": 1486500584591
}
Подробнее в уроках:

Schema Registry

Реестр схем
Термин

Централизованный сервис для хранения и версионирования схем Avro/Protobuf/JSON Schema. При использовании с Debezium позволяет эффективно сериализовать события и обеспечивает совместимость при эволюции схем таблиц.

Пример:
# Просмотр зарегистрированных схем
curl http://localhost:8081/subjects

# Получение схемы для топика
curl http://localhost:8081/subjects/\
dbserver1.inventory.customers-value/versions/latest

# Connector config с Schema Registry
{
  "value.converter": "io.confluent.connect.avro.AvroConverter",
  "value.converter.schema.registry.url":
    "http://schema-registry:8081"
}

Idempotency

Идемпотентность
Термин

Свойство операции, при котором повторное применение даёт тот же результат, что и однократное. В CDC критично для обработки дубликатов событий (при retry, rebalance). Consumer должен корректно обрабатывать повторную доставку того же события.

Пример:
// НЕ идемпотентная операция
UPDATE accounts SET balance = balance + 100
WHERE id = 123;
// Повторное применение = двойное начисление!

// Идемпотентная операция (event sourcing)
INSERT INTO account_events (account_id, type, amount, event_id)
VALUES (123, 'CREDIT', 100, 'evt-456')
ON CONFLICT (event_id) DO NOTHING;
// Повторное применение = игнорируется

// Debezium + Kafka idempotent producer
{
  "producer.enable.idempotence": true,
  "producer.max.in.flight.requests.per.connection": 5
}

Exactly-Once

Ровно один раз
Термин

Гарантия доставки сообщения, при которой каждое событие обрабатывается ровно один раз без потерь и дубликатов. В Kafka достигается через idempotent producer и transactional API. По умолчанию Debezium + Kafka обеспечивают at-least-once, и тогда exactly-once требует idempotent consumer. Начиная с Debezium 3.3 (октябрь 2025) для всех core connectors (PostgreSQL, MySQL, MariaDB, MongoDB, Oracle, SQL Server) доступна exactly-once source semantics — включается через worker-настройку Kafka Connect 3.3+ `exactly.once.source.support=enabled`.

Пример:
// Kafka Streams - exactly-once
Properties props = new Properties();
props.put(StreamsConfig.PROCESSING_GUARANTEE_CONFIG,
  StreamsConfig.EXACTLY_ONCE_V2);

// Debezium config - основа для exactly-once
{
  // Kafka producer идемпотентность
  "producer.enable.idempotence": true,

  // Consumer должен сам обеспечить идемпотентность
  // через deduplication или event_id tracking
}

// Consumer pattern - deduplication
SET processed_events = new Set();
for (event in stream) {
  if (!processed_events.has(event.id)) {
    process(event);
    processed_events.add(event.id);
  }
}

Event Sourcing

Событийное хранение
Термин

Архитектурный паттерн, где состояние приложения хранится как последовательность событий, а не как текущий snapshot. CDC отлично сочетается с Event Sourcing — изменения базы данных становятся событиями в event log (Kafka), из которых можно восстановить любое состояние системы.

Пример:
// Event Store структура
CREATE TABLE event_store (
  event_id UUID PRIMARY KEY,
  aggregate_id VARCHAR(255),
  aggregate_type VARCHAR(255),
  event_type VARCHAR(255),
  event_data JSONB,
  created_at TIMESTAMP DEFAULT NOW()
);

// CDC события как Event Source
{
  "event_id": "evt-123",
  "aggregate_id": "order-456",
  "aggregate_type": "Order",
  "event_type": "OrderPlaced",
  "event_data": {
    "orderId": 456,
    "customerId": 789,
    "amount": 99.99
  }
}

// Восстановление состояния
SELECT * FROM event_store
WHERE aggregate_id = 'order-456'
ORDER BY created_at;