Перейти к содержанию
Learning Platform
Глоссарий Troubleshooting
Урок 12.06 · 30 мин
Продвинутый
CDCPostgreSQLMySQLreplicationWAL

MaterializedPostgreSQL и MaterializedMySQL

ClickHouse имеет встроенные движки баз данных для CDC (Change Data Capture) из PostgreSQL и MySQL. Вместо ручной синхронизации данных или внешних инструментов вроде Debezium, эти движки подписываются на журнал изменений источника и автоматически реплицируют все INSERT/UPDATE/DELETE в ClickHouse.


MaterializedPostgreSQL

INFO

Managed-альтернатива для ClickHouse Cloud. С мая 2025 ClickPipes Postgres CDC (на базе приобретённого ClickHouse PeerDB) официально GA для ClickHouse Cloud. Это рекомендуемый production-путь для пользователей CH Cloud: connector в несколько кликов реплицирует Postgres в ClickHouse, ~5x дешевле внешних ETL-инструментов, метеринг включён с 1 сентября 2025. Self-hosted ClickHouse продолжает использовать MaterializedPostgreSQL (engine, описанный ниже) или Debezium. Сравнение — в конце урока.

MaterializedPostgreSQL создаёт базу данных ClickHouse, которая является зеркалом PostgreSQL-базы через логическую репликацию (WAL):

CREATE DATABASE pg_replica
ENGINE = MaterializedPostgreSQL('postgres-host:5432', 'mydb', 'replication_user', 'secret')
SETTINGS materialized_postgresql_schema = 'public';

После создания ClickHouse:

  1. Выполняет начальный снапшот всех таблиц из PostgreSQL
  2. Подписывается на WAL через logical replication slot
  3. Получает и применяет все изменения в реальном времени

Таблицы в ClickHouse становятся доступны через стандартные SELECT-запросы:

-- Таблица pg_replica.users автоматически синхронизируется с PostgreSQL
SELECT count() FROM pg_replica.users;
WARNING

PostgreSQL требует wal_level=logical для логической репликации. По умолчанию PostgreSQL настроен с wal_level=replica, который недостаточен. Для изменения:

-- В PostgreSQL (требует права суперпользователя)
ALTER SYSTEM SET wal_level = logical;
-- Требуется полный перезапуск PostgreSQL (не reload!)
-- sudo systemctl restart postgresql

Проверить текущий уровень: SHOW wal_level;. Без wal_level=logical MaterializedPostgreSQL вернёт ошибку “logical replication not enabled”.


Shadow tables: _sign и _version

MaterializedPostgreSQL хранит данные в shadow-таблицах ReplacingMergeTree с двумя служебными колонками:

  • _sign (Int8): 1 = строка активна (INSERT), -1 = строка удалена (DELETE)
  • _version (UInt64): монотонно возрастающий счётчик версий для отслеживания UPDATE
-- Прямой доступ к shadow-таблице (с _sign и _version)
SELECT *, _sign, _version
FROM pg_replica.orders
ORDER BY id, _version;

При SELECT через materialized view ClickHouse автоматически фильтрует строки с _sign = 1 и возвращает только актуальные версии.

MaterializedPostgreSQL: WAL-репликация в ClickHouse
PostgreSQL WAL (wal_level=logical)PostgreSQL с wal_level=logical: WAL (Write-Ahead Log) записывает каждое изменение в журнал. Logical replication slot позволяет внешним потребителям читать WAL в decoded (human-readable) форме: INSERT/UPDATE/DELETE с actual values.
Logical replication slot
MaterializedPostgreSQL engineMaterializedPostgreSQL engine: ClickHouse создаёт logical replication slot в PostgreSQL. Движок декодирует WAL-записи и транслирует их как INSERT в shadow-таблицы ReplacingMergeTree. Начальная загрузка выполняется через pg_dump snapshot.
ReplacingMergeTree shadow tables
_sign=1 (active)_sign=1: строка активна (INSERT или результат UPDATE). При UPDATE PostgreSQL генерирует DELETE (_sign=-1) + INSERT (_sign=1) нового значения. ClickHouse видит это как две записи с одним pk.
_sign=-1 (deleted)_sign=-1: строка помечена как удалённая (DELETE или старая версия после UPDATE). При merge ReplacingMergeTree убирает дубли, оставляя только актуальную версию (_version максимальный, _sign=1).
_version counter_version: монотонно возрастающий счётчик для каждой строки. Позволяет ReplacingMergeTree определить, какая из нескольких версий строки с одним pk является актуальной: максимальный _version = актуальная версия.

