Logical Replication

PostgreSQLは、 logical replication を提供することにより、レプリケーション機能を物理的レプリケーションを超えて拡張します。これは、正確なブロックアドレスとバイトごとのコピーのレベルで動作します。論理レプリケーションは、定義されたレプリケーションID通常は主キーに基づいて、データオブジェクトとその変更をレプリケートします。

論理レプリケーションでは、パブリッシュアンドサブスクライブモデルを使用し、サブスクライバーはパブリッシャーノードでパブリケーションに接続します。サブスクライバーはこれらのパブリケーションからデータの変更をプルし、再公開できるため、カスケードレプリケーションと複雑なトポロジが有効になります。

注釈

CloudNativePGでのパブリッシャークラスターのフェールオーバー後に論理レプリケーションサブスクライバーを保護するには、論理デコードのレプリケーションスロット同期が有効になっていることを確認します。これがないと、論理レプリケーションクライアントはデータを失い、フェールオーバー後にシームレスに続行できない場合があります。構成の詳細については、 Replication: Logical Decoding Slot Synchronization を参照してください。

この柔軟なモデルは、次の場合に特に役立ちます。

  • オンラインデータの移行

  • ライブPostgreSQLバージョンのアップグレード

  • システム間のデータ分散

  • リアルタイム分析

  • 外部アプリケーションとの統合

注釈

の詳細、例、および制限については、

official PostgreSQL documentation on Logical Replication を参照してください。

CloudNativePG は、主要なPostgreSQL論理レプリケーションオブジェクトの宣言サポートを提供することにより、この機能を強化します。

  • Publication リソースを介した 出版物

  • Subscription リソースを介した サブスクリプション

出版物

PostgreSQLのパブリッシュアンドサブスクライブレプリケーションモデルでは、

**publication**

データ変更のソースです。これは、データベース内の1つ以上のテーブルから生成された変更セット レプリケーションセット としても知られる論理コンテナとして機能します。パブリケーションは、 パブリッシャー として機能するPostgreSQL 10+インスタンスで定義できます。パブリッククラウドで人気のDBaaSソリューションによって管理されているインスタンスを含みます。各パブリケーションは単一のデータベースに関連付けられ、どのテーブルと変更をレプリケートするかについての詳細な制御を提供します。

Kubernetes外部のパブリッシャーの場合、次のことができます create publications using SQL

または cnpg publication create を活用します。

CloudNativePGCluster オブジェクトを管理する場合、PostgreSQLパブリケーションはPublication リソースを介して宣言的に定義できます。

注釈

API Reference を参照してください。

Publication オブジェクトに定義できる属性の完全なリストについては、

freddie という名前のクラスターがあり、 app データベース内のすべてのテーブルをレプリケートするとします。これはPublication マニフェストです。

apiVersion: postgresql.cnpg.io/v1
kind: Publication
metadata:
  name: freddie-publisher
spec:
  cluster:
    name: freddie
  dbname: app
  name: publisher
  target:
    allTables: true

上記の例では

  • パブリケーションオブジェクトの名前はfreddie-publisher metadata.name です。

  • パブリケーションは、publisher spec.name という名前のfreddie クラスター spec.cluster.name のプライマリを介して作成されます。

  • app データベース spec.dbname のすべてのテーブル spec.target.allTables: true が含まれます。

パブリケーションテーブルのきめの細かい制御

allTables オプションは、データベース内のすべてのテーブルをレプリケートする便利な方法を提供しますが、PostgreSQLバージョン15以降では、 CREATE PUBLICATION を介して柔軟性の強化が導入されました。

コマンド。これにより、どのテーブル、またはどのタイプのデータ変更をパブリケーションに含めるかを正確に定義できます。

注釈

15より前のバージョンのPostgreSQLを使用している場合、特定のリリースで`CREATE PUBLICATION` で使用可能な構文とオプションを確認してください。一部のパラメーターと機能はサポートされていない場合があります。

複雑なまたは調整されたレプリケーションセットアップについては、

PostgreSQL logical replication documentation を参照してください。

さらに、 CloudNativePG API reference を参照してください。

レプリケーションターゲットの宣言によるカスタマイズの詳細については、

