Prerequisites:
- module-1/02-debezium-architecture
Logical Decoding: Глубокое погружение
В предыдущем модуле мы узнали, что Debezium читает transaction log (WAL) PostgreSQL. Но как именно это происходит? В этом уроке мы погрузимся в механизм logical decoding — технологию, которая превращает бинарный WAL в понятный поток изменений.
Физическая vs Логическая репликация
PostgreSQL поддерживает два типа репликации. Понимание разницы критически важно для настройки CDC.
Только PostgreSQL → PostgreSQL
Вся база целиком
Выборочные таблицы
Разные версии PostgreSQL
| Характеристика | Физическая | Логическая |
|---|---|---|
| Формат данных | Бинарные блоки | Структурированные изменения |
| Гранулярность | Вся база | Отдельные таблицы |
| Потребители | Только PostgreSQL | Любая система |
| Use case | High Availability | CDC, интеграции |
Для CDC нам нужна логическая репликация, потому что мы хотим получать понятные события об изменениях, а не бинарные данные.
Что такое Logical Decoding?
Logical Decoding — это механизм PostgreSQL, который преобразует записи WAL в логический формат. Каждая транзакция декодируется в последовательность операций INSERT, UPDATE, DELETE с данными строк.
Компоненты Logical Decoding
WAL (Write-Ahead Log) — журнал транзакций, куда PostgreSQL записывает каждое изменение ДО применения к таблицам. Гарантирует durability.
Replication Slot — закладка в WAL. PostgreSQL не удаляет WAL сегменты, пока слот их не прочитал. Критически важно для надежности CDC.
Logical Decoder — компонент PostgreSQL, который интерпретирует WAL записи в контексте транзакций.
Output Plugin — форматирует декодированные изменения. pgoutput — стандартный плагин PostgreSQL 10+.
pgoutput: Стандартный плагин
pgoutput — это встроенный output plugin PostgreSQL для логической репликации. Именно его использует Debezium.
Почему pgoutput — стандарт для Debezium?
| Плагин | Статус | Особенности |
|---|---|---|
| pgoutput | Встроенный (PG 10+) | Не требует установки, работает на Aurora/RDS |
| wal2json | Сторонний | JSON формат, требует установки, больше overhead |
| decoderbufs | Сторонний | Protobuf формат, недоступен на Aurora |
Рекомендация: Всегда используйте pgoutput. Это единственный плагин, который:
- Не требует установки дополнительного ПО
- Работает на всех managed PostgreSQL (Aurora, RDS, Cloud SQL)
- Поддерживается командой PostgreSQL
{
"name": "postgres-connector",
"config": {
"connector.class": "io.debezium.connector.postgresql.PostgresConnector",
"plugin.name": "pgoutput",
"database.hostname": "postgres",
"database.port": "5432",
"database.user": "postgres",
"database.dbname": "inventory"
}
}
Проверка знанийПочему pgoutput рекомендуется для Debezium, даже если wal2json выдаёт более читаемый JSON?
Анатомия WAL для Logical Decoding
Когда вы выполняете транзакцию, PostgreSQL записывает её в WAL. При wal_level=logical добавляется дополнительная информация для декодирования.
Что содержит WAL запись при logical decoding?
┌─────────────────────────────────────────────────────┐
│ WAL Record │
├─────────────────────────────────────────────────────┤
│ LSN (Log Sequence Number): 0/1A3B4C0 │
│ Transaction ID: 12345 │
│ Timestamp: 2026-02-01 10:30:00.123 │
│ Operation: UPDATE │
│ Relation: public.customers (OID: 16384) │
│ Old tuple key: {id: 1} │
│ New tuple: {id: 1, name: 'Alice', email: '...'} │
└─────────────────────────────────────────────────────┘
LSN (Log Sequence Number) — уникальный идентификатор позиции в WAL. Debezium использует LSN для отслеживания прогресса.
Transaction ID — группирует изменения одной транзакции. Debezium публикует события с одним transaction ID атомарно.
Old/New tuple — старые и новые значения строки. Доступность старых значений зависит от REPLICA IDENTITY.
Publications: Контроль над тем, что реплицируется
Publication — это набор таблиц, изменения которых будут доступны для логической репликации. Debezium использует publications для фильтрации таблиц.
Создание Publication
-- Публикация для всех таблиц (рекомендуется для начала)
CREATE PUBLICATION dbz_publication FOR ALL TABLES;
-- Публикация только для конкретных таблиц
CREATE PUBLICATION orders_publication
FOR TABLE public.orders, public.customers;
-- Публикация с фильтрацией операций
CREATE PUBLICATION inserts_only
FOR TABLE public.events
WITH (publish = 'insert'); -- Только INSERT, без UPDATE/DELETE
Проверка существующих Publications
-- Список всех publications
SELECT * FROM pg_publication;
-- Таблицы в publication
SELECT * FROM pg_publication_tables
WHERE pubname = 'dbz_publication';
Как Debezium использует Publications
В конфигурации коннектора указывается имя publication:
{
"name": "inventory-connector",
"config": {
"connector.class": "io.debezium.connector.postgresql.PostgresConnector",
"plugin.name": "pgoutput",
"publication.name": "dbz_publication",
"publication.autocreate.mode": "filtered"
}
}
publication.autocreate.mode:
all_tables— создать для всех таблиц (по умолчанию)filtered— создать только для таблиц изtable.include.listdisabled— использовать существующую publication
REPLICA IDENTITY: Что попадает в before/after
REPLICA IDENTITY определяет, какие данные PostgreSQL включает в WAL при UPDATE и DELETE. Это критически влияет на содержимое CDC событий.
Четыре режима REPLICA IDENTITY
| Режим | UPDATE before | DELETE before | Overhead |
|---|---|---|---|
| DEFAULT | Только PK | Только PK | Минимальный |
| USING INDEX | Колонки индекса | Колонки индекса | Низкий |
| FULL | Вся строка | Вся строка | Высокий |
| NOTHING | Пусто | Пусто | Нулевой |
Пример события при разных REPLICA IDENTITY
REPLICA IDENTITY DEFAULT (Primary Key):
{
"op": "u",
"before": {
"id": 1
},
"after": {
"id": 1,
"name": "Alice Updated",
"email": "[email protected]"
}
}
REPLICA IDENTITY FULL:
{
"op": "u",
"before": {
"id": 1,
"name": "Alice",
"email": "[email protected]"
},
"after": {
"id": 1,
"name": "Alice Updated",
"email": "[email protected]"
}
}
Когда использовать FULL?
Используйте REPLICA IDENTITY FULL когда:
- Нужно знать, что именно изменилось — сравнение before/after
- Потребителю нужны все поля до изменения — аудит, compliance
- Логика обработки зависит от старых значений
-- Включить FULL для конкретной таблицы
ALTER TABLE public.customers REPLICA IDENTITY FULL;
-- Проверить текущую настройку
SELECT relname, relreplident
FROM pg_class
WHERE relname = 'customers';
-- relreplident: 'd' = DEFAULT, 'f' = FULL, 'i' = INDEX, 'n' = NOTHING
Проверка знанийТаблица имеет REPLICA IDENTITY DEFAULT. Какие данные будут в поле before при UPDATE-событии?
Предупреждение о производительности
REPLICA IDENTITY FULL увеличивает объем WAL. Каждый UPDATE и DELETE записывает полную строку в WAL. Для таблиц с частыми изменениями и широкими строками (много колонок, JSONB) это может увеличить WAL volume на 30-50%.
Рекомендация: используйте DEFAULT для большинства таблиц, FULL — только где действительно необходимо.
Полный поток Logical Decoding
Соединим все компоненты в единый поток.
Ключевые точки
- wal_level=logical — обязательная настройка PostgreSQL
- Replication Slot — гарантирует, что WAL не удалится до прочтения
- pgoutput — преобразует бинарный WAL в структурированные данные
- Publication — определяет, какие таблицы реплицируются
- REPLICA IDENTITY — определяет полноту данных в before/after
Проверка настроек
-- Проверить wal_level
SHOW wal_level;
-- Должно быть: logical
-- Проверить существующие слоты
SELECT slot_name, plugin, slot_type, active
FROM pg_replication_slots;
-- Проверить publications
SELECT pubname, puballtables
FROM pg_publication;
-- Проверить REPLICA IDENTITY для таблицы
SELECT c.relname, c.relreplident
FROM pg_class c
JOIN pg_namespace n ON n.oid = c.relnamespace
WHERE n.nspname = 'public' AND c.relkind = 'r';
Что дальше?
Теперь, когда вы понимаете, как PostgreSQL преобразует WAL в логические изменения, следующий важный вопрос: как управлять replication slots?
Slots — это мощный механизм, но они требуют внимания. Abandoned slot может заполнить диск, остановив базу данных. В следующем уроке мы изучим жизненный цикл replication slots и критически важные процедуры мониторинга.
Ключевые выводы
- Logical Decoding преобразует бинарный WAL в понятные события INSERT/UPDATE/DELETE
- pgoutput — стандартный плагин, работает везде, не требует установки
- Publications контролируют, какие таблицы участвуют в логической репликации
- REPLICA IDENTITY определяет полноту данных — DEFAULT для эффективности, FULL для полной истории
- Replication Slots гарантируют, что Debezium не пропустит изменения
Check Your Understanding
Finished the lesson?
Mark it as complete to track your progress