16 KiB
slug | sidebar_label | sidebar_position |
---|---|---|
/ja/engines/database-engines/materialized-postgresql | MaterializedPostgreSQL | 60 |
[experimental] MaterializedPostgreSQL
PostgreSQL データベースからテーブルを ClickHouse データベースとして作成します。最初に、MaterializedPostgreSQL
エンジンを使って PostgreSQL データベースのスナップショットを作成し、必要なテーブルをロードします。必要なテーブルには、指定されたデータベース内の任意のスキーマの任意のサブセットのテーブルを含めることができます。スナップショットの取得と同時に、データベースエンジンは LSN を取得し、テーブルの初期ダンプが行われると、WAL から更新をプルし始めます。データベースが作成されると、PostgreSQL データベースに新しく追加されたテーブルは自動的にレプリケーションに追加されません。それらは ATTACH TABLE db.table
クエリを使用して手動で追加する必要があります。
レプリケーションは PostgreSQL の論理レプリケーションプロトコルで実装されています。これにより、DDL のレプリケートはできませんが、レプリケーションを壊す変更(カラム型の変更、カラムの追加/削除)が発生したかどうかを知ることができます。このような変更が検出されると、該当するテーブルの更新受信が停止します。この場合、テーブルを完全に再読み込みするには ATTACH
/DETACH PERMANENTLY
クエリを使用する必要があります。もし DDL がレプリケーションを壊さなければ(例えば、カラムの名前変更)、テーブルは更新を受信し続けます(挿入は位置で行われます)。
:::note
このデータベースエンジンはエクスペリメンタルです。使用するには、構成ファイルで allow_experimental_database_materialized_postgresql
を 1 に設定するか、SET
コマンドを使用します:
SET allow_experimental_database_materialized_postgresql=1
:::
データベースの作成
CREATE DATABASE [IF NOT EXISTS] db_name [ON CLUSTER cluster]
ENGINE = MaterializedPostgreSQL('host:port', 'database', 'user', 'password') [SETTINGS ...]
エンジンパラメータ
host:port
— PostgreSQL サーバーエンドポイント。database
— PostgreSQL データベース名。user
— PostgreSQL ユーザー。password
— ユーザーパスワード。
使用例
CREATE DATABASE postgres_db
ENGINE = MaterializedPostgreSQL('postgres1:5432', 'postgres_database', 'postgres_user', 'postgres_password');
SHOW TABLES FROM postgres_db;
┌─name───┐
│ table1 │
└────────┘
SELECT * FROM postgresql_db.postgres_table;
新しいテーブルを動的にレプリケーションに追加
MaterializedPostgreSQL
データベースが作成された後、対応する PostgreSQL データベースの新しいテーブルは自動的に検出されません。これらのテーブルは手動で追加できます:
ATTACH TABLE postgres_database.new_table;
:::warning
バージョン 22.1 以前では、レプリケーションにテーブルを追加すると、削除されない一時的なレプリケーションスロット({db_name}_ch_replication_slot_tmp
と命名)が残ります。22.1 より前の ClickHouse バージョンでテーブルをアタッチする場合は、手動で削除することを確認してください(SELECT pg_drop_replication_slot('{db_name}_ch_replication_slot_tmp')
)。さもないと、ディスク使用量が増加します。この問題は 22.1 で修正されました。
:::
レプリケーションからのテーブルを動的に削除
特定のテーブルをレプリケーションから削除することができます:
DETACH TABLE postgres_database.table_to_remove PERMANENTLY;
PostgreSQL スキーマ
PostgreSQL スキーマ は 3 つの方法で設定できます(バージョン 21.12 以降)。
MaterializedPostgreSQL
データベースエンジンに対して 1 つのスキーマ。設定materialized_postgresql_schema
を使用する必要があります。 テーブルへのアクセスはテーブル名のみを介します:
CREATE DATABASE postgres_database
ENGINE = MaterializedPostgreSQL('postgres1:5432', 'postgres_database', 'postgres_user', 'postgres_password')
SETTINGS materialized_postgresql_schema = 'postgres_schema';
SELECT * FROM postgres_database.table1;
- 任意の数のスキーマと指定されたテーブルセットを持つ
MaterializedPostgreSQL
データベースエンジン。設定materialized_postgresql_tables_list
を使用する必要があります。それぞれのテーブルはスキーマと共に書かれます。 テーブルへのアクセスはスキーマ名とテーブル名を同時に指定して行われます:
CREATE DATABASE database1
ENGINE = MaterializedPostgreSQL('postgres1:5432', 'postgres_database', 'postgres_user', 'postgres_password')
SETTINGS materialized_postgresql_tables_list = 'schema1.table1,schema2.table2,schema1.table3',
materialized_postgresql_tables_list_with_schema = 1;
SELECT * FROM database1.`schema1.table1`;
SELECT * FROM database1.`schema2.table2`;
しかし、この場合、materialized_postgresql_tables_list
にあるすべてのテーブルはスキーマ名と一緒に書かれる必要があります。
materialized_postgresql_tables_list_with_schema = 1
が必要です。
注意: この場合、テーブル名にドットは許可されません。
- 任意の数のスキーマを持ち、全テーブルを設定する
MaterializedPostgreSQL
データベースエンジン。設定materialized_postgresql_schema_list
を使用する必要があります。
CREATE DATABASE database1
ENGINE = MaterializedPostgreSQL('postgres1:5432', 'postgres_database', 'postgres_user', 'postgres_password')
SETTINGS materialized_postgresql_schema_list = 'schema1,schema2,schema3';
SELECT * FROM database1.`schema1.table1`;
SELECT * FROM database1.`schema1.table2`;
SELECT * FROM database1.`schema2.table2`;
注意: この場合、テーブル名にドットは許可されません。
必要条件
-
wal_level 設定は
logical
の値を持ち、max_replication_slots
パラメータは PostgreSQL 設定ファイルで少なくとも2
の値を持つ必要があります。 -
それぞれのレプリケートされたテーブルは次のいずれかの レプリカアイデンティティ を持つ必要があります:
-
主キー(デフォルト)
-
インデックス
postgres# CREATE TABLE postgres_table (a Integer NOT NULL, b Integer, c Integer NOT NULL, d Integer, e Integer NOT NULL);
postgres# CREATE unique INDEX postgres_table_index on postgres_table(a, c, e);
postgres# ALTER TABLE postgres_table REPLICA IDENTITY USING INDEX postgres_table_index;
主キーは常に最初にチェックされます。存在しない場合、レプリカアイデンティティインデックスとして定義されたインデックスがチェックされます。インデックスはレプリカアイデンティティとして使用される場合、テーブル内に一つだけ存在する必要があります。 特定のテーブルでどのタイプが使用されるかを確認するには、次のコマンドを使用します:
postgres# SELECT CASE relreplident
WHEN 'd' THEN 'default'
WHEN 'n' THEN 'nothing'
WHEN 'f' THEN 'full'
WHEN 'i' THEN 'index'
END AS replica_identity
FROM pg_class
WHERE oid = 'postgres_table'::regclass;
:::note TOAST 値のレプリケーションはサポートされていません。デフォルトではデータ型のデフォルト値が使用されます。 :::
設定
materialized_postgresql_tables_list
PostgreSQL データベーステーブルのカンマ区切りリストを設定します。これらのテーブルは [MaterializedPostgreSQL](../../engines/database-engines/materialized-postgresql.md) データベースエンジンを介してレプリケートされます。
各テーブルは、括弧内にレプリケートされたカラムのサブセットを持つことができます。カラムのサブセットが省略された場合、テーブルのすべてのカラムがレプリケートされます。
``` sql
materialized_postgresql_tables_list = 'table1(co1, col2),table2,table3(co3, col5, col7)
```
デフォルト値: 空のリスト — 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 テーブルの初期ダンプ](../../engines/database-engines/materialized-postgresql.md)が実行されます。`materialized_postgresql_replication_slot` と一緒に使用する必要があります。
``` sql
CREATE DATABASE database1
ENGINE = MaterializedPostgreSQL('postgres1:5432', 'postgres_database', 'postgres_user', 'postgres_password')
SETTINGS materialized_postgresql_tables_list = 'table1,table2,table3';
SELECT * FROM database1.table1;
```
設定は DDL クエリを使用して必要に応じて変更できます。ただし、`materialized_postgresql_tables_list` 設定は変更できません。この設定でテーブルのリストを更新するには、`ATTACH TABLE` クエリを使用してください。
``` sql
ALTER DATABASE postgres_database MODIFY SETTING materialized_postgresql_max_block_size = <new_size>;
```
materialized_postgresql_use_unique_replication_consumer_identifier
レプリケーションのためにユニークなレプリケーションコンシューマ識別子を使用します。デフォルト: 0
。
もし 1
に設定すると、同じ PostgreSQL
テーブルを指し示す複数の MaterializedPostgreSQL
テーブルを設定することができます。
注意事項
論理レプリケーションスロットのフェイルオーバー
プライマリに存在する論理レプリケーションスロットは、スタンバイレプリカでは利用できません。
したがって、フェイルオーバーが発生した場合、新しいプライマリ(古い物理スタンバイ)は、古いプライマリで存在していたスロットを認識しません。これは PostgreSQL からのレプリケーションを壊すことになります。
これを解決する方法の一つは、レプリケーションスロットを自分で管理し、永続的なレプリケーションスロットを定義することです(いくつかの情報はこちらで見つけることができます)。materialized_postgresql_replication_slot
設定を通じてスロット名を渡す必要があり、EXPORT SNAPSHOT
オプションでエクスポートされる必要があります。スナップショット識別子は materialized_postgresql_snapshot
設定を通じて渡す必要があります。
注意すべきは、本当に必要な場合のみこれを使用すべきであるということです。これを行う具体的な必要性や完全な理解がない限り、テーブルエンジンが独自にレプリケーションスロットを作成し管理することを許可した方が良いです。
例(@bchrobot より)
-
PostgreSQL でレプリケーションスロットを設定します。
apiVersion: "acid.zalan.do/v1" kind: postgresql metadata: name: acid-demo-cluster spec: numberOfInstances: 2 postgresql: parameters: wal_level: logical patroni: slots: clickhouse_sync: type: logical database: demodb plugin: pgoutput
-
レプリケーションスロットが準備されるのを待ち、トランザクションを開始し、トランザクションスナップショット識別子をエクスポートします:
BEGIN; SELECT pg_export_snapshot();
-
ClickHouse でデータベースを作成します:
CREATE DATABASE demodb ENGINE = MaterializedPostgreSQL('postgres1:5432', 'postgres_database', 'postgres_user', 'postgres_password') SETTINGS materialized_postgresql_replication_slot = 'clickhouse_sync', materialized_postgresql_snapshot = '0000000A-0000023F-3', materialized_postgresql_tables_list = 'table1,table2,table3';
-
PostgreSQL トランザクションを終了したら、ClickHouse DB へのレプリケーションが確認されます。フェイルオーバー後もレプリケーションが続くことを確認します:
kubectl exec acid-demo-cluster-0 -c postgres -- su postgres -c 'patronictl failover --candidate acid-demo-cluster-1 --force'
必要な権限
-
CREATE PUBLICATION -- 作成クエリ権限。
-
CREATE_REPLICATION_SLOT -- レプリケーション権限。
-
pg_drop_replication_slot -- レプリケーション権限またはスーパーユーザー。
-
DROP PUBLICATION -- パブリケーションの所有者(
MaterializedPostgreSQL
エンジン内のusername
)。
materialized_postgresql_replication_slot
と materialized_postgresql_snapshot
設定を使用することで、コマンド 2
および 3
の実行とその権限を避けることが可能です。ただし、非常に注意が必要です。
テーブルへのアクセス権:
-
pg_publication
-
pg_replication_slots
-
pg_publication_tables