Kubernetes에서 논리적 복제 구성

PostgreSQL에서 논리 복제는 게시자 데이터베이스에서 데이터베이스 또는 기타 애플리케이션일 수 있는 하나 이상의 구독자로 데이터 변경사항을 복사하는 방법입니다. AlloyDB Omni Kubernetes Operator를 사용하여 만든 클러스터에서 논리적 복제를 사용 설정하고 구성할 수 있습니다.

이 문서에서는 게시자 클러스터와 구독자 클러스터를 만들고 구성하는 방법을 보여주는 예시를 제공합니다. 이 문서를 읽기 전에 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_level 매개변수를 logical로 업데이트합니다.

    $ kubectl patch dbclusters.al publisher  -p '{"spec":{"primarySpec":{"parameters":{"wal_level":"logical"}}}}' --type=merge
    
  2. 필요한 팟을 찾습니다.

    $ 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. 게시자 클러스터의 데이터베이스 포드에 로그인합니다.

    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_level 매개변수를 logical로 설정합니다.

    $ kubectl patch dbclusters.al subscriber  -p '{"spec":{"primarySpec":{"parameters":{"wal_level":"logical"}}}}' --type=merge
    
  2. 필요한 팟을 찾습니다.

    $ 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. 구독자 클러스터 데이터베이스 포드에 로그인합니다.

    $ 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)
    

다음 단계