レプリケーション スロットとパブリケーションを作成する

ドキュメントのバージョンを選択してください。

このドキュメントでは、AlloyDB Omni で論理レプリケーション スロットを作成する方法について説明します。PostgreSQL では、論理レプリケーションとは、パブリッシャー データベースから 1 つ以上のサブスクライバー(データベースやその他のアプリケーション)にデータ変更をコピーする方法です。AlloyDB Omni Kubernetes Operator を使用して作成したクラスタで論理レプリケーションを有効にして構成できます。

ストリーミングされる変更は、個々の行の更新、挿入、削除です。サブスクライバーは、永続的な接続を確保する一意のレプリケーション スロットを介してパブリッシャーに接続します。永続接続ではデータ ストリーミングの状態が維持されるため、中断が発生した場合は、中断地点からストリーミングが再開されます。

PostgreSQL の論理レプリケーションの詳細については、論理レプリケーションをご覧ください。

このページのコード スニペットは、モデルとして使用できる例です。値は、AlloyDB Omni リソースの値に置き換えてください。

始める前に

パブリッシャー クラスタを作成する

レプリケーション スロットを作成する前に、論理レプリケーションを有効にしてパブリッシャー クラスタを作成する必要があります。DBCluster マニフェストで wal_level パラメータを logical に設定する必要があります。

論理レプリケーションを有効にしてパブリッシャー データベース クラスタを作成するには、次のマニフェストを適用します。

  apiVersion: v1
  kind: Secret
  metadata:
    name: db-pw-DB_CLUSTER_NAME
    namespace: DB_CLUSTER_NAMESPACE
  type: Opaque
  data:
    DB_CLUSTER_NAME: "ENCODED_PASSWORD"
  ---
  apiVersion: alloydbomni.dbadmin.goog/v1
  kind: DBCluster
  metadata:
    name: DB_CLUSTER_NAME
    namespace: DB_CLUSTER_NAMESPACE
  spec:
    databaseVersion: "ALLOYDB_OMNI_VERSION"
    spec:
    availability:
      numberOfStandbys: 1
    primarySpec:
      parameters:
        wal_level: "logical"
      adminUser:
        passwordRef:
          name: db-pw-DB_CLUSTER_NAME
      resources:
        cpu: CPU_COUNT
        memory: MEMORY_SIZE
        disks:
        - name: DataDisk
          size: DISK_SIZE

次のように置き換えます。

  • DB_CLUSTER_NAME: このデータベース クラスタの名前。例: publisher

  • DB_CLUSTER_NAMESPACE(省略可): データベース クラスタを作成する Namespace。例: publisher-namespace

  • ENCODED_PASSWORD: デフォルトの postgres ユーザーロールのデータベース ログイン パスワード。base64 文字列としてエンコードされます。例: ChangeMe123 の場合は Q2hhbmdlTWUxMjM=

  • ALLOYDB_OMNI_VERSION: AlloyDB Omni のバージョン(15.7.0 以降)。

  • CPU_COUNT: このデータベース クラスタ内の各データベース インスタンスで使用できる CPU の数。

  • MEMORY_SIZE: このデータベース クラスタのデータベース インスタンスあたりのメモリ量。CPU ごとに 8 GB に設定することをおすすめします。たとえば、このマニフェストの前の部分で cpu2 に設定した場合は、memory16Gi に設定することをおすすめします。

  • DISK_SIZE: データベース インスタンスあたりのディスクサイズ。例: 10Gi

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

パブリッシャー クラスタを作成したら、パブリッシャー クラスタの Replication リソースを使用して、論理レプリケーション スロットを作成できます。各 Replication リソースは、対応するデータベース クラスタ リソースに関連付けられます。データベース クラスタには、複数の論理レプリケーション リソースを関連付けることができます。

パブリッシャー クラスタにレプリケーション スロットを構成するには、次のマニフェストを適用します。

$ cat << EOF | kubectl apply -f -
apiVersion: v1
kind: Secret
metadata:
  name: USER_PASSWORD_SECRET_NAME
  namespace: USER_PASSWORD_SECRET_NAMESPACE
type: Opaque
---
apiVersion: alloydbomni.dbadmin.goog/v1
kind: Replication
metadata:
  name: REPLICATION_NAME
  namespace: NAMESPACE
