Troubleshooting CDC
База знаний типичных ошибок Debezium с диагностикой, причинами и пошаговыми решениями. Используйте фильтры для поиска по коннектору и категории проблемы, или Cmd+K для поиска по тексту ошибки.
Фильтр по коннектору
Фильтр по категории
Symptoms
- Debezium не может подключиться к PostgreSQL для репликации
- В логах коннектора: "FATAL: no pg_hba.conf entry for replication connection"
- Connector status: FAILED при попытке старта
Cause
PostgreSQL не разрешает подключения для репликации от указанного хоста. Файл pg_hba.conf контролирует аутентификацию и должен явно разрешать replication connections для пользователя и хоста Debezium.
Solution
- Откройте файл
pg_hba.conf(обычно/var/lib/postgresql/data/pg_hba.conf) - Добавьте строку для репликации:
host replication debezium 0.0.0.0/0 md5 - Перезагрузите конфигурацию:
SELECT pg_reload_conf();(или перезапуск PostgreSQL) - Проверьте подключение:
psql -h localhost -U debezium -d postgres -c "IDENTIFY_SYSTEM" replication=database
Related lessons:
Symptoms
- Коннектор не стартует после рестарта Kafka Connect
- Ошибка при создании нового коннектора с тем же именем слота
- PostgreSQL показывает slot с active = true
Cause
Предыдущий инстанс коннектора не освободил replication slot корректно, или slot уже используется другим процессом репликации. PostgreSQL позволяет только одно активное соединение к каждому слоту.
Solution
- Проверьте активные слоты:
SELECT slot_name, active, active_pid FROM pg_replication_slots; - Если slot показывает
active = true, найдите процесс:SELECT pid, usename, application_name FROM pg_stat_replication; - Терминируйте соединение:
SELECT pg_terminate_backend(); - Или удалите слот (ПОТЕРЯЕТЕ ПОЗИЦИЮ!):
SELECT pg_drop_replication_slot('debezium'); - Пересоздайте коннектор с
snapshot.mode=initialесли удалили слот
Related lessons:
Symptoms
- Директория pg_wal занимает десятки/сотни GB
- Диск PostgreSQL заполняется
- Replication slot показывает большой lag между current_lsn и restart_lsn
Cause
Replication slot удерживает WAL-сегменты, не позволяя PostgreSQL удалять их до тех пор, пока Debezium не прочитает. Если коннектор остановлен или работает медленно, WAL накапливается.
Solution
- Проверьте lag слота:
SELECT slot_name, pg_wal_lsn_diff(pg_current_wal_lsn(), restart_lsn) AS lag_bytes FROM pg_replication_slots; - Если коннектор МЁРТВ и не планируется запускать — удалите слот:
SELECT pg_drop_replication_slot('debezium'); - Если коннектор временно остановлен — запустите его для чтения накопленного WAL
- Настройте мониторинг lag и автоудаление неиспользуемых слотов:
max_slot_wal_keep_size = 10GB
Related lessons:
Symptoms
- Snapshot фаза зависает или падает с timeout
- Ошибка "could not obtain lock" в логах коннектора
- Snapshot не завершается на больших таблицах
Cause
Debezium пытается сделать consistent snapshot и требует короткую блокировку таблиц. Если на таблице есть долгие транзакции или активные записи, блокировку получить невозможно.
Solution
- Увеличьте
snapshot.lock.timeout.msв конфигурации коннектора (по умолчанию 10 секунд) - Запланируйте snapshot на период низкой нагрузки (ночь, выходные)
- Используйте
snapshot.mode=neverиsnapshot.mode=schema_onlyесли начальные данные не критичны - Проверьте активные транзакции:
SELECT pid, usename, query, state FROM pg_stat_activity WHERE state != 'idle';
Related lessons:
Symptoms
- MySQL коннектор не может начать streaming или snapshot
- Ошибка ERROR 1236 при инициализации коннектора
- Binlog файлы были ротированы или удалены
Cause
Debezium пытается читать binlog с позиции, которая уже была удалена из-за ротации логов. Это происходит после длительного downtime коннектора или при агрессивных настройках expire_logs_days / binlog_expire_logs_seconds.
Solution
- Проверьте доступные binlog файлы:
SHOW BINARY LOGS; - Увеличьте retention период:
SET GLOBAL expire_logs_days = 7;илиSET GLOBAL binlog_expire_logs_seconds = 604800; - Удалите коннектор и пересоздайте с
snapshot.mode=initialдля полного ресканирования - Настройте Heartbeat для предотвращения удаления binlog на малоактивных таблицах
Related lessons:
Symptoms
- MySQL коннектор падает при попытке подключения в GTID режиме
- Ошибка про purged GTIDs в логах Debezium
- После восстановления сервера или длительного downtime
Cause
MySQL удалил binlog файлы, содержащие GTID транзакции, которые Debezium ещё не прочитал. При использовании GTID режима невозможно продолжить репликацию с пропущенными GTID.
Solution
- Проверьте purged GTID set:
SHOW GLOBAL VARIABLES LIKE 'gtid_purged'; - Проверьте executed GTID set:
SHOW MASTER STATUS; - ВАРИАНТ 1: Пересоздайте коннектор с полным snapshot
- ВАРИАНТ 2 (ОПАСНО): Сбросьте gtid_purged на slave (Debezium):
RESET MASTER;иSET GLOBAL gtid_purged=''; - Увеличьте binlog retention для предотвращения проблемы
Related lessons:
Symptoms
- Коннектор не создаётся, валидация конфигурации падает
- Ошибка при POST /connectors с некорректным database.server.name
- Спецсимволы в имени сервера
Cause
Параметр database.server.name используется как префикс для Kafka топиков. Kafka топики не поддерживают большинство спецсимволов, только [a-zA-Z0-9._-].
Solution
- Используйте только буквы, цифры, точку, дефис и подчёркивание в
database.server.name - Пример правильного значения:
dbserver1,pg-prod,mysql.replica_01 - Пример неправильного:
db@server,pg prod,mysql:5432 - Измените конфигурацию коннектора и пересоздайте
Related lessons:
Symptoms
- Consumer group показывает растущий lag
- Задержка между изменением в БД и доставкой в Kafka увеличивается
- kafka-consumer-groups --describe показывает LAG > 0 и растёт
Cause
Consumer приложение не успевает обрабатывать CDC события с той скоростью, с которой они поступают. Возможные причины: медленная бизнес-логика, неоптимальная сериализация, недостаточная параллелизация.
Solution
- Проверьте метрики consumer: throughput, processing time per message
- Увеличьте количество партиций топика для параллельной обработки
- Увеличьте количество consumer инстансов (до числа партиций)
- Оптимизируйте бизнес-логику: используйте batch processing, асинхронность
- Рассмотрите использование Kafka Streams для более эффективной обработки
Related lessons:
Symptoms
- Коннектор не может создать replication slot
- Ошибка "logical decoding requires wal_level >= logical" в PostgreSQL логах
- pg_create_logical_replication_slot() возвращает ошибку
Cause
PostgreSQL параметр wal_level установлен в replica или minimal, что недостаточно для logical replication. Debezium требует wal_level = logical для захвата изменений через логическую репликацию.
Solution
- Проверьте текущий уровень:
SHOW wal_level; - Откройте postgresql.conf и установите:
wal_level = logical - Перезапустите PostgreSQL сервер (требуется полный рестарт, reload недостаточен)
- Проверьте изменение:
SHOW wal_level;должно вернуть "logical" - После перезапуска создайте коннектор заново
Related lessons:
Symptoms
- PostgreSQL коннектор не стартует в pgoutput plugin режиме
- Ошибка "publication does not exist" при инициализации
- Connector status: FAILED с упоминанием publication
Cause
При использовании pgoutput plugin (Debezium 2.0+), коннектор ожидает существующую PostgreSQL publication. Если publication.autocreate.mode=disabled, publication должна быть создана вручную.
Solution
- Проверьте существующие publications:
SELECT * FROM pg_publication; - Создайте publication для всех таблиц:
CREATE PUBLICATION dbz_publication FOR ALL TABLES; - Или для конкретных таблиц:
CREATE PUBLICATION dbz_publication FOR TABLE customers, orders; - Или включите автосоздание в конфигурации:
publication.autocreate.mode=all_tables - Убедитесь, что пользователь Debezium имеет права на publication
Related lessons:
Symptoms
- Коннектор не может создать replication slot
- Ошибка "must be superuser or replication role"
- pg_create_logical_replication_slot() падает с permission denied
Cause
Пользователь БД, который использует Debezium, не имеет прав REPLICATION. Только пользователи с REPLICATION role или SUPERUSER могут создавать и использовать replication slots.
Solution
- Проверьте права пользователя:
SELECT rolname, rolreplication FROM pg_roles WHERE rolname = 'debezium'; - Предоставьте REPLICATION права:
ALTER USER debezium WITH REPLICATION; - Или создайте пользователя с нужными правами:
CREATE USER debezium WITH REPLICATION PASSWORD 'password'; - Дополнительно дайте права на БД:
GRANT CONNECT ON DATABASE mydb TO debezium; - И на схему:
GRANT USAGE ON SCHEMA public TO debezium; GRANT SELECT ON ALL TABLES IN SCHEMA public TO debezium;
Related lessons:
Symptoms
- MySQL коннектор не стартует
- Ошибка про row-level binlog format при инициализации
- Debezium требует ROW формат, но MySQL использует STATEMENT или MIXED
Cause
MySQL параметр binlog_format установлен в STATEMENT или MIXED. Debezium требует binlog_format = ROW для захвата всех изменений на уровне строк, включая изменения данных до и после.
Solution
- Проверьте текущий формат:
SHOW VARIABLES LIKE 'binlog_format'; - Установите динамически (до перезапуска):
SET GLOBAL binlog_format = 'ROW'; - Сделайте постоянным в my.cnf:
[mysqld]секция, добавьтеbinlog_format = ROW - Перезапустите MySQL для применения постоянных настроек
- Проверьте:
SHOW VARIABLES LIKE 'binlog_format';должно вернуть "ROW"
Related lessons:
Symptoms
- MySQL коннектор не может начать репликацию
- Ошибка "server_id is not set" или "server_id cannot be 0"
- Binlog replication не работает
Cause
MySQL параметр server_id не установлен или равен 0. Для репликации (включая CDC) каждый сервер в топологии должен иметь уникальный server_id > 0.
Solution
- Проверьте текущий server_id:
SHOW VARIABLES LIKE 'server_id'; - Установите уникальный ID:
SET GLOBAL server_id = 223344;(временно) - Сделайте постоянным в my.cnf:
[mysqld]секция, добавьтеserver_id = 223344 - Перезапустите MySQL
- Убедитесь, что server_id уникален среди всех MySQL серверов и Debezium коннекторов в вашей инфраструктуре
Related lessons:
Symptoms
- CDC события содержат неполные данные
- Для UPDATE операций отсутствуют значения "before"
- Warning в логах Debezium про binlog_row_image
Cause
MySQL параметр binlog_row_image установлен в MINIMAL или NOBLOB. Debezium требует FULL для получения полных данных "before" и "after" для всех операций.
Solution
- Проверьте текущее значение:
SHOW VARIABLES LIKE 'binlog_row_image'; - Установите FULL:
SET GLOBAL binlog_row_image = 'FULL'; - Сделайте постоянным в my.cnf:
[mysqld]секция, добавьтеbinlog_row_image = FULL - Перезапустите MySQL для применения
- После изменения пересоздайте коннектор для корректной обработки новых событий
Related lessons:
Symptoms
- MySQL коннектор периодически падает с ошибкой 2013
- Долгие snapshot операции прерываются
- Ошибка "Lost connection to MySQL server" во время чтения binlog
Cause
MySQL терминирует соединение из-за превышения таймаута или проблем сети. Причины: wait_timeout слишком мал, max_allowed_packet недостаточен, сетевые разрывы, большие транзакции.
Solution
- Увеличьте wait_timeout и interactive_timeout на сервере:
SET GLOBAL wait_timeout = 28800; - Увеличьте max_allowed_packet:
SET GLOBAL max_allowed_packet = 67108864;(64MB) - В my.cnf добавьте:
wait_timeout = 28800,max_allowed_packet = 64M - В конфигурации коннектора увеличьте connect.timeout.ms и connect.keep.alive.ms
- Проверьте сетевую стабильность между Kafka Connect и MySQL
Related lessons:
Symptoms
- POST /connectors возвращает 409 Conflict
- Ошибка "Connector xyz already exists"
- Невозможно создать коннектор с существующим именем
Cause
Имя коннектора уже используется в Kafka Connect кластере. Каждый коннектор должен иметь уникальное имя в пределах кластера.
Solution
- Проверьте существующие коннекторы:
curl http://localhost:8083/connectors - Удалите старый коннектор:
curl -X DELETE http://localhost:8083/connectors/xyz - Или используйте другое имя для нового коннектора
- Или обновите существующий:
curl -X PUT http://localhost:8083/connectors/xyz/config -H "Content-Type: application/json" -d @config.json - Убедитесь, что имя уникально перед созданием
Related lessons:
Symptoms
- MySQL коннектор не стартует после перезапуска
- Ошибка про недоступный schema.history.internal.kafka.topic
- Коннектор не может восстановить историю DDL изменений
Cause
Kafka топик для хранения истории схем БД (DDL changes) был удалён или недоступен. MySQL коннектор требует этот топик для отслеживания структуры таблиц во времени.
Solution
- Проверьте существование топика:
kafka-topics --bootstrap-server localhost:9092 --list | grep schema-history - Если топик удалён, варианты восстановления:
- ВАРИАНТ 1 (если есть бэкап): Восстановите топик из бэкапа
- ВАРИАНТ 2: Пересоздайте коннектор с snapshot.mode=initial (потеряете offset)
- ВАРИАНТ 3 (ОПАСНО): schema.history.internal.skip.unparseable.ddl=true
- Настройте retention для schema history топика: min.compaction.lag.ms, delete.retention.ms
Related lessons:
Symptoms
- Коннектор не может сохранить offset
- Ошибка про недоступный offset.storage.topic
- Connector повторно читает те же события после рестарта
Cause
Kafka топик для хранения offset (connect-offsets) недоступен, удалён, или у Kafka Connect нет прав на запись. Без offset коннектор не может отслеживать свою позицию в логах репликации.
Solution
- Проверьте топик offset:
kafka-topics --bootstrap-server localhost:9092 --describe --topic connect-offsets - Убедитесь, что топик существует и имеет достаточное число партиций и реплик
- Проверьте права Kafka Connect на запись в топик (ACL если используется)
- Проверьте настройки Kafka Connect worker: offset.storage.topic, offset.storage.replication.factor
- Если топик удалён — создайте заново:
kafka-topics --create --topic connect-offsets --replication-factor 3 --partitions 25 --config cleanup.policy=compact
Related lessons:
Symptoms
- Kafka Connect worker падает с OutOfMemoryError
- Коннектор зависает во время snapshot больших таблиц
- Увеличение памяти в метриках JVM до предела heap
Cause
Недостаточно памяти JVM heap для обработки больших событий или snapshot операций. Причины: очень большие таблицы в snapshot, огромные транзакции, много коннекторов на одном worker, малый heap size.
Solution
- Увеличьте heap size в KAFKA_HEAP_OPTS:
export KAFKA_HEAP_OPTS="-Xms4G -Xmx4G" - Для snapshot: используйте incremental snapshot вместо initial (Debezium 1.6+)
- Уменьшите max.batch.size и max.queue.size в конфигурации коннектора
- Разделите коннекторы по разным worker процессам
- Мониторьте JVM метрики: heap usage, GC frequency, GC pause time
- Используйте G1GC для лучшего управления памятью:
-XX:+UseG1GC
Related lessons:
Symptoms
- PostgreSQL коннектор не стартует с plugin.name=pgoutput
- Ошибка "could not access file pgoutput"
- pg_create_logical_replication_slot падает при указании pgoutput
Cause
PostgreSQL не имеет установленного pgoutput плагина или используется старая версия PostgreSQL (< 10). pgoutput — это встроенный плагин логической репликации, доступный с PostgreSQL 10+.
Solution
- Проверьте версию PostgreSQL:
SELECT version();— должна быть 10 или выше - Проверьте доступные плагины:
SELECT * FROM pg_available_extensions WHERE name = 'pgoutput'; - Если PostgreSQL < 10: обновите до версии 10+ или используйте decoderbufs plugin
- Если PostgreSQL >= 10 но pgoutput отсутствует: переустановите PostgreSQL или плагин
- Альтернативно используйте plugin.name=decoderbufs (требует отдельной установки)
- Для RDS/Aurora: убедитесь, что rds.logical_replication = 1 в parameter group
Related lessons:
Error not found? Use Cmd+K (Ctrl+K) to search for error text in the knowledge base. Also refer to module lessons for deeper understanding of mechanisms and problem diagnosis.