Postgres CDC コネクタは、まず PostgreSQL データベースの完全なスナップショットを読み取り、後続の変更データをキャプチャします。これにより、 exactly-once 処理セマンティクスを保証します。本ドキュメントでは、 Postgres CDC コネクタの設定方法と使用方法について説明します。
概要
Postgres CDC コネクタは、次の機能をサポートしています:
|
カテゴリ |
詳細 |
|
サポートされているタイプ |
SQL ソース、Flink CDC ソース 説明
シンクテーブルとルックアップ (ディメンション) テーブルには、JDBC コネクタを使用します。 |
|
実行モード |
ストリーミング |
|
データフォーマット |
該当なし |
|
メトリクス |
|
|
API タイプ |
SQL と Flink CDC |
|
シンクの更新/削除 |
該当なし |
特徴
Postgres CDC コネクタは、 Ververica Runtime (VVR) 8.0.6 以降で利用可能な、変更データキャプチャ (CDC) 用のインクリメンタルスナップショットフレームワークと統合されています。完全な履歴データを読み取った後、コネクタは先行書き込みログ (WAL) からの変更ログの読み取りに自動的に切り替わります。このプロセスは、 exactly-once セマンティクスを保証します。Postgres CDC ソーステーブルは、完全データの並行かつロックフリーの読み取り、およびブレークポイントからのレジューム可能な読み取りをサポートします。
主な特徴と利点:
-
ストリーム処理とバッチ処理の統合。コネクタは完全データと増分データの両方を読み取るため、2 つのジョブを個別に実行する必要がなくなります。
-
完全データの並行読み取り。水平スケーリングにより、読み取りパフォーマンスを向上できます。
-
完全データの読み取りから増分読み取りへのシームレスな切り替え。コネクタは自動的にスケールインし、リソース使用量を削減します。
-
レジューム可能な読み取り。コネクタはスナップショットフェーズ中にブレークポイントから再開できるため、ジョブの安定性が向上します。
-
ロックフリーの読み取り。完全データの読み取りではロックが不要なため、オンライン業務への影響を防ぎます。
前提条件
Postgres CDC コネクタは、PostgreSQL の 論理レプリケーション 機能を使用して、変更データキャプチャ (CDC) ストリームを読み取ります。このコネクタは、ApsaraDB RDS for PostgreSQL、Amazon RDS for PostgreSQL、およびセルフマネージド PostgreSQL をサポートしています。
必要な設定は、ApsaraDB RDS for PostgreSQL、Amazon RDS for PostgreSQL、またはセルフマネージド PostgreSQL のいずれを使用するかによって異なります。詳細な手順については、「Postgres の設定」 ドキュメントをご参照ください。
設定が完了したら、次の条件が満たされていることを確認してください:
-
wal_level パラメータが
logicalに設定されている必要があります。この設定は、論理デコーディングをサポートするために必要な情報を先行書き込みログ (WAL) に追加します。 -
サブスクライブ対象のテーブルの レプリカアイデンティティ が
FULLに設定されている必要があります。この設定により、INSERTイベントとUPDATEイベントに、テーブル内のすべての列の以前の値が含まれるようになり、データの整合性が保証されます。説明REPLICA IDENTITYは、PostgreSQL 固有のテーブルレベルの設定です。これにより、INSERTイベントとUPDATEイベントに、影響を受ける列の以前の値が含まれるかどうかが決まります。詳細については、「レプリカアイデンティティ」をご参照ください。 -
max_wal_sendersパラメータとmax_replication_slotsパラメータの値が、現在使用中のレプリケーションスロット数と Flink ジョブで必要なスロット数の合計よりも大きいことを確認してください。 -
アカウントに
SUPERUSER権限、またはLOGIN権限とREPLICATION権限の両方があることを確認してください。また、アカウントには、完全なデータをクエリするために、サブスクライブ対象のテーブルに対するSELECT権限も必要です。
-
Postgres テーブルに生成列が含まれている場合は、スロットの作成時に publish_generated_columns パラメータを
trueに設定してください。そうしないと、スナップショットフェーズで読み取られたテーブルスキーマが、増分フェーズで読み取られたスキーマと異なる場合があります。
注意事項
PostgreSQL CDC のインクリメンタルスナップショット機能は、VVR V8.0.6 以降で利用できます。
レプリケーションスロット
Flink PostgreSQL CDC ジョブは、レプリケーションスロットを使用して、先行書き込みログ (WAL) が早期にパージされるのを防ぎ、データ整合性を確保します。レプリケーションスロットが不適切に管理されていると、過剰なディスク使用量やデータ読み取りの遅延などの問題を引き起こす可能性があります。以下のベストプラクティスに従ってください:
-
未使用スロットの速やかなクリーンアップ
-
Flink は、ジョブが停止したり、ステートレスな再起動を実行したりした後でも、レプリケーションスロットを自動的に削除しません。これは、WAL がパージされた場合に発生する可能性のあるデータ損失を防ぐためです。
-
ジョブが再起動されないことを確認した場合は、関連するレプリケーションスロットを手動で削除して、ディスク領域を解放する必要があります。
説明ライフサイクル管理: レプリケーションスロットをジョブレベルのリソースとして扱い、ジョブの開始と停止に合わせて管理してください。
-
-
古いスロットの再利用を避ける
-
新しいジョブでは、古いスロット名を再利用するのではなく、新しいスロット名を使用する必要があります。古いスロットを再利用すると、ジョブが起動時に大量の履歴 WAL データを読み取ることになり、新しいデータの処理が遅延する可能性があります。
-
PostgreSQL の論理レプリケーションでは、1 つのスロットは 1 つの接続でしか使用できません。異なるジョブは、異なるスロット名を使用する必要があります。
説明命名規則:
slot.nameをカスタマイズする際、一時的なスロットとの競合を避けるため、my_slot_1のように末尾に数字が付く名前は避けてください。
-
-
インクリメンタルスナップショットが有効な場合のスロットの動作
-
前提条件: チェックポイントが有効であり、ソーステーブルに主キーが定義されている必要があります。
-
スロット作成ルール:
-
インクリメンタルスナップショットが無効な場合: 並列度 1 のみサポートされます。1 つのグローバルスロットが使用されます。
-
インクリメンタルスナップショットが有効な場合:
-
スナップショットフェーズ: 各並行ソースサブタスクは一時的なスロットを作成します。命名形式は
${slot.name}_${task_id}です。 -
インクリメンタルフェーズ: すべての一時的なスロットは自動的に回収されます。グローバルスロットが 1 つだけ保持されます。
-
-
-
最大スロット数: ソースの並列度 + 1 (スナップショットフェーズ中)
-
-
リソースとパフォーマンス
-
PostgreSQL で利用可能なスロット数やディスク容量に制限がある場合は、スナップショットフェーズの並列度を下げて、使用する一時スロットの数を減らしてください。これにより、スナップショットフェーズ中の読み取り速度は低下します。
-
ダウンストリームシンクがべき等な書き込みをサポートしている場合は、
scan.incremental.snapshot.backfill.skip = trueを設定してください。この設定により、スナップショットフェーズ中の WAL バックフィルがスキップされ、ジョブの起動が高速化されます。この設定は、at-least-once セマンティクスのみを提供します。中間状態に必要な履歴の変更が失われる可能性があるため、集約やルックアップ結合などのステートフルな計算には適していません。
-
-
インクリメンタルスナップショットが無効な場合、スナップショットフェーズではチェックポイントはサポートされません。
PostgreSQL パブリケーションの再利用
PostgreSQL CDC コネクタは、パブリケーションに依存して、どのテーブルの変更をスロットにプッシュするかを決定します。複数のジョブが同じパブリケーションを共有すると、それらの設定は上書きされます。
原因
publication.autocreate.mode のデフォルト値は filtered で、これにはコネクタ設定で指定されたテーブルのみが含まれます。このモードでは、ジョブの開始時にパブリケーション内のテーブルが変更されるため、他のジョブの読み取り操作に影響を与える可能性があります。
解決策
-
監視対象のすべてのテーブルを含むパブリケーションを PostgreSQL で手動で作成してください。または、ジョブごとに個別のパブリケーションを作成してください。
-- my_flink_pub という名前で、テーブル table_a および table_b のパブリケーションを作成します CREATE PUBLICATION my_flink_pub FOR TABLE table_a, table_b; -- または、データベース内のすべてのテーブルのパブリケーションを作成します CREATE PUBLICATION my_flink_pub FOR ALL TABLES;説明大規模なデータベースの場合、すべてのテーブルをサブスクライブすることは推奨されません。これは、過剰なネットワーク帯域幅の使用や Flink クラスターでの高いCPU使用率を引き起こす可能性があるためです。
-
次の Flink 設定を追加してください:
-
debezium.publication.name = 'my_flink_pub'(パブリケーション名を指定します) -
debezium.publication.autocreate.mode = 'disabled'(起動時に Flink がパブリケーションを作成または変更しようとするのを防ぎます)
-
このアプローチは完全なアイソレーションを提供し、パブリケーションを手動で管理できるようにします。これにより、新しいジョブが既存のジョブに影響を与えるのを防ぎ、より安全なアクセス制御が可能になります。
SQL
構文
CREATE TABLE postgrescdc_source (
id INT NOT NULL,
name STRING,
description STRING,
weight DECIMAL(10,3)
) WITH (
'connector' = 'postgres-cdc',
'hostname' = '<host name>',
'port' = '<port>',
'username' = '<user name>',
'password' = '<password>',
'database-name' = '<database name>',
'schema-name' = '<schema name>',
'table-name' = '<table name>',
'decoding.plugin.name'= 'pgoutput',
'scan.incremental.snapshot.enabled' = 'true',
-- バックフィルをスキップすると読み取りが高速化され、リソース使用量を削減できますが、データが重複する可能性があります。ダウンストリームのシンクがべき等である場合に有効にしてください。
'scan.incremental.snapshot.backfill.skip' = 'false',
-- 本番環境では、これを 'filtered' または 'disabled' に設定し、Flink 経由ではなく手動でパブリケーションを管理してください。
'debezium-publication.autocreate.mode' = 'disabled'
-- 複数のソースがある場合は、ソースごとに異なるパブリケーションを設定してください。
--'debezium.publication.name' = 'my_flink_pub'
);
コネクタオプション
|
オプション |
説明 |
データ型 |
必須 |
デフォルト |
備考 |
|
connector |
コネクタ名。 |
STRING |
はい |
– |
値は |
|
hostname |
PostgreSQL データベースの IP アドレスまたはホスト名。 |
STRING |
はい |
– |
– |
|
username |
PostgreSQL データベースのユーザー名。 |
STRING |
はい |
– |
– |
|
password |
PostgreSQL データベースのパスワード。 |
STRING |
はい |
– |
– |
|
database-name |
PostgreSQL データベース名。 |
STRING |
はい |
– |
– |
|
schema-name |
PostgreSQL スキーマ名。正規表現をサポートします。 |
STRING |
はい |
– |
– |
|
table-name |
PostgreSQL テーブル名。正規表現をサポートします。 |
STRING |
はい |
– |
テーブル名では、正規表現を使用して複数のテーブルからデータを読み取れます。 |
|
port |
ポート番号。 |
INTEGER |
いいえ |
5432 |
– |
|
decoding.plugin.name |
PostgreSQL 論理デコーディングプラグインの名前。 |
STRING |
いいえ |
decoderbufs |
これは PostgreSQL にインストールされているプラグインによって決まります。サポートされているプラグインは次のとおりです:
|
|
slot.name |
論理デコーディングスロット名。 |
STRING |
VVR 8.0.1 以降では必須です。以前のバージョンではオプションです。 |
|
VVR 8.0.1 以降ではデフォルト値はありません。 |
|
debezium.* |
Debezium のプロパティとパラメータ |
STRING |
いいえ |
– |
Debezium クライアントの動作をよりきめ細かく制御できます。 たとえば、 |
|
scan.incremental.snapshot.enabled |
インクリメンタルスナップショットを有効にするかどうかを指定します。 |
BOOLEAN |
いいえ |
false |
|
|
scan.startup.mode |
データ読み取りの起動モード。 |
STRING |
いいえ |
initial |
有効な値:
|
|
changelog-mode |
ストリームの変更をエンコードするためのチェンジログモード。 |
STRING |
いいえ |
all |
サポートされているチェンジログモード:
|
|
heartbeat.interval.ms |
ハートビートパケットを送信する間隔。 |
Duration |
いいえ |
30000 |
単位はミリ秒です。 Postgres CDC コネクタは、スロットのオフセットを進めるために、データベースに対してハートビートを能動的に送信します。テーブルの変更が少ない場合、この値を設定すると WAL ログをタイムリーに回収できます。 |
|
scan.incremental.snapshot.chunk.key-column |
スナップショットフェーズでシャードを分割する際に使用するチャンクキー列を指定します。 |
STRING |
いいえ |
– |
デフォルトでは、主キーの最初の列が選択されます。 |
|
scan.incremental.close-idle-reader.enabled |
スナップショットの完了後にアイドルリーダーを閉じるかどうかを指定します。 |
BOOLEAN |
いいえ |
false |
この設定を有効にするには、 |
|
scan.incremental.snapshot.backfill.skip |
スナップショットフェーズ中のログの読み取りをスキップするかどうかを指定します。 |
BOOLEAN |
いいえ |
false |
有効: インクリメンタルフェーズは低ウォーターマークからログの読み取りを開始します。これにより WAL スロットの数は減りますが、セマンティクスは at-least-once セマンティクスのみとなります。ダウンストリームがべき等な書き込みをサポートしている場合に推奨します。 無効 (デフォルト): 整合性を確保するために、スナップショットフェーズ中に低ウォーターマークと高ウォーターマークの間のログが読み取られます。集計や結合を含む SQL では必須です。 |
型マッピング
次の表に、PostgreSQL と Flink のフィールド型のマッピングを示します。
|
PostgreSQL CDC |
Flink |
|
SMALLINT |
SMALLINT |
|
INT2 |
|
|
SMALLSERIAL |
|
|
SERIAL2 |
|
|
INTEGER |
INT |
|
SERIAL |
|
|
BIGINT |
BIGINT |
|
BIGSERIAL |
|
|
REAL |
FLOAT |
|
FLOAT4 |
|
|
FLOAT8 |
DOUBLE |
|
DOUBLE PRECISION |
|
|
NUMERIC(p, s) |
DECIMAL(p, s) |
|
DECIMAL(p, s) |
|
|
BOOLEAN |
BOOLEAN |
|
DATE |
DATE |
|
TIME [(p)] [WITHOUT TIMEZONE] |
TIME [(p)] [WITHOUT TIMEZONE] |
|
TIMESTAMP [(p)] [WITHOUT TIMEZONE] |
TIMESTAMP [(p)] [WITHOUT TIMEZONE] |
|
CHAR(n) |
STRING |
|
CHARACTER(n) |
|
|
VARCHAR(n) |
|
|
CHARACTER VARYING(n) |
|
|
TEXT |
|
|
BYTEA |
BYTES |
例
CREATE TABLE source (
id INT NOT NULL,
name STRING,
description STRING,
weight DECIMAL(10,3)
) WITH (
'connector' = 'postgres-cdc',
'hostname' = '<host name>',
'port' = '<port>',
'username' = '<user name>',
'password' = '<password>',
'database-name' = '<database name>',
'schema-name' = '<schema name>',
'table-name' = '<table name>'
);
SELECT * FROM source;
Flink CDC
VVR V11.4 以降では、PostgreSQL コネクタを Flink CDC ソースとしてサポートしています。
構文
source:
type: postgres
name: PostgreSQL Source
hostname: localhost
port: 5432
username: pg_username
password: pg_password
tables: db.scm.tbl
slot.name: test_slot
scan.startup.mode: initial
server-time-zone: UTC
connect.timeout: 30s
decoding.plugin.name: decoderbufs
sink:
type: ...
コネクタオプション
|
オプション |
説明 |
必須 |
データ型 |
デフォルト |
備考 |
|
type |
コネクタ名。 |
はい |
STRING |
– |
|
|
name |
データソース名。 |
いいえ |
STRING |
– |
– |
|
hostname |
PostgreSQL データベースサーバーのドメイン名または IP アドレス。 |
はい |
STRING |
– |
– |
|
port |
PostgreSQL データベースサーバーのポート番号。 |
いいえ |
INTEGER |
5432 |
– |
|
username |
PostgreSQL のユーザー名。 |
はい |
STRING |
– |
– |
|
password |
PostgreSQL のパスワード。 |
はい |
STRING |
– |
– |
|
tables |
キャプチャするテーブル名。 正規表現をサポートします。 |
はい |
STRING |
– |
重要
現在、同一データベース内のテーブルのみをキャプチャできます。 ピリオド (.) は、完全修飾名の区切り文字として扱われます。正規表現で任意の文字にマッチさせるためにピリオド (.) を使用する場合は、バックスラッシュでエスケープしてください。例: |
|
slot.name |
PostgreSQL レプリケーションスロット名。 |
はい |
STRING |
– |
名前は PostgreSQL のレプリケーションスロット命名規則に準拠する必要があります。使用できる文字は、小文字、数字、アンダースコアです。 |
|
decoding.plugin.name |
サーバーにインストールされている PostgreSQL 論理デコーディングプラグインの名前。 |
いいえ |
STRING |
|
有効な値: |
|
tables.exclude |
除外するテーブル。このオプションは |
いいえ |
STRING |
– |
|
|
server-time-zone |
データベースサーバーのセッションタイムゾーン。例:「Asia/Shanghai」など。 |
いいえ |
STRING |
– |
設定しない場合は、システムのデフォルトタイムゾーン ( |
|
scan.incremental.snapshot.chunk.size |
インクリメンタルスナップショットフレームワークにおける、各チャンクのサイズ (行数)。 |
いいえ |
INTEGER |
8096 |
インクリメンタルスナップショットを有効にすると、テーブルは読み取りのために複数のチャンクに分割されます。チャンクのデータは、すべて消費されるまでメモリにキャッシュされます。 チャンクが小さいほど、テーブル全体のチャンク数は増加します。これにより障害復旧の粒度は小さくなりますが、メモリ不足 (OOM) エラーや全体的なスループット低下につながる可能性があります。そのため、バランスを考慮して適切なチャンクサイズを設定する必要があります。 |
|
scan.snapshot.fetch.size |
テーブルの全データを読み取る際に、一度にフェッチするレコード数の上限。 |
いいえ |
INTEGER |
1024 |
– |
|
scan.startup.mode |
データ消費の起動モード。 |
いいえ |
STRING |
initial |
有効な値:
|
|
scan.incremental.close-idle-reader.enabled |
スナップショットの完了後にアイドルリーダーを閉じるかどうかを指定します。 |
いいえ |
BOOLEAN |
false |
この設定を有効にするには、 |
|
scan.lsn-commit.checkpoints-num-delay |
LSN オフセットのコミットを開始するまでに遅延させるチェックポイント数。 |
いいえ |
INTEGER |
3 |
状態から復旧できなくなることを防ぐために、チェックポイント LSN オフセットはローリング方式でコミットされます。 |
|
connect.timeout |
PostgreSQL データベースサーバーへの接続試行時に、タイムアウトするまでの最大待機時間。 |
いいえ |
DURATION |
30s |
この値は 250 ミリ秒未満にできません。 |
|
connect.max-retries |
接続確立時の最大再試行回数。 |
いいえ |
INTEGER |
3 |
– |
|
connection.pool.size |
コネクションプールのサイズ。 |
いいえ |
INTEGER |
20 |
– |
|
jdbc.properties.* |
カスタム JDBC URL プロパティを渡せます。 |
いいえ |
STRING |
– |
|
|
heartbeat.interval |
最新の利用可能な WAL ログオフセットを追跡するために、ハートビートイベントを送信する間隔。 |
いいえ |
DURATION |
30s |
– |
|
debezium.* |
PostgreSQL サーバーからのデータ変更のキャプチャに使用される Debezium Embedded Engine に、Debezium のプロパティを渡します。 |
いいえ |
STRING |
– |
Debezium PostgreSQL コネクタのプロパティの詳細については、関連ドキュメントをご参照ください。 |
|
chunk-meta.group.size |
チャンクメタデータのサイズ。 |
いいえ |
STRING |
1000 |
メタデータがこの値を超える場合は、複数回に分けて渡されます。 |
|
metadata.list |
ダウンストリームに渡される読み取り可能なメタデータのリスト。このリストは transform モジュールで使用できます。 |
いいえ |
STRING |
false |
区切り文字にはカンマ (,) を使用します。現在利用可能なメタデータは |
|
scan.incremental.snapshot.unbounded-chunk-first.enabled |
スナップショット読み取りフェーズ中に、非有界チャンクを先にディスパッチするかどうかを指定します。 |
いいえ |
STRING |
false |
これは実験的機能です。有効にすると、スナップショットフェーズ中に TaskManager が最後のチャンクを同期する際のメモリ不足 (OOM) エラーのリスクを低減できます。ジョブの初回起動前にこのオプションを有効にすることを推奨します。 |