メインコンテンツまでスキップ

論理レプリケーションの管理と監視

このページでは、 Lakebase で論理レプリケーションを監視する方法、レプリケーションがゼロへのスケールや Branch とどのように相互作用するか、および一般的な問題を解決する方法について説明します。設定については、「Lakebaseにデータをレプリケートする」および「Lakebaseからデータをレプリケートする」を参照してください。

レプリケーションの監視​

2つの例外を除いて、任意の Postgres ロールがこのページのレプリケーションカタログをクエリーできます。pg_subscription の subconninfo 列には接続パスワードが含まれている可能性があり、制限されているため、 SELECT *を使用する代わりに特定の列を選択します。pg_stat_replicationでは、ロールにpg_read_all_stats ( databricks_superuserのメンバーが持つ) がない限り、ほとんどの列は非表示になっています。

サブスクライバーで、サブスクリプションが存在し、有効になっていることを確認します。

SQL
SELECT subname, subenabled FROM pg_catalog.pg_subscription;

パブリッシャーで、パブリケーションが存在することを確認します:

SQL
SELECT pubname FROM pg_catalog.pg_publication;

サブスクライバー上のテーブルごとの同期ステータスを確認します。すべてのテーブルが Ready (fully live) を読み取ると、初期コピーが完了し、サブスクリプションがストリーミングされます:

SQL
SELECT
srrelid::regclass AS table_name,
CASE srsubstate
WHEN 'i' THEN 'Initializing'
WHEN 'd' THEN 'Data copying (in progress)'
WHEN 's' THEN 'Synchronized (catching up)'
WHEN 'r' THEN 'Ready (fully live)'
END AS sync_status
FROM pg_catalog.pg_subscription_rel;

サブスクリプションの状態と遅延を確認してください:

SQL
SELECT subname, received_lsn, latest_end_lsn, last_msg_receipt_time
FROM pg_catalog.pg_stat_subscription;

パブリッシャとサブスクライバの行数を比較して、テーブルが同期していることを確認します。

SQL
SELECT COUNT(*) FROM public.playing_with_lakebase;

パブリッシャーで、レプリケーションスロットとそれぞれの進行状況をリストします:

SQL
SELECT slot_name, slot_type, active, restart_lsn
FROM pg_catalog.pg_replication_slots;

Lakebaseでは、結果には内部物理スロット wal_proposer_slot および wal_retention_slot も含まれます。Lakebaseはこれらのスロットを管理しており、論理レプリケーションの一部ではありません。

論理レプリケーションとゼロへのスケーリング​

アクティブなサブスクライバーがあるLakebaseコンピュートはゼロにスケールされないため、コンピュートの使用量が増加する可能性があります。

アクティブなサブスクライバを確認します。

SQL
SELECT *
FROM pg_catalog.pg_stat_replication
WHERE application_name <> 'walproposer';

レプリケーションスロットとストレージ​

レプリケーションスロットにより、サブスクライバーが変更を受信したことを確認するまで、パブリッシャーは先行書き込みログ(WAL)を保持します。サブスクライバーが変更の取り込みを停止すると、たとえば無効化、切断、障害、または遅延が原因の場合、パブリッシャー上でWALが蓄積します。これは、論理レプリケーションにおける深刻な問題の最も一般的な原因です:

  • パブリッシャーのストレージが不足する可能性があります。 保持されているWALはパブリッシャーのストレージがいっぱいになるまで増加し、データベースが書き込みを受け入れるのを停止し、停止を引き起こす可能性があります。
  • スロットをドロップしても、ストレージは即座に解放されません。 Postgres は、後でチェックポイントで WAL セグメントをリサイクルする場合にのみ、保持された WAL を削除します。パブリッシャーのストレージがすでに不足している場合、その再利用処理が完了しない可能性があります。
  • リスクは外部パブリッシャーにも適用されます。 Lakebaseが外部データベースにサブスクライブする場合、サブスクリプションが変更の消費を停止すると、その外部ソースでWALが蓄積されます。

保持されているWALの監視​

パブリッシャーで、各論理スロットが保持するWALの量とそれがアクティブかどうかを確認します:

SQL
SELECT slot_name, active, wal_status,
pg_catalog.pg_size_pretty(pg_catalog.pg_wal_lsn_diff(pg_catalog.pg_current_wal_lsn(), restart_lsn)) AS retained_wal
FROM pg_catalog.pg_replication_slots
WHERE slot_type = 'logical';

