Kubernetes で論理レプリケーションを構成する

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

このドキュメントでは、パブリッシャー クラスタとサブスクライバー クラスタを作成して構成する方法の例を示します。このドキュメントを読む前に、AlloyDB Omni の概要を理解しておく必要があります。また、PostgreSQL 論理レプリケーションの制限事項にも注意する必要があります。

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

クラスタを作成する

  1. Kubernetes に Omni Operator をインストールする

  2. パブリッシャー クラスタを作成します。

    $ cat << EOF | kubectl apply -f -
    apiVersion: v1
    kind: Secret
    metadata:
      name: db-pw-publisher
    type: Opaque
    data:
      publisher: "b2RzcGFzc3dvcmQ=" # Password is odspassword
    ---
    apiVersion: alloydbomni.dbadmin.goog/v1
    kind: DBCluster
    metadata:
      name: publisher
    spec:
      primarySpec:
        adminUser:
          passwordRef:
            name: db-pw-publisher
        databaseVersion: "15.7.0"
        resources:
          memory: 10Gi
          cpu: 1
          disks:
          - name: DataDisk
            size: 40Gi
    EOF
    
  3. サブスクライバー クラスタを作成します。

    $ cat << EOF | kubectl apply -f -
    apiVersion: v1
    kind: Secret
    metadata:
      name: db-pw-subscriber
    type: Opaque
    data:
      subscriber: "b2RzcGFzc3dvcmQ=" # Password is odspassword
    ---
    apiVersion: alloydbomni.dbadmin.goog/v1
    kind: DBCluster
    metadata:
      name: subscriber
    spec:
      primarySpec:
        adminUser:
          passwordRef:
            name: db-pw-subscriber
        databaseVersion: "15.7.0"
        resources:
          memory: 10Gi
          cpu: 1
          disks:
          - name: DataDisk
            size: 40Gi
    EOF
    

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

パブリッシャー クラスタを構成してテーブルを作成します。必要に応じて、データをテストとして公開して、サブスクライバーにレプリケートされていることを確認できます。

  1. パラメータ wal_levellogical に更新します。

    $ kubectl patch dbclusters.al publisher  -p '{"spec":{"primarySpec":{"parameters":{"wal_level":"logical"}}}}' --type=merge
    
  2. 必要な Pod を見つけます。

    $ kubectl get pod -l "alloydbomni.internal.dbadmin.goog/dbcluster=publisher, alloydbomni.internal.dbadmin.goog/task-type=database, dbs.internal.dbadmin.goog/ha-role=Primary"
    
  3. パブリッシャー クラスタのデータベース Pod にログインします。

    NAME                                          READY   STATUS    RESTARTS   AGE
    al-2bce-publisher-0                           3/3     Running   0          36m
    $ kubectl exec -ti al-2bce-publisher-0  -- /bin/bash
    
  4. customer という名前のデータベースを作成します。

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

    $ psql -h localhost -U postgres customer
    customer=# CREATE TABLE COMPANY(
    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 COMPANY (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 company;
    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)
    
  6. レプリケーション用にユーザー logicalreplica を作成し、権限を付与します。

    CREATE USER logicalreplica WITH REPLICATION LOGIN PASSWORD '123';
    
  7. 権限を付与します。この例では、公開スキーマを使用します。

    GRANT SELECT ON ALL TABLES IN SCHEMA public TO logicalreplica;
    GRANT USAGE ON SCHEMA public TO logicalreplica;
    ALTER DEFAULT PRIVILEGES IN SCHEMA public
        GRANT SELECT ON TABLES TO logicalreplica;
    
  8. customer データベースにパブリケーションを作成します。

    CREATE PUBLICATION pub_customer;
    ALTER PUBLICATION pub_customer ADD TABLE company;
    

サブスクライバー クラスタを構成する

