Logical Replication
PostgreSQLは、 logical replication を提供することにより、レプリケーション機能を物理的レプリケーションを超えて拡張します。これは、正確なブロックアドレスとバイトごとのコピーのレベルで動作します。論理レプリケーションは、定義されたレプリケーションID通常は主キーに基づいて、データオブジェクトとその変更をレプリケートします。
論理レプリケーションでは、パブリッシュアンドサブスクライブモデルを使用し、サブスクライバーはパブリッシャーノードでパブリケーションに接続します。サブスクライバーはこれらのパブリケーションからデータの変更をプルし、再公開できるため、カスケードレプリケーションと複雑なトポロジが有効になります。
注釈
CloudNativePGでのパブリッシャークラスターのフェールオーバー後に論理レプリケーションサブスクライバーを保護するには、論理デコードのレプリケーションスロット同期が有効になっていることを確認します。これがないと、論理レプリケーションクライアントはデータを失い、フェールオーバー後にシームレスに続行できない場合があります。構成の詳細については、 Replication: Logical Decoding Slot Synchronization を参照してください。
この柔軟なモデルは、次の場合に特に役立ちます。
オンラインデータの移行
ライブPostgreSQLバージョンのアップグレード
システム間のデータ分散
リアルタイム分析
外部アプリケーションとの統合
注釈
の詳細、例、および制限については、
official PostgreSQL documentation on Logical Replication を参照してください。
CloudNativePG は、主要なPostgreSQL論理レプリケーションオブジェクトの宣言サポートを提供することにより、この機能を強化します。
Publicationリソースを介した 出版物Subscriptionリソースを介した サブスクリプション
出版物
PostgreSQLのパブリッシュアンドサブスクライブレプリケーションモデルでは、
データ変更のソースです。これは、データベース内の1つ以上のテーブルから生成された変更セット レプリケーションセット としても知られる論理コンテナとして機能します。パブリケーションは、 パブリッシャー として機能するPostgreSQL 10+インスタンスで定義できます。パブリッククラウドで人気のDBaaSソリューションによって管理されているインスタンスを含みます。各パブリケーションは単一のデータベースに関連付けられ、どのテーブルと変更をレプリケートするかについての詳細な制御を提供します。
Kubernetes外部のパブリッシャーの場合、次のことができます create publications using SQL
または cnpg publication create を活用します。
CloudNativePG でCluster
オブジェクトを管理する場合、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-publishermetadata.nameです。パブリケーションは、
publisherspec.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.nameKubernetesPublicationオブジェクトの一意の名前。spec.cluster.namePostgreSQLクラスターの名前。spec.dbnameパブリケーションが作成されるデータベース名。spec.namePostgreSQLでのパブリケーション名。spec.targetパブリケーションに含めるテーブルまたは変更を指定します。
Publication オブジェクトは特定のCluster
を参照し、パブリケーションを作成する場所を決定する必要があります。これはクラスターのプライマリインスタンスによって管理され、必要に応じてパブリケーションが作成または更新されます。
調整とステータス
Publication
を作成すると、CloudNativePGは指定されたクラスターのプライマリインスタンスでそれを管理します。リコンシリエーションサイクルが成功すると、Publication
ステータスは次を反映します。
applied: true、構成が正常に適用されたことを示します。observedGenerationはmetadata.generationと一致し、適用された構成が最新の変更に対応することを確認します。
リコンシリエーション中にエラーが発生した場合、status.applied
はfalse になり、エラーメッセージはstatus.message
フィールドに含まれます。
パブリケーションの削除
publicationReclaimPolicy フィールドは、Publication
オブジェクトを削除するときの動作を制御します。
retainデフォルト 手動管理のためにPostgreSQLにパブリケーションを残します。deletePostgreSQLからパブリケーションを自動的に削除します。
次の例を考えます。
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のパブリッシュアンドサブスクライブレプリケーションモデルでは、
は、データの変更を消費するダウンストリームコンポーネントを表します。サブスクリプションは、パブリッシャーのデータベースへの接続を確立し、サブスクライブするパブリケーションのセット1つ以上を指定します。サブスクリプションは、 サブスクライバー として機能するサポートされているPostgreSQLインスタンスで作成できます。
注釈
スキーマ定義はレプリケートされないため、サブスクライバーは、データレプリケーションを開始する前に、対応するテーブルを既に定義している必要があります。
CloudNativePGは、 Subscription
リソースを使用して宣言的に定義できることにより、サブスクリプション管理を簡素化します。
注釈
API Reference を参照してください。
各Subscription
オブジェクトに定義できる属性の完全なリストについては、
freddie クラスター publisher のapp
データベース上のpublisher パブリケーションからking
クラスター subscriber のapp
データベースに変更をレプリケートするとします。次に、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-subscribermetadata.nameです。サブスクリプションは、
kingクラスターspec.cluster.nameのappデータベースspec.dbnameに、subscriberspec.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名前空間内のKubernetesSubscriptionオブジェクトの一意の名前。spec.cluster.nameサブスクリプションが作成されるPostgreSQLクラスターの名前。spec.dbnameサブスクリプションが作成されるデータベースの名前。spec.namePostgreSQLに表示されるサブスクリプションの名前。spec.externalClusterNamespec.cluster.nameクラスターの構成で定義された外部クラスターの名前。これは、発行者データベースを参照します。spec.publicationNameサブスクリプションが接続するパブリッシャーデータベース内のパブリケーションの名前。
Subscription オブジェクトは特定のCluster
を参照し、サブスクリプションを管理する場所を決定する必要があります。
CloudNativePGは、指定されたクラスターのプライマリインスタンスでサブスクリプションが作成または更新されるようにします。
調整とステータス
Subscription
を作成すると、CloudNativePGは指定されたクラスターのプライマリインスタンスでそれを管理します。リコンシリエーションサイクルが成功すると、Subscription
ステータスは次を反映します。
applied: true、構成が正常に適用されたことを示します。observedGenerationはmetadata.generationと一致し、適用された構成が最新の変更に対応することを確認します。
リコンシリエーション中にエラーが発生した場合、status.applied
はfalse になり、エラーメッセージはstatus.message
フィールドに含まれます。
サブスクリプションの削除
subscriptionReclaimPolicy フィールドは、Subscription
オブジェクトを削除するときの動作を制御します。
retainデフォルト 手動管理のためにPostgreSQLにサブスクリプションを残します。deletePostgreSQLからサブスクリプションを自動的に削除します。
次の例を考えます。
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 は、
freddie のpublisher
によって公開された変更を消費するように構成されます。
以下は、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
を更新し、ソースデータベースと同期していることを確認します。