※ How to configure PostgreSQL HA with repmgr.
※ Version: Linux 8.10 (Rocky), PostgreSQL 16.4, repmgr 5.5.0.
안녕하세요. 듀스트림입니다.
고민을 꽤 많이 했습니다. repmgr과 Patroni 중 어떤 걸 먼저 작성하는 게 좋을지 말이죠.
상대적으로 구성이 쉬운 repmgr을 먼저 하기로 결정했습니다.
그래서 오늘의 포스팅은 repmgr을 사용하여 PostgreSQL 고가용성(HA)을 구성하는 방법입니다.
오늘도 흐름은 기존과 마찬가지로 repmgr이 무엇이지 어떤 기능이 있는지 실습 전 먼저 알아보도록하겠습니다.
repmgr?
• repmgr는 PostgreSQL 클러스터에서 복제와 장애 조치를 관리하기 위한 오픈 소스 도구입니다.
• PostgreSQL의 기본 복제 기능을 확장하여 스탠바이 서버 설정, 복제 모니터링, 장애 조치 및 스위치오버 등의 관리 작업을 수행할 수 있게 해줍니다.
주요 기능
• 스탠바이 서버 설정: 새로운 스탠바이 서버를 쉽게 설정하고 기존 클러스터에 통합할 수 있습니다.
• 복제 모니터링: 클러스터 내의 복제 상태를 지속적으로 모니터링하여 문제를 조기에 감지합니다.
• 장애 조치(Failover): 프라이머리 서버에 문제가 발생할 경우 자동 또는 수동으로 스탠바이 서버를 프라이머리로 승격시켜 서비스 중단을 최소화합니다.
• 스위치오버(Switchover): 계획된 유지 보수 시 프라이머리와 스탠바이 서버의 역할을 안전하게 전환할 수 있습니다.
우리가 구성할 아키텍처를 살펴보겠습니다.
▸ repmgr을 사용한 이중화 아키텍처입니다.

▸ 이중화 + witness 아키텍처는 witness 노드가 다른 노드를 감시하는 구조로 되어있습니다.