MaterializedMySQL

MaterializedMySQL работает аналогично, но использует MySQL binlog вместо PostgreSQL WAL:

CREATE DATABASE mysql_replica
ENGINE = MaterializedMySQL('mysql-host:3306', 'mydb', 'replication_user', 'secret');

ClickHouse подключается к MySQL как реплика (slave) и читает binlog в реальном времени. Начальная загрузка выполняется через mysqldump-совместимый snapshot.

-- Проверка статуса репликации
SELECT *
FROM system.replication_queue
WHERE database = 'mysql_replica';

Ограничения и мониторинг

Ограничения MaterializedPostgreSQL:

  • DDL-изменения в PostgreSQL (ALTER TABLE, DROP TABLE) могут прерывать репликацию — требуется ручное вмешательство
  • Таблицы без primary key не могут реплицироваться корректно
  • Поддерживаются не все типы данных PostgreSQL

Ограничения MaterializedMySQL:

  • DDL-изменения в MySQL частично поддерживаются (добавление колонок работает; DROP TABLE прерывает репликацию)
  • JSON-тип в MySQL может требовать явного маппинга
-- Мониторинг отставания репликации
SELECT
    database,
    last_exception,
    last_exception_time,
    total_rows_read,
    total_bytes_read
FROM system.materialized_postgresql_tables;

-- Детализация по таблицам
SELECT *
FROM system.replication_queue
WHERE database LIKE 'pg_%';

Рекомендуется: настроить алерты на last_exception и last_exception_time — они первыми сигнализируют о проблемах с WAL/binlog.


Выбор инструмента: ClickPipes vs MaterializedPostgreSQL vs Debezium

КритерийClickPipes Postgres CDC (CH Cloud)MaterializedPostgreSQL (self-hosted)Debezium + Kafka Sink
ПлатформаТолько ClickHouse CloudЛюбой self-hosted ClickHouseЛюбой ClickHouse + Kafka-стек
СтатусGA с мая 2025 (на базе PeerDB)Встроен в ClickHouseProduction-ready
УправлениеManaged (несколько кликов)СамоуправляемоеТребует Kafka Connect
Цена~5x дешевле external ETLБесплатно (кроме compute)Стоимость Kafka + Connect
ГибкостьОграничена UI/APIГибкая через SETTINGSМаксимальная (SMT, custom sinks)
DDL handlingАвтоматическоеПрерывание репликацииЗависит от connector

Когда что выбирать:

  • ClickHouse Cloud — ClickPipes Postgres CDC (GA с мая 2025).
  • Self-hosted с прямой сетью PG -> CHMaterializedPostgreSQL (этот урок).
  • Self-hosted с уже существующим Kafka-стеком или необходимостью SMT/multi-sink — Debezium.

Ключевые выводы

  1. MaterializedPostgreSQL и MaterializedMySQL — встроенные CDC-движки ClickHouse: подписываются на WAL/binlog источника и автоматически реплицируют все изменения.
  2. PostgreSQL обязательно требует wal_level=logical (изменение требует полного перезапуска сервера, не reload).
  3. Shadow-таблицы используют ReplacingMergeTree с _sign (1=active, -1=deleted) и _version для отслеживания INSERT/UPDATE/DELETE-семантики.
  4. DDL-изменения в источнике (особенно DROP TABLE) могут прерывать репликацию — необходим мониторинг last_exception.
  5. Для production CDC из PostgreSQL/MySQL в self-hosted: MaterializedPostgreSQL/MaterializedMySQL проще Debezium, но требует прямого доступа к сети между ClickHouse и источником.
  6. Для ClickHouse Cloud рекомендуемый путь — managed ClickPipes Postgres CDC (GA с мая 2025, на базе PeerDB).
Logical replication в PostgreSQL: publication, subscription и wal_level=logical CDC-паттерны: Debezium, WAL-based replication и change streams

Закончили урок?

Отметьте его как пройденный, чтобы отслеживать свой прогресс

Войдите чтобы оценить урок

Прогресс модуля
0 из 11