次の例では、app データベースのportal スキーマ内のすべてのテーブルと、access スキーマのusers テーブルをレプリケートするパブリケーションを定義します。

apiVersion: postgresql.cnpg.io/v1
kind: Publication
metadata:
  name: publisher
spec:
  cluster:
    name: freddie
  dbname: app
  name: publisher
  target:
    objects:
      - tablesInSchema: portal
      - table:
          name: users
          schema: access

Publication マニフェストの必須フィールド

Publication オブジェクトには次のフィールドが必要です。

  • metadata.name Kubernetes Publication オブジェクトの一意の名前。

  • spec.cluster.name PostgreSQLクラスターの名前。

  • spec.dbname パブリケーションが作成されるデータベース名。

  • spec.name PostgreSQLでのパブリケーション名。

  • spec.target パブリケーションに含めるテーブルまたは変更を指定します。

Publication オブジェクトは特定のCluster を参照し、パブリケーションを作成する場所を決定する必要があります。これはクラスターのプライマリインスタンスによって管理され、必要に応じてパブリケーションが作成または更新されます。

調整とステータス

Publication を作成すると、CloudNativePGは指定されたクラスターのプライマリインスタンスでそれを管理します。リコンシリエーションサイクルが成功すると、Publication ステータスは次を反映します。

  • applied: true 、構成が正常に適用されたことを示します。

  • observedGenerationmetadata.generation と一致し、適用された構成が最新の変更に対応することを確認します。

リコンシリエーション中にエラーが発生した場合、status.appliedfalse になり、エラーメッセージはstatus.message フィールドに含まれます。

パブリケーションの削除

publicationReclaimPolicy フィールドは、Publication オブジェクトを削除するときの動作を制御します。

  • retain デフォルト 手動管理のためにPostgreSQLにパブリケーションを残します。

  • delete PostgreSQLからパブリケーションを自動的に削除します。

次の例を考えます。

apiVersion: postgresql.cnpg.io/v1
kind: Publication
metadata:
  name: freddie-publisher
spec:
  cluster:
    name: freddie
  dbname: app
  name: publisher
  target:
    allTables: true
  publicationReclaimPolicy: delete

この場合、 Publication オブジェクトを削除すると、 freddie クラスターのapp データベースからpublisher パブリケーションも削除されます。

サブスクリプション

PostgreSQLのパブリッシュアンドサブスクライブレプリケーションモデルでは、

**subscription**

は、データの変更を消費するダウンストリームコンポーネントを表します。サブスクリプションは、パブリッシャーのデータベースへの接続を確立し、サブスクライブするパブリケーションのセット1つ以上を指定します。サブスクリプションは、 サブスクライバー として機能するサポートされているPostgreSQLインスタンスで作成できます。

注釈

スキーマ定義はレプリケートされないため、サブスクライバーは、データレプリケーションを開始する前に、対応するテーブルを既に定義している必要があります。

CloudNativePGは、 Subscription リソースを使用して宣言的に定義できることにより、サブスクリプション管理を簡素化します。

注釈

API Reference を参照してください。

Subscription オブジェクトに定義できる属性の完全なリストについては、

freddie クラスター publisherapp データベース上のpublisher パブリケーションからking クラスター subscriberapp データベースに変更をレプリケートするとします。次に、Subscription マニフェストの例を示します。

apiVersion: postgresql.cnpg.io/v1
kind: Subscription
metadata:
  name: freddie-to-king-subscription
spec:
  cluster:
    name: king
  dbname: app
  name: subscriber
  externalClusterName: freddie
  publicationName: publisher

上記の例では

  • サブスクリプションオブジェクトの名前はfreddie-to-king-subscriber metadata.name です。

  • サブスクリプションは、king クラスターspec.cluster.nameapp データベースspec.dbname に、subscriber spec.name という名前で作成されます。

  • spec.externalClusterName によって参照される、外部freddie クラスターのpublisher パブリケーションに接続します。

この設定を容易にするには、 king クラスターの構成でfreddie 外部クラスターを定義する必要があります。以下は、 king マニフェストで外部クラスターを定義する方法を示す抜粋例です。

