MaterializedPostgreSQL
ClickHouse Cloud ユーザーは、PostgreSQL から ClickHouse へのレプリケーションに ClickPipes を使用することを推奨されます。これにより、PostgreSQL 用の高性能な変更データキャプチャ (CDC) がネイティブにサポートされます。
PostgreSQL データベースからテーブルを持つ ClickHouse データベースを作成します。まず、エンジン 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 スキーマ は、(バージョン 21.12 以降)3 つの方法で構成できます。
- 1 つの
MaterializedPostgreSQL
データベースエンジン用の 1 つのスキーマ。設定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
を使用する必要があります。
警告:この場合、テーブル名にドットは許可されません。
要件
-
PostgreSQL 設定ファイルの wal_level 設定は
logical
の値を持ち、max_replication_slots
パラメータは少なくとも2
の値を持つ必要があります。 -
各レプリケートされたテーブルは、以下のいずれかの レプリカアイデンティティ を持っている必要があります:
-
主キー(デフォルト)
-
インデックス
主キーが常に最初にチェックされます。主キーが存在しない場合、レプリカアイデンティティインデックスとして定義されたインデックスがチェックされます。 インデックスがレプリカアイデンティティとして使用される場合、そのテーブルにはそのインデックスが 1 つだけ存在しなければなりません。 特定のテーブルで使用されているタイプを確認するには、以下のコマンドを使用します:
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
に設定すると、同じ PostgreSQL
テーブルを指す複数の MaterializedPostgreSQL
テーブルをセットアップすることができます。
注意事項
論理レプリケーションスロットのフェイルオーバー
プライマリに存在する論理レプリケーションスロットは、スタンバイレプリカでは利用できません。
したがって、フェイルオーバーが発生した場合、新しいプライマリ(古い物理スタンバイ)は、古いプライマリで存在していたスロットについて知ることができません。これにより、PostgreSQL からのレプリケーションが壊れます。
これに対処するためには、レプリケーションスロットを自分で管理し、永続的なレプリケーションスロットを定義する必要があります(詳細情報は こちらにあります)。スロット名を materialized_postgresql_replication_slot
設定を介して渡す必要があり、EXPORT SNAPSHOT
オプションでエクスポートされている必要があります。スナップショット識別子は materialized_postgresql_snapshot
設定を介して渡す必要があります。
これは必要な場合のみ使用することに注意してください。実際に必要ない場合や、その理由を完全に理解していない場合、テーブルエンジンが自分でスロットを作成および管理できるようにする方が良いです。
例(@bchrobot から)
-
PostgreSQL にレプリケーションスロットを設定します。
-
レプリケーションスロットが準備できるのを待ち、その後トランザクションを開始してトランザクションスナップショット識別子をエクスポートします:
-
ClickHouse にデータベースを作成します:
-
ClickHouse DB へのレプリケーションが確認できたら、PostgreSQL トランザクションを終了します。フェイルオーバー後もレプリケーションが続くことを確認します:
必要な権限
-
CREATE PUBLICATION — 作成クエリの特権。
-
CREATE_REPLICATION_SLOT — レプリケーションの特権。
-
pg_drop_replication_slot — レプリケーションの特権またはスーパーユーザー。
-
DROP PUBLICATION — 出版物の所有者(MaterializedPostgreSQL エンジン内の
username
)。
2
および 3
コマンドを実行し、その権限を持たないようにすることは可能です。設定 materialized_postgresql_replication_slot
と materialized_postgresql_snapshot
を使用します。ただし、十分な注意が必要です。
テーブルへのアクセス:
-
pg_publication
-
pg_replication_slots
-
pg_publication_tables