※ witness 노드가 필요하지 않다면, 아래 내용 중 witness에 관한 부분은 생략하셔도 됩니다.
1. 사전 준비
• 두 서버에 설치된 PostgreSQL 버전은 반드시 동일해야 합니다.
• 두 서버 간 PostgreSQL 기본 포트(5432), SSH 포트(22)에 대해 TCP 통신이 허용되어야 합니다.
2. PostgreSQL OS 유저에 sudo 권한 부여
아래 내용은 모든 노드에서 root 유저로 수행합니다.
패키지 권한 문제 해결을 위해 sudo 권한이 필요합니다.
작업 완료 후 부여한 권한 회수가 필요합니다.
▸ sudoers 수정
# vi /etc/sudoers
visudo
▸ 아래 내용을 맨 밑에 추가
# postgres에게 모든 명령에 대한 sudo 권한 부여, 비밀번호를 묻지 않음
postgres ALL=(ALL) NOPASSWD: ALL
→ 권한 회수 방법은 추가한 내용 제거
3. Primary, Standby 노드의 PostgreSQL OS 유저 간 쌍방 SSH 키 교환
switchover, clone, 파일 시스템 동기화를 위해 필요합니다.
Primary, Standby 노드에서 PostgreSQL OS 유저로 실행합니다.
▸ SSH 키 생성
cd ~
ssh-keygen -t rsa
Enter
Enter
Enter
▸ SSH 공개 키 복사
ssh-copy-id -p 22 postgres@<target_IP_or_Hostname>
yes
password 입력
▸ 접속 확인
→ 패스워드를 물어보지 않아야 합니다.
ssh -p 22 postgres@<target_IP_or_Hostname>
4. 필수 패키지 설치
아래 내용은 모든 노드에서 root 유저로 실행합니다.
dnf install -y gcc make cmake git readline-devel zlib-devel libxslt-devel libxml2-devel openldap-devel curl-devel json-c-devel
5. repmgr 다운로드 & 설치
아래 내용은 모든 노드에서 root 유저로 실행합니다.
▸ git clone으로 다운로드
cd /usr/local/src
git clone https://github.com/EnterpriseDB/repmgr.git
▸ repmgr 디렉토리로 이동
cd repmgr
▸ 설치할 버전으로 체크아웃
git checkout v5.5.0
▸ 디렉토리 이동 및 권한 변경
mv /usr/local/src/repmgr /home/postgres/repmgr
chown -R postgres:postgres /home/postgres/repmgr
▸ 설치할 유저로 스위치
su - postgres
+ postgresql binary 경로가 환경 변수에 추가되어 있지 않다면 아래 내용 수행
# 현재 세션에서만 적용
# pg_config 경로를 찾아서 PATH에 추가
export PATH=$PATH:$(dirname $(which pg_config))
# 영구적용
# 1. 경로 확인
which pg_config
# 2. .bashrc에 경로 추가 (현재 사용자만 적용)
echo 'export PATH=$PATH:/postgres/bin' >> ~/.bashrc
# 3. 변경 사항 적용
source ~/.bashrc
▸ repmgr 디렉토리로 이동
cd /home/postgres/repmgr
▸ configure
./configure
▸ Makefile을 기반으로 소스 코드 빌드
→ USE_PGXS=1: PostgreSQL 확장 모듈을 빌드할 때, PGXS라는 PostgreSQL 확장 시스템(Extension System)을 사용하라는 의미입니다.
sudo make USE_PGXS=1
▸ 빌드된 파일을 PostgreSQL 시스템에 설치
sudo make USE_PGXS=1 install
▸ 설치 확인
repmgr --version
6. PostgreSQL 설정
Primary, witness 노드에서 실행합니다.
▸ postgresql.conf에 아래 내용 추가
# The list of shared libraries to be loaded at server startup
shared_preload_libraries = 'repmgr'
# replication settings
max_wal_senders = 10 # WAL Sender 프로세스의 최대 개수를 설정하는 파라미터
max_replication_slots = 10 # Replication Slot의 최대 개수를 설정하는 파라미터
▸ pg_hba.conf에 아래 내용 추가
# replication
host replication repmgr <primary_IP_address>/32 trust
host replication repmgr <standby_IP_address>/32 trust
# for rewind
host postgres repmgr <primary_IP_address>/32 trust
host postgres repmgr <standby_IP_address>/32 trust
# witness
host replication repmgr <witness_IP_address>/32 trust
host postgres repmgr <witness_IP_address>/32 trust
▸ 파라미터 적용을 위해 아래 명령어로 재기동
pg_ctl restart
▸ repmgr용 PostgreSQL 유저 생성
→ repmgr 사용자는 PostgreSQL 슈퍼유저 권한이 필요합니다.
psql -c "CREATE ROLE repmgr WITH SUPERUSER REPLICATION LOGIN ENCRYPTED PASSWORD 'repmgr';"
7. repmgr 파라미터 설정
모든 노드에서 실행하며, 설정값은 각 노드 별로 상이합니다.
▸ repmgr 설정 파일 경로 생성
mkdir /postgres/etc
▸ repmgr 설정 파일 생성
vi /postgres/etc/repmgr.conf
▸ 아래 내용 추가: Primary
# Primary
# connection info
node_id=1
node_name='node01'
conninfo='host=<local_IP_or_Hostname> user=repmgr dbname=postgres connect_timeout=2 port=5432'
data_directory='/data'
use_replication_slots=yes
ssh_options='-p 22 -q -o ConnectTimeout=10'
# log
log_level=INFO
log_file='/data/log/repmgr.log'
# repmgrd settings
reconnect_attempts=3
reconnect_interval=10
failover=automatic
promote_command='repmgr standby promote -f /postgres/etc/repmgr.conf'
follow_command='repmgr standby follow -f /postgres/etc/repmgr.conf -W --upstream-node-id=%n --log-to-file'
#connection_check_type=query
# event notification
#event_notification_command='bash /postgres/etc/vip_escalation.sh %n'
#event_notifications='standby_promote'
▸ 아래 내용 추가: Standby
# Standby
# connection info
node_id=2
node_name='node02'
conninfo='host=<local_IP_or_Hostname> user=repmgr dbname=postgres connect_timeout=2 port=5432'
data_directory='/data'
use_replication_slots=yes
ssh_options='-p 22 -q -o ConnectTimeout=10'
# log
log_level=INFO
log_file='/data/log/repmgr.log'
# repmgrd settings
reconnect_attempts=3
reconnect_interval=10
failover=automatic
promote_command='repmgr standby promote -f /postgres/etc/repmgr.conf'
follow_command='repmgr standby follow -f /postgres/etc/repmgr.conf -W --upstream-node-id=%n --log-to-file'
#connection_check_type=query
# event notification
#event_notification_command='bash /postgres/etc/vip_escalation.sh %n'
#event_notifications='standby_promote'
▸ 아래 내용 추가: witness
# witness
# connection info
node_id=3
node_name='witness'
conninfo='host=<local_IP_or_Hostname> user=repmgr dbname=postgres connect_timeout=2 port=5432'
data_directory='/data'
ssh_options='-p 22 -q -o ConnectTimeout=10'
# log
log_level=DEBUG
log_file='/data/log/repmgr.log'
#connection_check_type=query
8. HA 클러스터 설정
작성된 노드에서 실행합니다.
▸ Primary 노드 클러스터 등록
repmgr -f /postgres/etc/repmgr.conf primary register
▸ Standby 노드 초기 복제 후 클러스터 등록
pg_ctl stop
repmgr standby clone -f /postgres/etc/repmgr.conf -h <primary_IP_or_Hostname> -U repmgr -d postgres --force
pg_ctl start
repmgr standby register -f /postgres/etc/repmgr.conf
▸ witness 노드 클러스터 등록
repmgr witness register -f /postgres/etc/repmgr.conf -h <primary_IP_or_Hostname> -d postgres -U repmgr -F
+ witness 노드 클러스터 등록 과정 중 아래와 같은 오류 발생 시 initdb 후 등록
# Error Message
ERROR: witness node cannot be in the same cluster as the primary node DETAIL: database system identifiers on primary node and provided witness node match
# 데이터 영역 삭제 후 initdb
pg_ctl stop
rm -rf /data
initdb -D /data
# 이후 postgresql.conf, pg_hba.conf 설정, repmgr ROLE 생성 필요
5번 내용 참고
9. repmgrd 실행
모든 노드에서 실행합니다.
repmgrd -f /postgres/etc/repmgr.conf -d
10. 클러스터 상태 확인
repmgr -f /postgres/etc/repmgr.conf service status
repmgr -f /postgres/etc/repmgr.conf cluster show