サブスクライバー クラスタがパブリッシャー クラスタからデータ更新を受信できるようにします。

  1. サブスクライバー データベースでパラメータ wal_levellogical に設定します。

    $ kubectl patch dbclusters.al subscriber  -p '{"spec":{"primarySpec":{"parameters":{"wal_level":"logical"}}}}' --type=merge
    
  2. 必要な Pod を見つけます。

    $ kubectl get pod -l "alloydbomni.internal.dbadmin.goog/dbcluster=subscriber, alloydbomni.internal.dbadmin.goog/task-type=database, dbs.internal.dbadmin.goog/ha-role=Primary"
    
  3. サブスクライバー クラスタ データベース Pod にログインします。

    $ kubectl get pod
    NAME                                          READY   STATUS    RESTARTS   AGE
    al-2bce-publisher-0                           3/3     Running   0          20h
    
    $ kubectl exec -ti al-3513-subscriber-0  -- /bin/bash
    Defaulted container "database" out of: database, logrotate-agent, memoryagent, dbinit (init)
    postgres@al-3513-subscriber-0:/$
    
  4. パブリッシャー Pod の IP アドレスを確認します(例: 10.116.14.190)。

    $ kubectl get service
    NAME                     TYPE           CLUSTER-IP      EXTERNAL-IP    PORT(S)          AGE
    al-publisher-rw-ilb      ClusterIP      10.116.14.190   <none>         5432/TCP         21h
    
  5. パブリッシャー データベースにパブリッシュされたデータの初期コピーとして、パブリッシャーからスキーマ バックアップを取得します。論理レプリケーションは DDL レプリケーションをサポートしていません。論理レプリケーションを開始する前に、レプリケートするスキーマまたはテーブルが宛先(サブスクライバー クラスタ)に存在している必要があります。

    postgres@al-3513-subscriber-0:/$ pg_dump -h 10.116.14.190 -U postgres --create --schema-only customer > /tmp/customer.schema-only.sql
    
  6. サブスクライバー データベースにバックアップを適用します。

    postgres@al-3513-subscriber-0:/$ psql -h localhost -U postgres < /tmp/customer.schema-only.sql
    
  7. 省略可: テーブルにデータがないことを確認します。

    # There is no data in table company
    customer=# select * from company;
    id | name | age | salary
    ----+------+-----+--------
    (0 rows)
    
  8. データベース customer のサブスクリプションを作成します。

    postgres@al-3513-subscriber-0:/$ psql -h localhost -U postgres customer
    customer=# CREATE SUBSCRIPTION sub_customer CONNECTION 'host=10.116.14.190 port=5432 user=logicalreplica dbname=customer password=123' PUBLICATION pub_customer;
    
  9. 省略可: サブスクライバー クラスタでレプリケーションを確認します。

    postgres@al-3513-subscriber-0:/$ psql -h localhost -U postgres customer
    customer=# select * from public.company;
    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)
    
  10. パブリッシャー クラスタで、テーブルに行を追加します。

    # On the publisher database
    $ kubectl exec -ti al-2bce-publisher-0  -- /bin/bash
    Defaulted container "database" out of: database, logrotate-agent, memoryagent, dbinit (init)
    postgres@al-2bce-publisher-0:/$ psql -h localhost -U postgres customer
    customer=# insert into company(id, name, age, salary) values (6, 'Alex', 39, 100000);
    
  11. サブスクライバー クラスタで、パブリッシャー クラスタのテーブルに追加された行が、サブスクライバー クラスタのテーブルに複製されていることを確認します。

    # On the subscriber database, data is synced.
    postgres@al-3513-subscriber-0:/$ psql -h localhost -U postgres customer
    customer=# select * from company;
    id | name  | age | salary
    ----+-------+-----+--------
      1 | Quinn |  25 |  65000
      2 | Kim   |  22 |  72250
      3 | Bola  |  31 |  53000
      4 | Sasha |  33 | 105000
      5 | Yuri  |  27 |  85000
      6 | Alex  |  39 | 100000
    (6 rows)
    

追加のテーブルを手動で作成する

論理レプリケーションでは、pglogicalreplicate_ddl_command とは異なり、DDL の変更は自動的に同期されません。オープンソース ツール pgl_ddl_deploy にはソリューションが用意されていますが、サブスクライバーで DDL コマンドを手動で実行することもできます。

  1. これを説明するために、パブリッシャー クラスタの customer データベースに finance という新しいテーブルを作成します。

    # On the publisher database
    $ kubectl exec -ti al-2bce-publisher-0  -- /bin/bash
    Defaulted container "database" out of: database, logrotate-agent, memoryagent, dbinit (init)
    postgres@al-2bce-publisher-0:/$ psql -h localhost -U postgres customer
    customer=# create table finance (row text);
    CREATE TABLE
    customer=# insert into finance values ('critical data');
    INSERT 0 1
    customer=# ALTER PUBLICATION pub_customer ADD TABLE finance;
    ALTER PUBLICATION
    
  2. 新しいテーブルがパブリッシャー クラスタに追加されたら、サブスクライバーで DDL(テーブルの作成)を手動で適用し、サブスクライバー クラスタで次のコマンドを実行してレプリケーションを確認します。

    postgres@al-3513-subscriber-0:/$ psql -h localhost -U postgres customer
    customer=# create table finance (row text);
    CREATE TABLE
    customer=# ALTER SUBSCRIPTION sub_customer REFRESH PUBLICATION;
    ALTER SUBSCRIPTION
    customer=# select * from finance;
          row
    ---------------
    critical data
    (1 row)
    

次のステップ