PostgreSQL에서 논리 복제는 게시자 데이터베이스에서 데이터베이스 또는 기타 애플리케이션일 수 있는 하나 이상의 구독자로 데이터 변경사항을 복사하는 방법입니다. AlloyDB Omni Kubernetes Operator를 사용하여 만든 클러스터에서 논리적 복제를 사용 설정하고 구성할 수 있습니다.
이 문서에서는 게시자 클러스터와 구독자 클러스터를 만들고 구성하는 방법을 보여주는 예시를 제공합니다. 이 문서를 읽기 전에 AlloyDB Omni 개요를 숙지해야 합니다. PostgreSQL 논리 복제의 제한사항에 대해서도 알아야 합니다.
이 페이지의 코드 스니펫은 모델로 사용할 수 있는 예시로, 값을 AlloyDB Omni 리소스의 값으로 바꿉니다.
클러스터 만들기
게시자 클러스터를 만듭니다.
$ 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
구독자 클러스터를 만듭니다.
$ 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
게시자 클러스터 구성
게시자 클러스터를 구성하고 테이블을 만듭니다. 원하는 경우 데이터를 테스트로 게시하여 구독자에게 복제되는지 확인할 수 있습니다.
wal_level
매개변수를logical
로 업데이트합니다.$ kubectl patch dbclusters.al publisher -p '{"spec":{"primarySpec":{"parameters":{"wal_level":"logical"}}}}' --type=merge
필요한 팟을 찾습니다.
$ kubectl get pod -l "alloydbomni.internal.dbadmin.goog/dbcluster=publisher, alloydbomni.internal.dbadmin.goog/task-type=database, dbs.internal.dbadmin.goog/ha-role=Primary"
게시자 클러스터의 데이터베이스 포드에 로그인합니다.
NAME READY STATUS RESTARTS AGE al-2bce-publisher-0 3/3 Running 0 36m $ kubectl exec -ti al-2bce-publisher-0 -- /bin/bash
customer
라는 데이터베이스를 만듭니다.CREATE DATABASE customer;
선택사항: 테스트 목적으로 데이터베이스에 테이블을 추가하고 데이터를 삽입합니다. 이 데이터를 사용하여 게시자에서 구독자로의 데이터 복제를 관찰할 수 있습니다.
$ 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)
복제 및 권한 부여를 위한 사용자
logicalreplica
를 만듭니다.CREATE USER logicalreplica WITH REPLICATION LOGIN PASSWORD '123';
권한 부여 이 예에서는 공개 스키마를 사용합니다.
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;
customer
데이터베이스에 게시를 만듭니다.CREATE PUBLICATION pub_customer; ALTER PUBLICATION pub_customer ADD TABLE company;
구독자 클러스터 구성
구독자 클러스터가 게시자 클러스터에서 데이터 업데이트를 수신하도록 사용 설정합니다.
구독자 데이터베이스에서
wal_level
매개변수를logical
로 설정합니다.$ kubectl patch dbclusters.al subscriber -p '{"spec":{"primarySpec":{"parameters":{"wal_level":"logical"}}}}' --type=merge
필요한 팟을 찾습니다.
$ kubectl get pod -l "alloydbomni.internal.dbadmin.goog/dbcluster=subscriber, alloydbomni.internal.dbadmin.goog/task-type=database, dbs.internal.dbadmin.goog/ha-role=Primary"
구독자 클러스터 데이터베이스 포드에 로그인합니다.
$ 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:/$
게시자 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
게시자 데이터베이스의 게시된 데이터의 초기 사본으로 게시자로부터 스키마 백업을 가져옵니다. 논리적 복제는 DDL 복제를 지원하지 않습니다. 복제하려는 스키마 또는 테이블은 논리적 복제가 시작되기 전에 대상 (구독자 클러스터)에 있어야 합니다.
postgres@al-3513-subscriber-0:/$ pg_dump -h 10.116.14.190 -U postgres --create --schema-only customer > /tmp/customer.schema-only.sql
구독자 데이터베이스에 백업을 적용합니다.
postgres@al-3513-subscriber-0:/$ psql -h localhost -U postgres < /tmp/customer.schema-only.sql
선택사항: 테이블에 데이터가 없는지 확인합니다.
# There is no data in table company customer=# select * from company; id | name | age | salary ----+------+-----+-------- (0 rows)
데이터베이스
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;
선택사항: 구독자 클러스터에서 복제를 확인합니다.
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)
게시자 클러스터에서 테이블에 행을 추가합니다.
# 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);
구독자 클러스터에서 게시자 클러스터의 테이블에 추가된 행이 구독자 클러스터의 테이블에 복제되었는지 확인합니다.
# 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)
수동으로 테이블 추가
논리적 복제에서는 pglogical
의 replicate_ddl_command
와 달리 DDL 변경사항이 자동으로 동기화되지 않습니다. 오픈소스 도구인 pgl_ddl_deploy
가 솔루션을 제공하지만 구독자에서 DDL 명령어를 수동으로 실행할 수도 있습니다.
이를 설명하기 위해 게시자 클러스터의
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
새 테이블이 게시자 클러스터에 추가되면 구독자에서 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)