11. HA 테스트
▸ 클러스터 상태 확인
repmgr -f /postgres/etc/repmgr.conf service status

▸ Primary 노드 정지
pg_ctl stop
▸ Auto-Failover 확인
repmgr -f /postgres/etc/repmgr.conf service status

12. 원상 복구
▸ Old Primary 클러스터 재합류
repmgr node rejoin -f /postgres/etc/repmgr.conf -h <current_primary_IP_or_Hostname> -d postgres -U repmgr --force-rewind
▸ 재합류한 Standby(Old Primary)를 Primary로 스위치오버
repmgr standby switchover -f /postgres/etc/repmgr.conf
여러분은 이제 repmgr을 활용하여 PostgreSQL의 고가용성(HA) 클러스터 구성을 성공적으로 완료하셨습니다.
PostgreSQL OS 사용자에게 부여한 sudo 권한도 반드시 회수하셨기를 바랍니다.
그럼, 다음 포스팅도 많은 기대 부탁드립니다!
'PostgreSQL' 카테고리의 다른 글
| PostgreSQL: Patroni로 고가용성(HA) 구성 방법 (0) | 2024.12.31 |
|---|---|
| PostgreSQL: timeout 관련 파라미터 (1) | 2024.12.28 |
| PostgreSQL: 쉘 스크립트로 PostgreSQL 고가용성(HA) 구현 (2) | 2024.12.11 |
| PostgreSQL: 고가용성(HA) 도구 비교 - Patroni vs repmgr (0) | 2024.12.10 |
| PostgreSQL: 이중화 장애 처리, 원상 복구 방법 (32) | 2024.12.09 |