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
우선 이중화를 구성하기 위해서는 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 설정에 대해 더 알아봐야겠다.
'DB' 카테고리의 다른 글
[PostgreSQL] repmgr을 이용한 DB 이중화 구성하기_2, auto failover (0) | 2022.10.02 |
---|---|
[PostgreSQL] repmgr을 이용한 DB 이중화 구성하기_1 (0) | 2022.10.01 |
[PostgreSQL] pglogical을 이용한 DB 이중화 구성하기_2, 양방향 이중화를 구성해 보자 (0) | 2022.09.21 |
[PostgreSQL] PostgreSQL 12 설치 후 Job for postgresql-12.service failed because the control process exited with error code. 에러 해결하기 (0) | 2022.09.08 |
[SQL] SQL 문법 간단 정리 (0) | 2021.02.01 |