spec:
  dbcluster:
    name: DB_CLUSTER_NAME
  upstream:
    logicalReplication:
      pluginName: DECODER_PLUGIN
      databaseName: DATABASE_NAME
    applicationName: APPLICATION_NAME
    replicationSlotName: REPLICATION_SLOT_NAME
    synchronous: "REPLICATION_MODE"
    username: APPLICATION_USER
    password:
      name: USER_PASSWORD_SECRET_NAME
      namespace: USER_PASSWORD_SECRET_NAMESPACE
EOF

次のように置き換えます。

  • REPLICATION_NAME: この Replication リソースの名前。例: replication-1
  • NAMESPACE: この Replication リソースの Kubernetes Namespace。データベース クラスタの Namespace と一致する必要があります。
  • DB_CLUSTER_NAME: データベース クラスタの名前。作成時に割り当てたものです。
  • DECODER_PLUGIN: 論理レプリケーションに使用するデコード プラグイン(pgoutput など)に設定します。デコード プラグインの詳細については、出力プラグインをご覧ください。
  • DATABASE_NAME: 変更をレプリケーション スロットにストリーミングするデータベースの名前に設定します。パブリッシャー クラスタにデータベースがすでに作成されていることを確認します。
  • APPLICATION_NAME(省略可): レプリケーション スロットに接続するアプリケーション名に設定します。このフィールドは、ストリーミング モードが「同期」に設定されている場合に必要です。
  • REPLICATION_MODE(省略可): 非同期レプリケーションの場合は false に設定します。速度を犠牲にして同期レプリケーションを有効にする場合は、この値を true に設定します。明示的に設定しない場合、デフォルト値の false になります。
  • REPLICATION_SLOT_NAME: 作成され、サブスクライバーによって使用されるレプリケーション スロットの名前。例: logicalrepltestslot
  • REPLICATION_USER(省略可): レプリケーション スロットに接続するユーザーの名前。レプリケーション ユーザーを設定する場合は、Secret 名、Namespace、パスワードを設定する必要があります。
  • USER_PASSWORD_SECRET_NAME(省略可): アプリケーション ユーザーの Kubernetes Secret 名。アプリケーション ユーザーが設定されている場合は必須です。
  • USER_PASSWORD_SECRET_NAMESPACE(省略可): アプリケーション ユーザーの Kubernetes Secret が配置されている Namespace。アプリケーション ユーザーが設定されている場合は必須です。

レプリケーション スロットのステータスを確認する

レプリケーション スロットのステータスを表示するには、次のコマンドを実行します。

kubectl get replication.alloydbomni.dbadmin.goog REPLICATION_NAME -n NAMESPACE -oyaml

レスポンスには、status フィールドとその他の詳細が含まれます。

apiVersion: alloydbomni.dbadmin.goog/v1
kind: Replication
metadata:
  name: REPLICATION_NAME
  namespace: NAMESPACE
...
...
status:
  conditions:
  - lastTransitionTime: "2025-01-25T06:49:25Z"
    message: Ready for replication
    reason: Ready
    status: "True"
    type: Ready
  - lastTransitionTime: "2025-01-25T06:49:25Z"
    message: Replication slot is not being used
    reason: Unhealthy
    status: "False"
    type: Healthy
  observedGeneration: 2
  upstream:
    host: DATABASE_ENDPOINT
    password:
      name: USER_PASSWORD_SECRET_NAME
      namespace: USER_PASSWORD_SECRET_NAMESPACE
    port: DATABASE_PORT
    replicationSlotName: REPLICATION_SLOT_NAME
    username: APPLICATION_USER

DATABASE_ENDPOINT には、データベースへの接続に使用する IP アドレスが表示されます。READY 列のステータス TRUE は、スロットでストリーミングの準備ができていることを示します。サブスクライバー DBCluster またはアプリケーションがレプリケーション スロットに接続すると、HEALTHY 列のステータスが TRUE に変わります。

