MaterializedPostgreSQL
ClickHouse Cloudユーザーは、PostgreSQLのレプリケーションに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 スキーマは、3つの方法で構成できます(バージョン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
の使用が必要です。
警告:この場合テーブル名にドットは許可されません。
要件
-
PostgreSQL設定ファイルでwal_level設定は
logical
の値を持ち、max_replication_slots
パラメータは少なくとも2
の値を持っている必要があります。 -
各レプリケートされたテーブルは、次のいずれかのレプリカIDを持っていなければなりません:
-
主キー(デフォルト)
-
インデックス
主キーは常に最初にチェックされます。存在しない場合は、レプリカアイデンティティインデックスとして定義されたインデックスがチェックされます。 インデックスがレプリカアイデンティティとして使用される場合、テーブルにはそのようなインデックスが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にデータベースを作成します:
-
PostgreSQLトランザクションを終了し、ClickHouse DBへのレプリケーションが確認されたら、フェイルオーバー後もレプリケーションが続くことを確認します:
必要な権限
-
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