🔸 Что нужно отправлять в дополнение к heartbeat сигналу
Расследуем проблему дальше. Применяем настройку, топик
__debezium-heartbeat.<префикс> появляется, сообщения в него идут. На первый взгляд всё хорошо. При этом LSN стоит на прежнем месте, а удержанный WAL продолжает расти. Heartbeat пишется только в Kafka и хранит последнюю позицию, которую коннектор видел в WAL. Без событий из отслеживаемых таблиц эта позиция не меняется, и подтверждать Postgres по-прежнему нечего.Но как лучше всего в СУБД сформировать изменение данных, не искажающее действительность? Для этого удобно завести отдельную служебную таблицу, добавить её в публикацию и в
table.include.list, а в heartbeat.action.query раз в интервал обновлять в ней одну строку. Коннектор получает событие из WAL, подтверждает новую позицию, и слот сдвигается. На PostgreSQL 14 и новее можно обойтись без таблицы, если писать служебное сообщение прямо в WAL:
"heartbeat.interval.ms": "30000",
"heartbeat.action.query": "SELECT pg_logical_emit_message(false, 'heartbeat', now()::varchar)"
Оба варианта требуют права на запись, поэтому при чтении из реплики они не работают, и решать проблему приходится на стороне сервера или мониторинга.
🔸 Серверный ограничитель
Можно ли это решить на стороне Postgres? Есть настройка, которая может нам помочь, давайте её проверим. `
max_slot_wal_keep_size` задаёт потолок удержанного WAL, после которого слот переходит в wal_status = lost и диск перестаёт расти. Недостаток в том, что продолжить чтение с потерянной позиции нельзя, коннектору понадобится новый снапшот. По умолчанию ограничитель выключен, так что неограниченный рост WAL за остановившимся слотом остаётся штатным поведением Postgres.Если в захвате только редко меняющиеся таблицы, стоит проверить, двигается ли
confirmed_flush_lsn у слота и сколько WAL он удерживает)p.s. Релиз лабы по тому, как ломать и чинить Debezium коннектор, уже завтра. А пока - скидка 10% на лабу "Переход на шардированный ClickHouse"