PolarDB for PostgreSQL のビジネスデータに対して全文検索や複雑な分析を実行する必要がある場合、データベース上でこれらの操作を直接実行すると、コアサービスの安定性に影響を与える可能性があります。PolarDB for PostgreSQL が提供する AutoETL 機能は、同じクラスター内の読み取り/書き込みノードから PolarSearch ノードにデータを自動的かつ継続的に同期し、ワンストップのデータサービスを提供します。検索および分析ワークロードをオンラインランザクション処理ワークロードから分離しながら、別の ETL ツールをデプロイまたはメンテナンスすることなくデータを同期できます。
AutoETL を使用してパイプラインを作成すると、デフォルトで AutoETL エンジンがデータ同期のために PolarDB データにアクセスすることを承認したことになります。
機能概要
AutoETL は、PolarDB for PostgreSQL に組み込まれたデータ同期機能です。これにより、クラスター内の異なるタイプのノード間でデータが自動的に流れるようになります。現在のバージョンでは、高性能な検索と分析のために、同じクラスター内の PolarDB for PostgreSQL から PolarSearch ノードへのデータ同期のみサポートしています。
組み込みの DBMS_ETL ツールキットを使用して、SQL コマンドで直接データ同期パイプラインを作成および管理できます。AutoETL は、3 つの柔軟なデータ同期方法を提供します:
-
単一テーブル同期 (
dbms_etl.sync_by_table):単一のソーステーブルを宛先インデックスに完全に同期します。 -
複数テーブル集約 (
dbms_etl.sync_by_map):JOIN操作を使用して複数のソーステーブルを集約し、その結果を宛先インデックスに同期します。 -
カスタム SQL (
dbms_etl.sync_by_sql):Flink SQL 互換の構文を使用して、複雑なデータクレンジング、変換、集約を行います。
適用範囲
AutoETL 機能を使用する前に、次の要件を満たしていることを確認してください:
-
クラスターバージョン:
-
PostgreSQL 16 (マイナーエンジンバージョン 2.0.16.11.15.0 以降)
-
PostgreSQL 14 (マイナーエンジンバージョン 2.0.14.22.43.0 以降)
-
-
同期方向:データは、同じクラスター内の PolarDB for PostgreSQL から PolarSearch ノードへのみ同期できます。
-
DDL 制限:同期パイプラインに含まれるソーステーブルに対して DDL 操作を実行することはできません。テーブルを変更するには、ETL パイプラインを再作成する必要があります。
-
コンピューティングリソース:AutoETL は、コンピューティングユニットとして CU (コンピューティングユニット) を使用します。デフォルトでは、クラスターの CU 数は、クラスター内のすべての PolarSearch ノードの CPU 合計の 2 倍です。コンソールの ページの [AutoETL] タブで、クラスターが使用する CU 数を確認できます。
同期パイプラインの作成
単一テーブル同期
-
データ準備
PolarDB for PostgreSQL で、次の SQL 文を実行してサンプルデータベースとテーブルを作成し、テストデータを挿入します。
CREATE SCHEMA IF NOT EXISTS db1; CREATE TABLE IF NOT EXISTS db1.t1 ( id INT PRIMARY KEY, c1 VARCHAR(100), c2 VARCHAR(100) ); INSERT INTO db1.t1(id, c1, c2) VALUES (1, 'apple', 'red'), (2, 'banana', 'yellow'), (3, 'grape', 'purple'); -
同期パイプラインの作成
dbms_etl.sync_by_tableストアドプロシージャを使用して、db1.t1テーブルから PolarSearch ノード上のdestインデックスへの同期タスクを作成します。構文
SELECT dbms_etl.sync_by_table('search', '<source_table>', '<sink_table>', '<column_list>');パラメーター
パラメーター
説明
search同期先。これは
searchに固定されており、PolarSearch ノードを表します。<source_table>ソーステーブルの名前。
SchemaName.TableName形式です。<sink_table>PolarSearch ノードの宛先インデックスの名前。
<column_list>同期する列名のリスト。コンマ (
,) で区切ります。空の文字列 ("") の場合、ソーステーブルのすべての列が同期されます。制限
-
ソーステーブルには、プライマリキーまたは一意キーが必要です。
-
column_listを指定する場合、プライマリキーまたは一意キーを含める必要があります。 -
異なる同期パイプラインで同じソーステーブルまたは宛先テーブルを使用しないでください。
-
パイプラインの作成後、ソーステーブルに追加した新しい列は自動的に同期されません。新しい列を同期するには、パイプラインを再作成する必要があります。
-
宛先インデックスにカスタム設定を使用したい場合は、同期パイプラインを作成する前に、PolarSearch ノードでインデックスを作成し、その設定を定義します。パイプライン作成時に宛先インデックスが存在しない場合、システムが自動的に作成します。
例
-
db1.t1テーブル全体を PolarSearch のdestインデックスに同期する:SELECT dbms_etl.sync_by_table('search', 'db1.t1', 'dest', ''); -
db1.t1テーブルのid列とc1列をdest1インデックスに同期する:SELECT dbms_etl.sync_by_table('search', 'db1.t1', 'dest1', 'id, c1'); -
db1.t1テーブルのid列とc1列をdest2インデックスに同期し、フィールド名のマッピングを指定する (idをd_idに、c1をd_c1にマッピングします):SELECT dbms_etl.sync_by_table('search', 'db1.t1', 'dest2', 'd_id(id), d_c1(c1)');
-
-
データの検証
PolarSearch ノードに接続し、Elasticsearch 互換の REST API を使用してクエリを実行し、データが同期されているか確認します。
# <polarsearch_endpoint> を PolarSearch ノードのエンドポイントに置き換えます curl -u <user>:<password> -X GET "http://<polarsearch_endpoint>/dest/_search"
複数テーブル集約
-
データ準備
PolarDB for PostgreSQL で、次の SQL 文を実行してサンプルデータベースとテーブルを作成し、テストデータを挿入します。
CREATE SCHEMA IF NOT EXISTS db2; CREATE SCHEMA IF NOT EXISTS db3; CREATE SCHEMA IF NOT EXISTS db4; CREATE TABLE IF NOT EXISTS db2.t2 (id INT PRIMARY KEY, c2 INT); CREATE TABLE IF NOT EXISTS db3.t3 (id INT PRIMARY KEY, c3 VARCHAR(10)); CREATE TABLE IF NOT EXISTS db4.t4 (id INT PRIMARY KEY, c4 INT); INSERT INTO db2.t2(id, c2) VALUES (1, 111), (2, 222), (4, 444); INSERT INTO db3.t3(id, c3) VALUES (1, 'aaa'), (3, 'ccc'), (4, 'ddd'); INSERT INTO db4.t4(id, c4) VALUES (1, 11), (2, 22), (3, 33); -
同期パイプラインの作成
dbms_etl.sync_by_mapストアドプロシージャを使用して、複数のテーブルからデータを JOIN し、PolarSearch ノードのインデックスに集約します。構文
SELECT dbms_etl.sync_by_map( 'search', '<columns_map>', -- 宛先インデックスのフィールドとソーステーブルのフィールドのマッピング '<join_fields>', -- テーブル間の JOIN キー '<join_types>', -- JOIN タイプ (inner, left) '<filter>' -- データフィルター条件 );パラメーター
パラメーター
書式例
説明
columns_mapdest.c4(db4.t4.c4),dest.c2(db2.t2.c2)宛先インデックスのフィールドとソーステーブルのフィールド間のマッピング。
この例では、宛先インデックス
destのc4フィールドはdb4.t4.c4から、c2フィールドはdb2.t2.c2から取得されます。join_fieldsdest.id=db4.t4.id,db2.t2.idテーブル間の JOIN キー。
この例では、宛先インデックスのドキュメント ID (
dest.id) はdb4.t4.idとdb2.t2.idで構成されます。db4.t4.idとdb2.t2.idは JOIN 条件でもあります。join_typesinner,leftテーブル間の JOIN タイプ。JOIN の順序は
join_fieldsのテーブルの順序に対応します。この例では、t4 INNER JOIN t2を実行し、その結果にt3 を LEFT JOIN します。filterdb4.t4.c4 > 10 AND db2.t2.c2 < 100標準の SQL
WHERE句で、同期前にソーステーブルのデータをフィルター処理するために使用します。制限
-
同期対象のすべてのソーステーブルには、プライマリキーが必要です。
-
この機能はストリーム処理を使用します。同期中は結果整合性のみが保証されます。
-
宛先インデックスの更新モードは、delete then insert です。
例
-
2 つのテーブルの
INNER JOIN:db4.t4とdb2.t2の間でidフィールドに対して INNER JOIN を実行し、t4.c4とt2.c2をdestインデックスのc4フィールドとc2フィールドに同期します。SELECT dbms_etl.sync_by_map( 'search', 'dest.c4(db4.t4.c4),dest.c2(db2.t2.c2)', 'dest.id=db4.t4.id,db2.t2.id', 'inner', '' ); -
複数のテーブルでの混合
JOINとフィルター:3 つのテーブルdb4.t4、db2.t2、db3.t3を JOIN します。t4とt2の間でINNER JOINを実行し、t4とt3の間でLEFT JOINを実行します。その後、データはt4.c4 > 10かつt2.c2 < 100の条件でフィルター処理されます。SELECT dbms_etl.sync_by_map( 'search', 'dest.c4(db4.t4.c4),dest.c2(db2.t2.c2),dest.c3(db3.t3.c3)', 'dest.id=db4.t4.id,db2.t2.id,db3.t3.id', 'inner,left', 'db4.t4.c4 > 10 and db2.t2.c2 < 100' );
-
-
データの検証
PolarSearch ノードに接続し、Elasticsearch 互換の REST API を使用してクエリを実行し、データが同期されているか確認します。
# <polarsearch_endpoint> を PolarSearch ノードのエンドポイントに置き換えます curl -u <user>:<password> -X GET "http://<polarsearch_endpoint>/dest/_search"
カスタム SQL
-
データ準備
PolarDB for PostgreSQL で、次の SQL 文を実行してサンプルデータベースとテーブルを作成し、テストデータを挿入します。
CREATE SCHEMA IF NOT EXISTS syncbysql_test; CREATE TABLE IF NOT EXISTS syncbysql_test.test_source ( id SERIAL PRIMARY KEY, polardb_document JSONB NOT NULL ); INSERT INTO syncbysql_test.test_source (polardb_document) VALUES ('{ "mailTemplateId": {"S": "TPL-001"}, "title": {"S": "Welcome Registration Notification"}, "createdAt": {"S": "2026-01-15 10:30:00"}, "updatedAt": {"S": "2026-01-15 10:30:00"} }'), ('{ "mailTemplateId": {"S": "TPL-002"}, "title": {"S": "Order Confirmation Email"}, "createdAt": {"S": "2026-02-01 14:20:00"}, "updatedAt": {"S": "2026-02-10 09:15:00"} }'), ('{ "mailTemplateId": {"S": "TPL-003"}, "title": {"S": "Password Reset Reminder"}, "createdAt": {"S": "2026-02-20 08:00:00"}, "updatedAt": {"S": "2026-03-01 16:45:00"} }'); -
同期パイプラインの作成
複雑な変換、集約、または計算が必要なシナリオでは、
dbms_etl.sync_by_sqlストアドプロシージャが Flink SQL 構文をサポートし、データ同期ロジックを定義します。重要セキュリティ警告:SQL 文にパスワードをハードコーディングしないでください。次の例は構文を示すためのものです。この例の
WITH句には平文のパスワードが含まれており、これは重大なセキュリティリスクです。本番環境では、より安全な方法で認証情報を管理してください。構文
SELECT dbms_etl.sync_by_sql('search', '<sync_sql>');例
syncbysql_testのtest_sourceテーブルからpolardb_documentJSON フィールドの値を PolarSearch に書き込みます。システムは、SQL 文内のプレースホルダー
{postgresql_host}、{postgresql_port}、{postgresql_user}、{postgresql_password}、{search_host}、{search_port}、{search_user}、および{search_password}を自動的に置換します。SQL 文では、これらの固定プレースホルダーを使用するだけで済みます。select dbms_etl.sync_by_sql( 'search', 'CREATE TEMPORARY TABLE test_source_for_sync ( polardb_document STRING ) WITH ( ''schema-name'' = ''syncbysql_test'', -- テーブルのスキーマ名に置き換えます ''database-name'' = ''testdb'', -- テーブルが属するデータベース名に置き換えます ''connector''= ''postgres-cdc'', ''hostname'' = ''{pg_host}'', ''port'' = ''{pg_port}'', ''username'' = ''{pg_user}'', ''password'' = ''{pg_password}'', ''table-name'' = ''test_source'', -- 同期するテーブル名に置き換えます ''slot.name'' = ''test_slot_3'', -- 名前をカスタマイズします。この例では test_slot_3 を使用します。 ''decoding.plugin.name'' = ''pgoutput'' ); CREATE TEMPORARY TABLE test_source_opensearch ( mail_template_id STRING, title STRING, created_at STRING, updated_at STRING, PRIMARY KEY (mail_template_id) NOT ENFORCED ) WITH ( ''connector'' = ''opensearch'', ''hosts'' = ''{search_host}'', ''index'' = ''test_source_opensearch'', ''username'' = ''{search_user}'', ''password'' = ''{search_password}'' ); INSERT INTO test_source_opensearch SELECT -- インポートするプロパティに応じてこのセクションを変更します JSON_VALUE(polardb_document, ''$.mailTemplateId.S'') AS mail_template_id, JSON_VALUE(polardb_document, ''$.title.S'') AS title, JSON_VALUE(polardb_document, ''$.createdAt.S'') AS created_at, JSON_VALUE(polardb_document, ''$.updatedAt.S'') AS updated_at FROM test_source_for_sync WHERE JSON_VALUE(polardb_document, ''$.mailTemplateId.S'') IS NOT NULL; ') AS sync_id; -
データの検証
PolarSearch ノードに接続し、Elasticsearch 互換の REST API を使用してクエリを実行し、データが同期されているか確認します。
# <polarsearch_endpoint> を PolarSearch ノードのエンドポイントに置き換えます curl -u <user>:<password> -X GET "http://<polarsearch_endpoint>/test_source_opensearch/_search"
同期パイプラインの管理
次のコマンドを使用して、同期パイプラインを表示または削除できます。
パイプラインの表示
-
すべてのパイプラインを表示する:
SELECT dbms_etl.show_sync_link(); -
ID で特定のパイプラインを表示する:
<sync_id>をステップ 2 で返された ID に置き換えます。SELECT dbms_etl.show_sync_link_by_id('<sync_id>');
パイプラインの削除
同期パイプラインの削除は高リスク操作です。続行する前に、操作を確認してください。この操作はパイプラインのデータ同期を停止し、関連リソースをクリーンアップしますが、PolarSearch のインデックスデータは削除しません。
この操作は、データ同期を停止し、関連リソースをクリーンアップします。
SELECT dbms_etl.drop_sync_link('<sync_id>');
システムは、パイプラインの状態に応じて drop_sync_link コマンドを異なる方法で処理します:
-
active状態のパイプラインは、まずステータスがdroppingに変わります。システムがパイプラインリソースと宛先インデックスデータをクリーンアップした後、ステータスはdroppedに変わります。 -
パイプラインが
dropped状態の場合、システムはそのパイプラインの情報を完全にパージします。 -
システムは、他の状態のパイプラインの削除をサポートしていません。