MaterializedPostgreSQL
Пользователям ClickHouse Cloud рекомендуется использовать ClickPipes для репликации PostgreSQL в ClickHouse. Это нативно поддерживает высокопроизводительный захват изменений данных (CDC) для PostgreSQL.
Создает базу данных ClickHouse с таблицами из базы данных PostgreSQL. Сначала база данных с движком MaterializedPostgreSQL
создает снимок базы данных PostgreSQL и загружает необходимые таблицы. Необходимые таблицы могут включать любую подсетку таблиц из любой подсетки схем указанной базы данных. Наряду с получением снимка, движок базы данных получает LSN, и как только выполнен начальный дамп таблиц - он начинает получать обновления из WAL. После создания базы данных новые добавленные таблицы в базе данных PostgreSQL не автоматически добавляются в репликацию. Их необходимо добавлять вручную с помощью запроса ATTACH TABLE db.table
.
Репликация реализована с помощью Протокола логической репликации PostgreSQL, который не позволяет реплицировать 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
). Если вы подключаете таблицы в версии ClickHouse до 22.1, убедитесь, что удалили его вручную (SELECT pg_drop_replication_slot('{db_name}_ch_replication_slot_tmp')
). В противном случае использование диска будет расти. Эта проблема исправлена в 22.1.
Динамическое удаление таблиц из репликации
Можно удалить определенные таблицы из репликации:
Схема PostgreSQL
Схема PostgreSQL schema может быть настроена тремя способами (начиная с версии 21.12).
- Одна схема для одного движка базы данных
MaterializedPostgreSQL
. Требуется использование настройкиmaterialized_postgresql_schema
. Таблицы доступны только по имени таблицы:
- Произвольное количество схем с указанным набором таблиц для одного движка базы данных
MaterializedPostgreSQL
. Требуется использование настройкиmaterialized_postgresql_tables_list
. Каждая таблица указывается вместе с ее схемой. Таблицы доступны одновременно по имени схемы и имени таблицы:
Но в этом случае все таблицы в materialized_postgresql_tables_list
должны быть указаны с именем их схемы.
Требуется materialized_postgresql_tables_list_with_schema = 1
.
Предупреждение: для этого случая точки в имени таблицы не допускаются.
- Произвольное количество схем с полным набором таблиц для одного движка базы данных
MaterializedPostgreSQL
. Требуется использование настройкиmaterialized_postgresql_schema_list
.
Предупреждение: для этого случая точки в имени таблицы не допускаются.
Требования
-
Настройка wal_level должна иметь значение
logical
, а параметрmax_replication_slots
должен иметь значение не менее2
в файле конфигурации PostgreSQL. -
Каждая реплицируемая таблица должна иметь один из следующих replica identity:
-
первичный ключ (по умолчанию)
-
индекс
Первичный ключ всегда проверяется в первую очередь. Если он отсутствует, то проверяется индекс, определенный как индекс-идентификатор реплики. Если индекс используется как идентификатор реплики, то в таблице должен быть только один такой индекс. Вы можете проверить, какой тип используется для конкретной таблицы с помощью следующей команды:
Репликация значений 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
Используйте уникальный идентификатор потребителя репликации для репликации. Значение по умолчанию: 0
.
Если установлено в 1
, позволяет настраивать несколько таблиц MaterializedPostgreSQL
, указывающих на одну и ту же таблицу PostgreSQL
.
Примечания
Переключение логического слота репликации
Логические слоты репликации, которые существуют на основном сервере, недоступны на резервных репликах.
Поэтому, если происходит переключение, новый основной сервер (старый физический резерв) не будет знать о любых слотах, которые существовали на старом основном сервере. Это приведет к поломке репликации из PostgreSQL.
Решением этой проблемы является управление слотами репликации самостоятельно и определение постоянного слота репликации (некоторая информация может быть найдена здесь). Вам нужно будет передать имя слота через настройку materialized_postgresql_replication_slot
, и он должен быть экспортирован с помощью опции EXPORT SNAPSHOT
. Идентификатор снимка необходимо передать через настройку materialized_postgresql_snapshot
.
Пожалуйста, обратите внимание, что это должно использоваться только в случае, если это действительно необходимо. Если нет реальной необходимости в этом или полного понимания причин, лучше всего позволить движку таблиц создавать и управлять своим собственным слотом репликации.
Пример (от @bchrobot)
- Настройте слот репликации в PostgreSQL.
- Дождитесь готовности слота репликации, затем начните транзакцию и экспортируйте идентификатор снимка транзакции:
- В ClickHouse создайте базу данных:
- Завершите транзакцию PostgreSQL, как только репликация в базу данных ClickHouse будет подтверждена. Убедитесь, что репликация продолжается после переключения:
Требуемые разрешения
-
CREATE PUBLICATION -- привилегия на создание запроса.
-
CREATE_REPLICATION_SLOT -- привилегия репликации.
-
pg_drop_replication_slot -- привилегия репликации или суперпользователя.
-
DROP PUBLICATION -- владелец публикации (
username
в самом движке MaterializedPostgreSQL).
Можно избежать выполнения команд 2
и 3
и получения этих разрешений. Используйте настройки materialized_postgresql_replication_slot
и materialized_postgresql_snapshot
. Но будьте очень осторожны.
Доступ к таблицам:
-
pg_publication
-
pg_replication_slots
-
pg_publication_tables