Перейти к основному содержанию
Пользователям ClickHouse Cloud рекомендуется использовать ClickPipes для репликации PostgreSQL в ClickHouse. Этот способ нативно поддерживает высокопроизводительную CDC (фиксация изменений данных) для PostgreSQL.
Создает базу данных ClickHouse с таблицами из базы данных PostgreSQL. Сначала база данных с движком MaterializedPostgreSQL создает снимок базы данных PostgreSQL и загружает необходимые таблицы. Эти таблицы могут представлять собой любое подмножество таблиц из любого подмножества схем указанной базы данных. Вместе со снимком движок базы данных получает LSN, а после выполнения начального дампа таблиц начинает получать обновления из WAL. После создания базы данных новые таблицы, добавленные в базу данных PostgreSQL, автоматически в репликацию не включаются. Их нужно добавлять вручную запросом ATTACH TABLE db.table. Репликация реализована с использованием протокола PostgreSQL Logical Replication Protocol, который не позволяет реплицировать DDL, но позволяет определить, произошли ли изменения, нарушающие репликацию (изменение типов столбцов, добавление или удаление столбцов). Такие изменения обнаруживаются, и соответствующие таблицы перестают получать обновления. В этом случае следует использовать запросы ATTACH/DETACH PERMANENTLY, чтобы полностью перезагрузить таблицу. Если DDL не нарушает репликацию (например, при переименовании столбца), таблица все равно будет получать обновления (вставка выполняется по позиции).
Этот движок базы данных является экспериментальным. Чтобы использовать его, установите allow_experimental_database_materialized_postgresql в 1 в файлах конфигурации или с помощью команды SET:

Создание базы данных

Параметры движка
  • host:port — конечная точка сервера PostgreSQL.
  • database — имя базы данных PostgreSQL.
  • user — имя пользователя PostgreSQL.
  • password — пароль пользователя.

Пример использования

Динамическое добавление новых таблиц в репликацию

После создания базы данных MaterializedPostgreSQL новые таблицы в соответствующей базе данных PostgreSQL не обнаруживаются автоматически. Такие таблицы можно добавить вручную:
До версии 22.1 при добавлении таблицы в репликацию оставался неудалённый временный слот репликации (с именем {db_name}_ch_replication_slot_tmp). Если вы выполняете ATTACH таблиц в ClickHouse версии ниже 22.1, обязательно удалите его вручную (SELECT pg_drop_replication_slot('{db_name}_ch_replication_slot_tmp')). В противном случае будет расти использование диска. Эта проблема исправлена в версии 22.1.

Динамическое удаление таблиц из репликации

Из репликации можно исключить отдельные таблицы:

Схема PostgreSQL

Схема схема в PostgreSQL может быть настроена тремя способами (начиная с версии 21.12).
  1. Одна схема для одного движка базы данных MaterializedPostgreSQL. Требуется использовать настройку materialized_postgresql_schema. Доступ к таблицам осуществляется только по имени таблицы:
  1. Любое количество схем с указанным набором таблиц для одного движка базы данных MaterializedPostgreSQL. Требуется использовать настройку materialized_postgresql_tables_list. Каждая таблица записывается вместе со своей схемой. Доступ к таблицам осуществляется одновременно по имени схемы и имени таблицы:
Но в этом случае все таблицы в materialized_postgresql_tables_list должны быть указаны вместе с именем своей схемы. Требуется materialized_postgresql_tables_list_with_schema = 1. Предупреждение: в этом случае точки в именах таблиц не допускаются.
  1. Любое количество схем с полным набором таблиц для одного движка базы данных MaterializedPostgreSQL. Для этого требуется использовать настройку materialized_postgresql_schema_list.
Предупреждение: в этом случае точки в имени таблицы недопустимы.

Требования

  1. Параметр wal_level в файле конфигурации PostgreSQL должен иметь значение logical, а параметр max_replication_slots — значение не менее 2.
  2. Для каждой реплицируемой таблицы должен быть задан один из следующих идентификаторов реплики:
  • первичный ключ (по умолчанию)
  • индекс
