DB

[PostgreSQL] pglogical을 이용한 DB 이중화 구성하기

메바동 2022. 9. 20. 23:56
728x90

PostgreSQL의 공식 문서 27번 항목은 Chapter 27. High Availability, Load Balancing, and Replication.

고가용성, 로드 밸런싱, 복제를 설명하고 있다.

이제 막 이중화에 대해 알아가기 시작하는 단계라 자세히는 모르지만 이중화를 구성함으로써 failover를 기대할 수 있고, 부하를 분산시킬 수도 있다고 한다.

 

이 중 오늘 알아볼 것은 공식 문서 27.1 항목에서 논리적 복제(Logical Replication)를 이용한 모듈인 pglogical에 대해 알아보려고 한다.

pgsql에서 논리적 복제는 Write-Ahead 로깅(WAL)에서 논리적 데이터 수정 스트림을 구성하여 테이블 별로 데이터 변경 사항을 복제할 수 있다고 되어있다.

 

pglogical에 대해 알아보는 이유는 그냥 회사에서 쓰는 걸 봤기 때문이다. 정리해두면 나도 언젠간 쓸 수도 있겠지...

 

https://github.com/2ndQuadrant/pglogical

 

GitHub - 2ndQuadrant/pglogical: Logical Replication extension for PostgreSQL 14, 13, 12, 11, 10, 9.6, 9.5, 9.4 (Postgres), provi

Logical Replication extension for PostgreSQL 14, 13, 12, 11, 10, 9.6, 9.5, 9.4 (Postgres), providing much faster replication than Slony, Bucardo or Londiste, as well as cross-version upgrades. - Gi...

github.com

 

우선 이중화를 구성하기 위해서는 PostgreSQL과 pglogical이 설치되어야 한다.

지난번 포스팅에 Rocky Linux 8 환경에 PostgreSQL 14를 설치했으니 위의 pglogical github에 있는 설명에 따라 pglogical을 설치하도록 한다.

 

sudo dnf install postgresql14-contrib -y

 

이중화를 구성하기 위한 테스트기 때문에 Rocky Linux 8 환경에 PostgreSQL 14가 설치된 VM 2개를 준비하였다.

지난 포스팅에서는 pgsql만 설치했기 때문에 postgresql14-contrib을 설치해준다.

 

다음으로는 PostgreSQL용 "2ndQuadrant's General Public" 저장소를 설치해준다.

curl https://techsupport.enterprisedb.com/api/repository/dl/default/release/14/rpm | bash

 

저장소가 설치되면 이제 pgsql 버전에 맞는 pglogical을 설치해 준다.

 

sudo dnf install postgresql14-pglogical -y

 

 

그다음 pgsql 설정 파일을 열어 pglogical을 사용하기 위한 설정을 수정해 준다.

 

sudo vi /var/lib/pgsql/14/data/postgresql.conf
wal_level = 'logical'
max_worker_processes = 10   # 공급자 노드에 필요한 DB당 하나
                            # 구독자 노드에 필요한 노드당 하나
max_replication_slots = 10  # 공급자 노드에 필요한 노드당 하나
max_wal_senders = 10        # 공급자 노드에 필요한 노드당 하나
shared_preload_libraries = 'pglogical'

track_commit_timestamp = on # 마지막 또는 첫번째 업데이트 충돌 해결을 위해 필요

 

수정 후에는 pgsql을 재시작해준다.

sudo systemctl restart postgresql-14.service

 

이제 pgsql에서 DB를 생성하고 테이블을 만든 뒤 이중화 테스트를 하면 된다.

 

 나는 우선 각 서버에 rocky1, rocky2라는 DB를 생성하고 해당 DB에 test라는 테이블을 생성해 주었다.

이제 pglogical을 사용하기 위해

 

CREATE EXTENSION pglogical;

 

각 DB에서 위 명령어를 사용해서 pglogical 확장을 설치해 주어야 한다.

이제 각 DB에 노드를 생성해서 공급과 구독을 할 수 있도록 설정해준다.

 

SELECT pglogical.create_node(
	node_name := '${노드명}',
	dsn := 'host=${IP} port=${port} dbname=${DB명} user=${유저명} password=${유저패스워드}'
);

 

 

이제 공급을 할 서버와 구독을 할 서버를 구분해서 작업해 주어야 한다.

나는 rocky1 서버를 공급, rocky2 서버를 구독용으로 설정해 줄 것이다.

 

공급자 설정하기

SELECT pglogical.replication_set_add_all_tables('default', ARRAY['public']);

 

공급자 설정이 끝이 났다.

공용 스키마의 모든 테이블을 기본 복제 집합에 추가한다는 명령어다.

 

구독자 설정하기

SELECT pglogical.create_subscription(
	subscription_name := '${구독명}',
	provider_dsn := 'host=${공급노드 IP} port=${공급노드 port} dbname=${공급노드 DB명} user=${공급노드 유저명} password=${공급 노드유저패스워드}',
	replication_sets := ARRAY['default']
);

 

provider_dsn에는 구독을 할 DB에 설정한 dsn을 적어주어야 한다.

 

SELECT pglogical.wait_for_subscription_sync_complete('${구독명}');

 

 

이로써 master, slave 형태의 공급과 구독을 하는 DB 이중화 설정이 끝이 났다.

 

테스트를 위해 테이블에 값을 넣어보기로 하자.

 

 

현재는 test 테이블을 조회했을 때 값이 없는 것으로 나온다.

여기서 rocky1 서버에 insert를 수행했을 때 rocky2 서버에서도 해당 값이 조회가 되어야 한다.

 

 

rocky1 서버에서 insert를 진행하였고, 이제 각 서버에서 다시 select를 수행해본다.

 

 

rocky2 서버에서도 정상적으로 조회가 되는 것을 볼 수 있다.

 

 

update와 delete도 제대로 동기화되는 것을 확인할 수 있다.

 

다만 이 상태에서 발생하는 문제는 rocky2는 read-only 상태가 아니라는 것이다.

 

다만 이 상태에서 rocky1에서 같은 key가 입력되었을 때

 

rocky1의 값으로 덮어써지는 모습을 볼 수 있다.

 

 

 

오늘은 여기까지 알아보고 다음에 pglogical 설정에 대해 더 알아봐야겠다.

728x90