ApsaraDB RDS for PostgreSQL は、論理レプリケーションスロットを通じて変更データキャプチャ (CDC) をサポートしています。これは、PostgreSQL のネイティブな行単位の変更ストリーミング機構です。本ガイドでは、ApsaraDB RDS for PostgreSQL インスタンス上で CDC を構成する手順について説明します。必要なパラメーターの設定、レプリケーションスロットの作成、および変更データの端から端までの読み取りと消費までを一貫して実施します。
前提条件
開始する前に、以下の条件を満たしていることを確認してください。
ApsaraDB RDS for PostgreSQL インスタンスが存在すること。詳細については、「ApsaraDB RDS for PostgreSQL インスタンスの作成」をご参照ください。
クライアントからの接続を許可する IP アドレスホワイトリストが設定されていること。詳細については、「IP アドレスホワイトリストの設定」をご参照ください。
クライアントに psql がインストールされていること。詳細については、「PostgreSQL ドキュメント:ソースコードからのインストール」をご参照ください。
制限事項
CDC はプライマリインスタンスでのみサポートされています。読み取り専用インスタンスはサポート対象外です。
ApsaraDB RDS for PostgreSQL は「論理レプリケーションスロットのフェイルオーバー」をサポートしているため、プライマリ/セカンダリ スイッチオーバーによる CDC の中断は発生しません。
開始前の潜在的リスク
レプリケーションスロットはそのコンシューマーを追跡しません。下流のクライアントが消費を停止したり、異常な状態で消費進捗を報告したりすると、ウォールログ (WAL) ファイルが無制限に蓄積します。CDC を有効化する前に、以下のリスクに対処してください。
ディスク領域の枯渇およびインスタンスのロック: 消費が停止すると WAL ファイルが蓄積し、放置されたままではディスク領域が枯渇し、インスタンスが読み取り専用モードにロックされます。
XID ラップアラウンド: 下流のクライアントがリアルタイムで消費進捗を報告しない場合、インスタンスは複数の行バージョンを保持し続けます。これによりトランザクション ID (XID) のラップアラウンドが発生し、結果としてインスタンスが読み取り専用モードにロックされる可能性があります。サンプルのエラーログを以下に示します。
HINT: Close open transactions soon to avoid wraparound problems. You might also need to commit or roll back old prepared transactions, or drop stale replication slots. WARNING: oldest xmin is far in the past.パラメーター変更によるインスタンス再起動: CDC を有効化するには、
wal_levelをlogicalに設定する必要があります。この変更はインスタンスの再起動をトリガーします。影響を最小限に抑えるため、非ピーク時間帯に実施してください。
これらのリスクを軽減するには、以下の対策を実施してください。
下流のクライアントを、消費進捗をリアルタイムで報告するように構成してください。
WAL ログサイズおよびストレージ使用率を定期的に監視してください。詳細については、「拡張モニタリングの表示」および「アラートの管理」をご参照ください。
非アクティブなレプリケーションスロットは速やかに削除し、AliPG が WAL ログを自動的にクリアできるようにしてください。詳細については、「CDC 機能の無効化」をご参照ください。
CDC 機能の有効化
以下の手順では、例として以下の値を使用します。実際の環境に応じて適宜置き換えてください。
| プレースホルダー | 例の値 | 説明 |
|---|---|---|
<instance-endpoint> | pgm-*****.pgsql.singapore.rds.aliyuncs.com | RDS インスタンスのエンドポイント |
testdb | — | テスト用データベース名 |
db_admin | — | 管理用の特権アカウント |
cdc_user | — | CDC データを消費する標準アカウント |
cdc_replication_slot | — | レプリケーションスロット名 |
ステップ 1:テスト用データベースの作成
ステップ 2:アカウントの作成と権限の設定
左側のナビゲーションウィンドウで、アカウント をクリックします。
アカウントの作成 をクリックし、以下の 2 つのアカウントを作成します:

管理用の特権アカウント:db_admin
変更データを取得するための標準アカウント:cdc_user
説明本例のアカウント名は参考用です。詳細については、「アカウントの作成」をご参照ください。
db_admin としてインスタンスに接続します。
説明インスタンスのエンドポイントを確認するには、「エンドポイントおよびポート番号の表示と変更」をご参照ください。
psql -h <instance-endpoint> -p 5432 -U db_admin -d testdbcdc_user にレプリケーションロールを付与します。
ALTER USER cdc_user WITH REPLICATION;付与されたことを確認します。
SELECT rolreplication FROM pg_roles WHERE rolname='cdc_user';期待される出力:
rolreplication ---------------- t (1 行)cdc_user に、すべてのテーブルに対する SELECT 権限を付与します。
GRANT SELECT ON ALL TABLES IN SCHEMA PUBLIC to cdc_user;
ステップ 3:wal_level を logical に設定
wal_level パラメーターは、WAL ログに書き込まれる情報量を制御します。デフォルト値は replica です。CDC を有効化するには、論理デコーディングに必要な情報を追加する logical 値を指定する必要があります。
| 値 | 説明 |
|---|---|
minimal | クラッシュまたは即時シャットダウンからの回復に必要なデータのみを記録します。ベースバックアップまたは WAL ログを用いた WAL ベースの復元はサポートされません。 |
replica | WAL アーカイブおよびレプリケーション(スタンバイサーバーでの読み取り専用クエリを含む)をサポートします。 |
logical | replica が提供する機能に加え、論理デコーディングに必要な情報を追加します。CDC に必須です。 |
現在の値を確認するには:
SELECT name, setting, short_desc, source
FROM pg_settings
WHERE name = 'wal_level';期待される出力:
name | setting | short_desc | source
----------+---------+---------------------------------------------------------------+--------------------
wal_level | replica | Sets the level of information written to the WAL. | configuration file
(1 行)wal_level を logical に変更するには、以下の手順を実行します。
インスタンス ページに移動し、インスタンス ID をクリックします。
左側のナビゲーションウィンドウで、パラメーター をクリックします。
wal_level を logical に設定し、変更を送信します。
変更を送信すると、インスタンスが再起動します。影響を最小限に抑えるため、非ピーク時間帯に実施してください。詳細については、「ApsaraDB RDS for PostgreSQL インスタンスのパラメーターの変更」をご参照ください。
ステップ 4:論理レプリケーションスロットの作成
インスタンスが再起動し、実行中 状態に戻ってから次の手順に進んでください。
db_admin としてインスタンスに接続します。
psql -h <instance-endpoint> -p 5432 -U db_admin -d testdbcdc_replication_slotという名前の論理レプリケーションスロットを、test_decoding出力プラグインを用いて作成します。説明test_decodingは、オープンソース PostgreSQL が提供する出力プラグインです。cdc_replication_slotは例の名前であり、要件に合った任意の名前を使用できます。SELECT pg_create_logical_replication_slot('cdc_replication_slot', 'test_decoding');期待される出力:
pg_create_logical_replication_slot ------------------------------------ (cdc_replication_slot,1/14003428) (1 行)レプリケーションスロットが正しく作成されたことを確認します。
SELECT * FROM pg_replication_slots;期待される出力:
slot_name | plugin | slot_type | datoid | database | temporary | active | active_pid | xmin | catalog_xmin | restart_lsn | confirmed_flush_lsn | wal_status | safe_wal_size | two_phase ---------------------+---------------+-----------+--------+----------+-----------+--------+------------+------+--------------+-------------+---------------------+------------+---------------+----------- cdc_replication_slot | test_decoding | logical | 18822 | testdb | f | f | | | 22356 | 1/140033F0 | 1/14003428 | reserved | | f (1 行)
ステップ 5:テスト用データの作成
以下のステートメントを実行して、テスト用テーブルを作成し、サンプルデータを挿入します。
CREATE TABLE public.tb_test(
id int NOT NULL PRIMARY KEY
);
ALTER TABLE public.tb_test ADD name varchar(1) NULL;
INSERT INTO public.tb_test SELECT 1, 'A';ステップ 6:レプリケーションスロットからの変更データの読み取り
cdc_user としてインスタンスに接続します。
psql -h <instance-endpoint> -p 5432 -U cdc_user -d testdb変更データを消費せずに、レプリケーションスロットから読み取ります。
SELECT * FROM pg_logical_slot_peek_changes('cdc_replication_slot', null, null);期待される出力:
lsn | xid | data -----------+-------+------------------------------------------------------------------------ 1/14003D90 | 22376 | BEGIN 22376 1/1401DDE8 | 22376 | COMMIT 22376 1/1401DDE8 | 22377 | BEGIN 22377 1/1401E100 | 22377 | COMMIT 22377 1/1401E2A8 | 22382 | BEGIN 22382 1/1401E2A8 | 22382 | table public.tb_test: INSERT: id[integer]:1 name[character varying]:'A' 1/1401E3C0 | 22382 | COMMIT 22382 (7 行)
ステップ 7:pg_recvlogical を用いた変更データの消費
pg_recvlogical は、PostgreSQL に同梱されるネイティブな論理デコーディングツールです。このツールはレプリケーションスロットから読み取り、消費位置を進めることで、消費済みの WAL データをクリア可能にします。
現在のデータベース接続を終了するには、
\qを実行します。以下のコマンドを実行して、変更データの消費を開始します。
説明pg_recvlogicalはpostgresユーザーとして実行する必要があります(su - postgres)。-bash: pg_recvlogical: command not foundというエラーが表示された場合は、「よくある質問」をご参照ください。pg_recvlogical -h <instance-endpoint> -U <privileged-account> -d <database> \ --create-slot --if-not-exists --slot=cdc_replication_slot \ --plugin=test_decoding --start -f -例:
pg_recvlogical -h pgm-*****.pgsql.singapore.rds.aliyuncs.com -U db_admin -d testdb \ --create-slot --if-not-exists --slot=cdc_replication_slot \ --plugin=test_decoding --start -f -期待される出力:
BEGIN 22376 COMMIT 22376 BEGIN 22377 COMMIT 22377 BEGIN 22382 table public.tb_test: INSERT: id[integer]:1 name[character varying]:'A' COMMIT 22382
CDC 機能の無効化
レプリケーションスロットはそのコンシューマーを追跡しないため、消費が停止すると WAL ログが蓄積し、ディスク領域を枯渇させ、インスタンスを読み取り専用モードにロックする可能性があります。非アクティブなレプリケーションスロットを削除することで、AliPG が WAL ログを自動的にクリアできるようになります。
非アクティブなレプリケーションスロットを削除する方法は、以下のいずれかを選択してください。
ApsaraDB RDS コンソール: 「WAL ログ管理機能の利用」をご参照ください。
API オペレーション: 「DeleteSlot」をご参照ください。
SQL ステートメント: 以下の手順に従ってください。
SQL を用いてレプリケーションスロットを削除するには、以下の手順を実行します。
db_admin としてインスタンスに接続します。
psql -h <instance-endpoint> -p 5432 -U db_admin -d testdb非アクティブなレプリケーションスロットの一覧を表示します。
SELECT slot_name, slot_type, database, active, safe_wal_size FROM pg_replication_slots WHERE active = 'f';期待される出力:
slot_name | slot_type | database | active | safe_wal_size ---------------------+-----------+----------+--------+--------------- cdc_replication_slot | logical | testdb | f | (1 行)レプリケーションスロットを削除します。
SELECT pg_drop_replication_slot('cdc_replication_slot');
よくある質問
「pg_recvlogical: command not found」と表示された場合、どうすればよいですか?
pg_recvlogical は PostgreSQL のネイティブな論理デコーディングツールです。このツールはデフォルトの test_decoding 拡張機能を利用しており、これは PostgreSQL ソースコードパッケージの contrib/test_decoding ディレクトリに格納されています。このツールは postgres ユーザーとして実行する必要があります(su - postgres)。コマンドが見つからない場合は、PostgreSQL のソースコードからコンパイルおよびインストールしてください。このツールはインストールパスの /bin ディレクトリに配置されます。詳細については、「ソースコードからのインストール」をご参照ください。
レプリケーションスロットを削除した後も、WAL ファイルがディスク領域を占有し続けています。どうすればよいですか?
保持される WAL ファイルの数を減らすために、wal_keep_segments をデフォルト値の 128 に設定してください。詳細については、「ApsaraDB RDS for PostgreSQL インスタンスのパラメーターの変更」をご参照ください。
次のステップ
論理レプリケーションスロットのフェイルオーバー — プライマリ/セカンダリ スイッチオーバー時にも CDC を継続的に動作させる
拡張モニタリングの表示 — WAL ログサイズおよびストレージ使用率を追跡する
アラートの管理 — ディスク使用率およびインスタンスロックイベントに関するアラートを設定する