externalClusters:
  - name: freddie
    connectionParameters:
      host: freddie-rw.default.svc
      user: postgres
      dbname: app

注釈

externalClusters セクションの構成の詳細については、ドキュメントの Bootstrap を参照してください。

ご覧のとおり、サブスクリプションは、ネットワーク経由でアクセス可能なPostgreSQLデータベースに接続できます。この柔軟性により、ほぼゼロのダウンタイムでデータをKubernetesにシームレスに移行できます。これは、人気のクラウドベースのDBaaSプラットフォームを含むさまざまな環境から移行するための優れたオプションです。

Subscription マニフェストの必須フィールド

次のフィールドはSubscription オブジェクトを定義するために必須です。

  • metadata.name 名前空間内のKubernetes Subscription オブジェクトの一意の名前。

  • spec.cluster.name サブスクリプションが作成されるPostgreSQLクラスターの名前。

  • spec.dbname サブスクリプションが作成されるデータベースの名前。

  • spec.name PostgreSQLに表示されるサブスクリプションの名前。

  • spec.externalClusterName spec.cluster.name クラスターの構成で定義された外部クラスターの名前。これは、発行者データベースを参照します。

  • spec.publicationName サブスクリプションが接続するパブリッシャーデータベース内のパブリケーションの名前。

Subscription オブジェクトは特定のCluster を参照し、サブスクリプションを管理する場所を決定する必要があります。 CloudNativePGは、指定されたクラスターのプライマリインスタンスでサブスクリプションが作成または更新されるようにします。

調整とステータス

Subscription を作成すると、CloudNativePGは指定されたクラスターのプライマリインスタンスでそれを管理します。リコンシリエーションサイクルが成功すると、Subscription ステータスは次を反映します。

  • applied: true 、構成が正常に適用されたことを示します。

  • observedGenerationmetadata.generation と一致し、適用された構成が最新の変更に対応することを確認します。

リコンシリエーション中にエラーが発生した場合、status.appliedfalse になり、エラーメッセージはstatus.message フィールドに含まれます。

サブスクリプションの削除

subscriptionReclaimPolicy フィールドは、Subscription オブジェクトを削除するときの動作を制御します。

  • retain デフォルト 手動管理のためにPostgreSQLにサブスクリプションを残します。

  • delete PostgreSQLからサブスクリプションを自動的に削除します。

次の例を考えます。

apiVersion: postgresql.cnpg.io/v1
kind: Subscription
metadata:
  name: freddie-to-king-subscription
spec:
  cluster:
    name: king
  dbname: app
  name: subscriber
  externalClusterName: freddie
  publicationName: publisher
  subscriptionReclaimPolicy: delete

この場合、 Subscription オブジェクトを削除すると、 king クラスターのapp データベースからsubscriber サブスクリプションも削除されます。

フェイルオーバーに対する復元力

パブリッシャーのフェールオーバー後も論理レプリケーションサブスクリプションが動作し続けるように保証には、クラスター全体で論理デコードスロットを同期するようにCloudNativePGを構成します。手順の詳細については、 論理デコードスロットの同期 を参照してください。

制限事項

official documentation で概要を示しているように、 PostgreSQLの論理レプリケーションには、いくつかの固有の制限があります。特に、次のオブジェクトはレプリケートされません。

  • データベーススキーマとDDLコマンド

  • シークエンスデータ

  • 大きなオブジェクト

スキーマレプリケーションのアドレス指定

スキーマレプリケーションに関連する最初の制限は、CloudNativePGの機能を使用して簡単に対処できます。たとえば、 import ブートストラップ機能を活用して、レプリケートが必要なテーブルのスキーマをコピーできます。または、PostgreSQLデータベースの場合と同様に、スキーマを手動で作成できます。

シーケンスの処理

シーケンスは、論理レプリケーションを介して自動的に同期は保たれませんが、CloudNativePGは、ライブマイグレーションで使用されるソリューションを提供します。 postgresql.cnpg.io/v1 を使用できます

シーケンス値を同期し、パブリッシャーとサブスクライバーデータベース間の一貫性を保証します。

論理レプリケーションを使用したライブ移行とメジャーPostgresアップグレードの例