レプリケーションがアクティブな間に、このクエリーを定期的に実行します。retained_walが増加し続けるか、activeがfalseの場合に調査します。extended の wal_status は、スロットがパブリッシャーが通常保持するよりも多くの WAL を保持していることを意味します。unreserved または lost の wal_status は、スロットが max_slot_wal_keep_size を超えて、必要な WAL を失っている、または失ったことを意味するため、サブスクリプションを再作成する必要があります。

WALの蓄積からの回復​

  1. 保留中のWALの監視のクエリーを使用して、WALを保持しているスロットを見つけます。

  2. サブスクライバが回復できる場合は、ネットワークの問題、無効なサブスクリプション、または適用失敗など、原因を修正して、サブスクライバが追いつき、スロットが進むようにします。

  3. サブスクリプションが不要になった場合は、サブスクライバーでそれを削除します。サブスクライバーに到達できない場合は、パブリッシャーでスロットを直接削除します。スロットを削除する前に、スロットが非アクティブである必要があります:

    SQL
    SELECT pg_catalog.pg_drop_replication_slot('<slot_name>');
  4. パブリッシャーが保持されたWALをリサイクルするのを待ちます。ストレージの容量が不足しそうなセルフマネージドパブリッシャーでは、リサイクルを完了させるために、まずストレージを追加してください。

Lakebase での非アクティブなスロットの自動削除​

Lakebaseがパブリッシャーの場合、約40時間非アクティブなレプリケーションスロットは自動的に削除され、スロットが永続的にWALを保持するのを防ぎます。サブスクライバが変更の消費を停止し、スロットの進行が停止すると、スロットはアクティブでなくなります。これは、サブスクライバが非アクティブ化されているか使用できない場合、またはサブスクライバが長いレプリケーション遅延で構成されている場合に発生する可能性があります。

スロットが削除されるのを防ぐには、サブスクライバが接続されたまま変更を消費し続けるようにしてください。サブスクライバが構成可能なレプリケーション遅延または頻度を使用する場合は、スロットが前進し続けるように40時間未満に保ってください。スロットが削除され、それでもそれが必要な場合は、サブスクライバ上でサブスクリプションを再作成してください。

外部パブリッシャーは、非アクティブなスロットを自動的に削除しません。セルフマネージド型のパブリッシャーでは、スロットが保持できるWALの上限を設定するためにmax_slot_wal_keep_sizeを設定します。スロットが上限を超えると、Postgresによって無効化されるため、サブスクリプションを再作成する必要があります。

Branchを復元するとレプリケーションスロットが削除される​

Branchを復元すると、そのBranch上のすべてのレプリケーションスロットが削除されます。Branchを復元した後、公開物とサブスクリプションを再作成します。

子Branchはサブスクリプションを継承しません​

親Branchで定義されたサブスクリプションは、その子Branchで複製されません。Lakebaseはブランチのコンピュートが起動される前に子ブランチからそれらを削除するため、2つのコンピュートが同じサブスクリプションを複製することはありません。これは、子Branchを作成、Reset、または復元する場合に適用されます。そこでレプリケーションが必要な場合は、子Branchでサブスクリプションを再作成してください。

データベースを削除すると、そのサブスクリプションが削除されます​

DROP DATABASEコマンドまたは操作に応じてデータベースを削除する前に、Lakebaseはそのデータベースで定義されている論理レプリケーションサブスクリプションをすべて削除します。

レプリケーションロール​

専用のレプリケーションロールには REPLICATION 属性が必要です。Lakebaseアプリ、Databricks CLI、またはREST APIで作成されたロールは、databricks_superuserのメンバーであるかどうかに関係なく、この属性を持っています。SQLで作成されたロールには、REPLICATION属性が自動的に付与されません。SQLで作成するには、属性を含めます。たとえば、CREATE ROLE replication_user WITH LOGIN REPLICATION PASSWORD '<password>';。既存のロールに追加するには、ALTER ROLE <role_name> REPLICATION;を実行します。どちらのステートメントも、プロジェクト所有者のロールなど、CREATEROLE属性とREPLICATION属性を持つロールを必要とします。

ロールの権限を確認します:

SQL
SELECT rolname, rolreplication
FROM pg_catalog.pg_roles
WHERE rolname = '<role_name>';

デコーダープラグイン​

Lakebaseは、次の 2つの論理デコード出力プラグインをサポートしています:

  • pgoutput:組み込みのPostgres論理レプリケーションプラグイン、およびdefault標準的なPostgres間のレプリケーションに使用します。
  • wal2json:変更データをJSONで取り込むシステム向けに、WALの変更をJSONとして出力します。