Сначала всегда проверяется первичный ключ. Если он отсутствует, проверяется индекс, заданный как индекс идентификации реплики. Если индекс используется для идентификации реплики, в таблице может быть только один такой индекс. Проверить, какой тип используется для конкретной таблицы, можно с помощью следующей команды:
Репликация значений TOAST не поддерживается. Будет использовано значение по умолчанию для данного типа данных.

Настройки

materialized_postgresql_tables_list

Задаёт разделённый запятыми список таблиц базы данных PostgreSQL, которые будут реплицироваться с помощью движка базы данных MaterializedPostgreSQL. Для каждой таблицы в скобках можно указать подмножество реплицируемых столбцов. Если подмножество столбцов не указано, будут реплицироваться все столбцы этой таблицы.
По умолчанию: пустой список — это значит, что будет реплицирована вся база данных PostgreSQL.

materialized_postgresql_schema

Значение по умолчанию: пустая строка. (Используется схема по умолчанию)

materialized_postgresql_schema_list

По умолчанию: пустой список. (Используется схема по умолчанию)

materialized_postgresql_max_block_size

Задаёт количество строк, накапливаемых в памяти перед записью данных в таблицу базы данных PostgreSQL. Возможные значения:
  • Положительное целое число.
Значение по умолчанию: 65536.

materialized_postgresql_replication_slot

Слот репликации, созданный пользователем. Должен использоваться вместе с materialized_postgresql_snapshot.

materialized_postgresql_snapshot

Текстовая строка, идентифицирующая снимок, на основе которого будет выполнен первоначальный дамп таблиц PostgreSQL. Должен использоваться вместе с materialized_postgresql_replication_slot.
При необходимости настройки можно изменить с помощью DDL-запроса. Однако изменить параметр materialized_postgresql_tables_list нельзя. Чтобы обновить список таблиц в этом параметре, используйте запрос ATTACH TABLE.

materialized_postgresql_use_unique_replication_consumer_identifier

Использовать уникальный идентификатор consumer’а репликации. Значение по умолчанию: 0. Если установить 1, можно настроить несколько таблиц MaterializedPostgreSQL, указывающих на одну и ту же таблицу PostgreSQL.

Примечания

Переключение слота логической репликации при сбое

Слоты логической репликации, существующие на основном узле, недоступны на резервных репликах. Поэтому при переключении при сбое новый основной узел (бывший физический standby) не будет знать о слотах, существовавших на старом основном узле. Это приведет к нарушению репликации из PostgreSQL. Решение — самостоятельно управлять слотами репликации и определить постоянный слот репликации (дополнительную информацию можно найти здесь). Имя слота нужно передать через настройку materialized_postgresql_replication_slot, а сам слот должен быть экспортирован с параметром EXPORT SNAPSHOT. Идентификатор снимка нужно передать через настройку materialized_postgresql_snapshot. Обратите внимание, что использовать это следует только при реальной необходимости. Если явной необходимости нет или вы не до конца понимаете, зачем это нужно, лучше позволить движку таблицы самостоятельно создать слот репликации и управлять им. Пример (от @bchrobot)
  1. Настройте слот репликации в PostgreSQL.
  2. Дождитесь, пока слот репликации будет готов, затем начните транзакцию и экспортируйте идентификатор снимка транзакции:
  3. В ClickHouse создайте базу данных:
  4. Завершите транзакцию PostgreSQL, как только убедитесь, что репликация в DB ClickHouse работает. Проверьте, что после переключения при сбое репликация продолжается:

Необходимые разрешения

  1. CREATE PUBLICATION — право на выполнение запроса CREATE.
  2. CREATE_REPLICATION_SLOT — привилегия репликации.
  3. pg_drop_replication_slot — привилегия репликации или права суперпользователя.
  4. DROP PUBLICATION — владелец публикации (username в самом движке MaterializedPostgreSQL).
Можно избежать выполнения команд 2 и 3 и обойтись без этих разрешений. Используйте настройки materialized_postgresql_replication_slot и materialized_postgresql_snapshot. Но с большой осторожностью. Доступ к таблицам:
  1. pg_publication
  2. pg_replication_slots
  3. pg_publication_tables
Последнее изменение 19 июня 2026 г.