MaterializedPostgreSQL
ClickHouse Cloudユーザーは、ClickPipesを使用してPostgreSQLからClickHouseへのレプリケーションを行うことを推奨します。これはPostgreSQLに対して高性能なChange Data Capture (CDC) をネイティブにサポートします。
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
という名前)が残ります。22.1以前のClickHouseバージョンでテーブルをアタッチする際は、それを手動で削除することを確認してください(SELECT pg_drop_replication_slot('{db_name}_ch_replication_slot_tmp')
)。そうしないとディスク使用量が増加します。この問題は22.1で修正されました。
レプリケーションからテーブルを動的に削除する
特定のテーブルをレプリケーションから削除することが可能です:
PostgreSQLスキーマ
PostgreSQLのschemaは3つの方法で構成できます(バージョン21.12以降)。
- 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
を使用する必要があります。
警告: この場合、テーブル名にドットは許可されていません。
要件
-
wal_levelの設定は
logical
でなければならず、max_replication_slots
のパラメータはPostgreSQLの設定ファイルで少なくとも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
レプリケーション用に一意のレプリケーションコンシューマアイデンティファイアを使用します。デフォルト: 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