パブリッシャー設定​

Lakebaseでは、 max_wal_senders と max_replication_slots は両方とも 10 に設定されます:

Text
max_wal_senders = 10
max_replication_slots = 10

max_wal_senders サブスクライバにデータをストリームする並列WAL送信者プロセスに上限を設け、 max_replication_slots はサブスクライバの進行状況を追跡するレプリケーションスロットに上限を設けます。サブスクライバごとにそれぞれ 1 つずつ計画します。異なる値をリクエストする場合は、Databricksまでお問い合わせください。

専用のレプリケーションスロットを作成する​

データサービスによっては、事前に作成しておく必要があるレプリケーションスロットがあります。標準のPostgres関数を使用して作成し、デコーダープラグインに名前を付けます。

SQL
SELECT pg_catalog.pg_create_logical_replication_slot('my_replication_slot', 'pgoutput');

サブスクリプションまたは公開を削除する​

サブスクリプションが不要になったら、サブスクライバーのサブスクリプションを削除します。パブリッシャーに到達できる場合、サブスクリプションを削除するとパブリッシャーから切断され、パブリッシャーのレプリケーションスロットが削除されます。複製されたデータはサブスクライバーデータベースに残ります。

SQL
DROP SUBSCRIPTION my_subscription;

パブリッシャーに到達できない場合、リモートスロットを削除する接続が確立できないため、DROP SUBSCRIPTIONは完了しません。まずスロットの関連付けを解除してから、サブスクリプションを削除します。

SQL
ALTER SUBSCRIPTION my_subscription DISABLE;
ALTER SUBSCRIPTION my_subscription SET (slot_name = NONE);
DROP SUBSCRIPTION my_subscription;

この場合、レプリケーションスロットはパブリッシャーに残り、WALを保持し続けます。WALを解放するには、パブリッシャーで削除します:

SQL
SELECT pg_catalog.pg_drop_replication_slot('<slot_name>');

パブリッシャで公開物を削除します。

SQL
DROP PUBLICATION my_publication;

トラブルシューティング​

症状

原因と解決策

サブスクリプションが接続されません。

パブリッシャに到達可能であること、および接続文字列、ロール、パスワードが正しいことを確認します。Lakebaseがサブスクライバの場合、パブリッシャEndpointがアカウントネットワークポリシーの許可リストにあることを確認します。「Lakebaseにデータをレプリケートする」を参照してください。

CREATE SUBSCRIPTION restricted by Account Network Policies で失敗しました。

アカウントでネットワークポリシーが適用されており、パブリッシャーホストが許可されたインターネットの宛先に含まれていません。ホストをアカウントネットワークポリシーに追加します。データをLakebaseに複製するを参照してください。

ストレージは増加し、解放されません。

レプリケーションスロットは、サブスクライバーが変更を消費していないため、WALを保持しています。解決しないままにしておくと、発行元がストレージを使い果たす可能性があります。保持されているWALを確認してから、サブスクライバーを再接続するか、スロットをドロップしてください。ストレージは、発行元がWALをリサイクルした後にのみ解放されます。レプリケーションスロットとストレージを参照してください。

サブスクライバーに行が到着しません。

ターゲットテーブルが一致する名前と列で存在し、公開に想定したテーブルが含まれていることを確認してください。

症状

原因と解決策

サブスクリプションが接続されません。

パブリッシャに到達可能であること、および接続文字列、ロール、パスワードが正しいことを確認します。Lakebaseがサブスクライバの場合、パブリッシャEndpointがアカウントネットワークポリシーの許可リストにあることを確認します。「Lakebaseにデータをレプリケートする」を参照してください。

CREATE SUBSCRIPTION restricted by Account Network Policies で失敗しました。

アカウントでネットワークポリシーが適用されており、パブリッシャーホストが許可されたインターネットの宛先に含まれていません。ホストをアカウントネットワークポリシーに追加します。データをLakebaseに複製するを参照してください。

ストレージは増加し、解放されません。

レプリケーションスロットは、サブスクライバーが変更を消費していないため、WALを保持しています。解決しないままにしておくと、発行元がストレージを使い果たす可能性があります。保持されているWALを確認してから、サブスクライバーを再接続するか、スロットをドロップしてください。ストレージは、発行元がWALをリサイクルした後にのみ解放されます。レプリケーションスロットとストレージを参照してください。

サブスクライバーに行が到着しません。

ターゲットテーブルが一致する名前と列で存在し、公開に想定したテーブルが含まれていることを確認してください。

次のステップ​