パブリッシャー クラスタを構成する

  1. 必要な Pod を見つけます。

    $ kubectl get pod -l "alloydbomni.internal.dbadmin.goog/dbcluster=DB_CLUSTER_NAME, alloydbomni.internal.dbadmin.goog/task-type=database, dbs.internal.dbadmin.goog/ha-role=Primary"
    
  2. psql を使用して、パブリッシャー クラスタのプライマリ Pod に接続します。

    psql -h IP_ADDRESS -U USERNAME -d DATABASE_NAME

    次のように置き換えます。

    • IP_ADDRESS: パブリッシャー クラスタのプライマリ Pod の IP アドレス。
    • USERNAME: データベースの postgres ユーザー。
    • DATABASE_NAME: サブスクライバーがサブスクライブするデータベース。
  3. レプリケーション リソースで指定された DATABASE_NAME が存在しない場合は、データベースを作成します。

    CREATE DATABASE DATABASE_NAME;
    
  4. 省略可: テスト目的で、データベースにテーブルを追加してデータを挿入します。このデータを使用して、パブリッシャーからサブスクライバーへのデータ レプリケーションをモニタリングできます。

    $ psql -h localhost -U postgres DATABASE_NAME
    customer=# CREATE TABLE TABLE_NAME(
    customer(#    ID INT PRIMARY KEY     NOT NULL,
    customer(#    NAME           TEXT    NOT NULL,
    customer(#    AGE            INT     NOT NULL,
    customer(#    SALARY         REAL
    customer(# );
    CREATE TABLE
    customer=# INSERT INTO TABLE_NAME (ID,NAME,AGE,SALARY) VALUES
    customer-# (1, 'Quinn', 25, 65000.00),
    customer-# (2, 'Kim', 22, 72250.00),
    customer-# (3, 'Bola', 31, 53000.00),
    customer-# (4, 'Sasha', 33, 105000.00),
    customer-# (5, 'Yuri', 27, 85000.00);
    INSERT 0 5
    customer=# \dt
              List of relations
    Schema |  Name   | Type  |  Owner
    --------+---------+-------+----------
    public | company | table | postgres
    (1 row)
    
    customer=# select * from TABLE_NAME;
    id | name  | age | salary
    ----+-------+-----+--------
      1 | Quinn  |  25 |  65000
      2 | Kim  |  22 |  72250
      3 | Bola   |  31 |  53000
      4 | Sasha |  33 | 105000
      5 | Yuri |  27 |  85000
    (5 rows)
    

    TABLE_NAME は、データを保存し、サブスクライバーがサブスクライブするテーブルに置き換えます。

  5. 権限を付与します。

    GRANT SELECT ON ALL TABLES IN SCHEMA public TO REPLICATION_USER;
    GRANT USAGE ON SCHEMA public TO REPLICATION_USER;
    ALTER DEFAULT PRIVILEGES IN SCHEMA public
    GRANT SELECT ON TABLES TO REPLICATION_USER;
    
  6. 次のコマンドを実行してパブリケーションを作成します。

    CREATE PUBLICATION PUBLICATION_NAME;
    ALTER PUBLICATION PUBLICATION_NAME ADD TABLE TABLE_NAME;
    

    次のように置き換えます。

    • PUBLICATION_NAME: サブスクライバーがサブスクライブで使用するパブリケーション名。

パブリケーションを作成したら、論理レプリケーション用にサブスクライバー クラスタを設定するか、レプリケーションを開始するようにアプリケーションを構成します。

制限事項

  • レプリケーション スロットの構成の更新はサポートされていません。構成を更新するには、レプリケーション スロットを削除し、更新された構成で再作成します。

    レプリケーション スロットを削除するには、次のコマンドを実行します。

    kubectl delete replication.alloydbomni.dbadmin.goog REPLICATION_NAME -n NAMESPACE
    
  • 論理レプリケーション スロットは、パブリッシャー データベースでのみ構成できます。replication API は、論理レプリケーション サブスクライバーの DBCluster またはアプリケーションをサポートしていません。

  • レプリケーション オブジェクトが参照するデータベース クラスタが高可用性用に構成されている場合、論理レプリケーション スロットはフェイルオーバー後にプロモートされたスタンバイで再作成されます。レプリケーション スロットが再作成されると、スロット内のストリームの位置は利用できなくなります。ストリームをサブスクライブするすべてのアプリケーションは、ストリームを再接続して再生する必要があります。

次のステップ