論理レプリケーションの強力な機能を強調するために、この例では、 PostgreSQL 16を実行しているパブリッシャーデータベース freddie から最新のPostgreSQLバージョンを実行しているサブスクライバデータベース king にデータをレプリケートする方法を示します。このセットアップは、評価と実践学習のためにKubernetesクラスターに展開できます。

この例は、論理レプリケーションがデータの一貫性を保証しながら、PostgreSQLバージョン間のライブマイグレーションとアップグレードを促進する方法を示しています。論理レプリケーションとCloudNativePGを組み合わせることで、Kubernetes環境でこのようなシナリオを簡単にセットアップ、管理、および評価できます。

ステップ1パブリッシャーの設定 freddie

最初のステップでは、バージョン16でのfreddie PostgreSQLクラスターを作成します。クラスターには、単一のインスタンスが含まれ、10,000の数値を保存するテーブルn で初期化されたapp データベースが含まれます。 publisher という名前の論理レプリケーションパブリケーションも、データベース内のすべてのテーブルを含むように構成されています。

freddie クラスターとそのパブリケーションリソースをセットアップするためのマニフェストは次のとおりです。

apiVersion: postgresql.cnpg.io/v1
kind: Cluster
metadata:
  name: freddie
spec:
  instances: 1

  imageName: ghcr.io/cloudnative-pg/postgresql:16-standard-trixie

  storage:
    size: 1Gi

  bootstrap:
    initdb:
      postInitApplicationSQL:
        - CREATE TABLE n (i SERIAL PRIMARY KEY, m INTEGER)
        - INSERT INTO n (m) (SELECT generate_series(1, 10000))
        - ALTER TABLE n OWNER TO app

  managed:
    roles:
      - name: app
        login: true
        replication: true
- --
apiVersion: postgresql.cnpg.io/v1
kind: Publication
metadata:
  name: freddie-publisher
spec:
  cluster:
    name: freddie
  dbname: app
  name: publisher
  target:
    allTables: true

ステップ2サブスクライバー king の設定

次に、最新バージョンのPostgreSQLを実行して、king PostgreSQLクラスターを作成します。このクラスターは、外部クラスター構成を使用してfreddie クラスター上のapp データベースからスキーマをインポートすることにより初期化します。 Subscription リソース freddie-to-king-subscription は、 freddiepublisher によって公開された変更を消費するように構成されます。

以下は、king クラスターとそのサブスクリプションをセットアップするためのマニフェストです。

apiVersion: postgresql.cnpg.io/v1
kind: Cluster
metadata:
  name: king
spec:
  instances: 1

  imageName: ghcr.io/cloudnative-pg/postgresql:18-standard-trixie

  storage:
    size: 1Gi

  bootstrap:
    initdb:
      import:
        type: microservice
        schemaOnly: true
        databases:
          - app
        source:
          externalCluster: freddie

  externalClusters:
  - name: freddie
    connectionParameters:
      host: freddie-rw.default.svc
      user: app
      dbname: app
    password:
      name: freddie-app
      key: password
- --
apiVersion: postgresql.cnpg.io/v1
kind: Subscription
metadata:
  name: freddie-to-king-subscription
spec:
  cluster:
    name: king
  dbname: app
  name: subscriber
  externalClusterName: freddie
  publicationName: publisher

king クラスターが実行されたら、 app データベースに接続し、n テーブルのレコードをカウントすることにより、レプリケーションが機能していることを確認できます。次の例では、簡単にするためにcnpg プラグインが提供するpsql コマンドを使用しています。

kubectl cnpg psql king -- app -qAt -c SELECT count(*) FROM n
10000

このコマンドは10000 を返し、 freddie クラスターからのデータがking クラスターに正常にレプリケートされたことを確認します。

cnpg プラグインを使用して、既存のシーケンスを同期して、パブリッシャーとサブスクライバー間の一貫性を保証することもできます。次の例は、king クラスターのシーケンスを同期する方法を示しています。

kubectl cnpg subscription sync-sequences king --subscription=subscriber
SELECT setval("public"."n_i_seq", 10000);

10000

このコマンドは、現在の値と一致するようにking クラスターのシーケンスn_i_seq を更新し、ソースデータベースと同期していることを確認します。