すべてのプロダクト
Search
ドキュメントセンター

PolarDB:ETL ストアドプロシージャ

最終更新日:Aug 28, 2026

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 数を確認できます。

同期パイプラインの作成

単一テーブル同期

  1. データ準備

    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');
  2. 同期パイプラインの作成

    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)');
  3. データの検証

    PolarSearch ノードに接続し、Elasticsearch 互換の REST API を使用してクエリを実行し、データが同期されているか確認します。

    # <polarsearch_endpoint> を PolarSearch ノードのエンドポイントに置き換えます
    curl -u <user>:<password> -X GET "http://<polarsearch_endpoint>/dest/_search"

複数テーブル集約

  1. データ準備

    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);
  2. 同期パイプラインの作成

    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_map

    dest.c4(db4.t4.c4),dest.c2(db2.t2.c2)

    宛先インデックスのフィールドとソーステーブルのフィールド間のマッピング。

    この例では、宛先インデックス dest の c4 フィールドは db4.t4.c4 から、c2 フィールドは db2.t2.c2 から取得されます。

    join_fields

    dest.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_types

    inner,left

    テーブル間の JOIN タイプ。JOIN の順序は join_fields のテーブルの順序に対応します。この例では、t4 INNER JOIN t2 を実行し、その結果に t3 を LEFT JOIN します。

    filter

    db4.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'
      );
  3. データの検証

    PolarSearch ノードに接続し、Elasticsearch 互換の REST API を使用してクエリを実行し、データが同期されているか確認します。

    # <polarsearch_endpoint> を PolarSearch ノードのエンドポイントに置き換えます
    curl -u <user>:<password> -X GET "http://<polarsearch_endpoint>/dest/_search"

カスタム SQL

  1. データ準備

    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"}
      }');
  2. 同期パイプラインの作成

    複雑な変換、集約、または計算が必要なシナリオでは、dbms_etl.sync_by_sql ストアドプロシージャが Flink SQL 構文をサポートし、データ同期ロジックを定義します。

    重要

    セキュリティ警告:SQL 文にパスワードをハードコーディングしないでください。次の例は構文を示すためのものです。この例の WITH 句には平文のパスワードが含まれており、これは重大なセキュリティリスクです。本番環境では、より安全な方法で認証情報を管理してください。

    構文

    SELECT dbms_etl.sync_by_sql('search', '<sync_sql>');

    例

    syncbysql_test の test_source テーブルから polardb_document JSON フィールドの値を 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;
  3. データの検証

    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 状態の場合、システムはそのパイプラインの情報を完全にパージします。

  • システムは、他の状態のパイプラインの削除をサポートしていません。

よくある質問

PolarDB テーブルのフィールドを PolarSearch ノード のインデックスフィールドにマッピングするにはどうすればよいですか?

AutoETL は、2 つのフィールドマッピング方法を提供します:

  • 暗黙的なマッピング (sync_by_table):sync_by_table を使用する場合、PolarSearch ノードのインデックスのフィールド名は、デフォルトで PolarDB for PostgreSQL ソーステーブルの列名になります。<column_list> パラメーターを使用して、作成および同期する列を指定できます。

  • 明示的なマッピング (sync_by_map):フィールド名を変更したり、複数のテーブルを集約したりする場合、sync_by_map の <columns_map> パラメーターを使用して、同期先フィールドとソーステーブル列の間のマッピングを明示的に定義できます。たとえば、dest.title(db1.posts.post_title) は、db1.posts テーブルの post_title 列が dest インデックスの title フィールドにマッピングすることを示します。