repmgr ?

  • PostgreSQL 의 Replication 및 Failover 를 관리하는 Opensource tool.
  • Hot-Standby 동작 방식으로, 서버 구성, replication 모니터링, Failover, Manual Failover(Swichover) 지원
    • Failover 는 갑작스럽게 장애로 인해 Primary가 동작하지 못할때 Standby server를 Promote 하는 것
    • Switchover 는 계획적으로 Primary를 종료 또는 강등하고 Standby server를 Promote 하는 것(patch, maintenance 등)
  • PostgreSQL 9.0 이상 지원
  • EDB가 유지 관리(GPL v3 라이선스)

주요 구성

  • repmgr 명령어
    • Replication 관련 register, clone, promote, switch 등을 수행하는 명령어(CLI)
  • repmgrd (demon)
    • Cluster를 모니터링하고 Failover, switchover 등을 수행하는 서비스
  • repmgr metadata DB
    • repmgr은 별도의 메타데이터 테이블(보통 repmgr DB 내)에 노드 상태·시퀀스 등을 기록하여 클러스터 결정을 지원
  • Witness server
    • 실제 데이터(PostgreSQL Instance) 를 저장하지 않는 가벼운 노드(MongoDB로 따지면 Arbiter)
      • WAL replication은 하지 않음
    • Cluster 내 Failover 시 투표(Quorum)와 판단에만 참여 - 새로운 Primary 선출에 투표참여
    • Split brain 방지
      • 여러 노드가 Primary 가 되겠다고 충돌을 방지
    • Quorum 형성 (홀수 노드 구성 목적)

주요 명령어

repmgr primary register — 현재 마스터 노드를 repmgr 메타데이터에 등록. 

repmgr standby clone — WAL 기반으로 standby를 클론(복제본 생성).

repmgr standby register — 복제본을 메타데이터에 등록. 

repmgr standby follow / repmgr standby switchover / repmgr standby promote — 복제본을 새 마스터로 승격하거나 기존 마스터 전환. 

repmgrd — 데몬 실행으로 Monitoring 및 Failover 활성화.

repmgr witness register --host=witness_host --dbname=repmgr --user=repmgr
repmgr.conf에서 node_role='witness' 로 설정

repmgr cluster show

 

주의 사항

  • Auto Failover 시 어떤 Node를 승격할지 정하는 Quorum 형성을 위해 홀수 노드로 구성하여 진행되도록 witness서버 구성

템플릿 샘플

#repmgr.conf (primary / standby)

node_id=1                       # 노드별 고유 ID (Primary=1, Standby=2, Witness=3)
node_name='node1'               # 노드 이름 (node2, node3 ..)
conninfo='host=node1 user=repmgr dbname=repmgr port=5432'
data_directory='/data/node1/data'

pg_bindir='/usr/pgsql/bin'
use_replication_slots=1
monitoring_history=yes
log_level=INFO

 

#service - /etc/systemd/system/repmgrd.service
[Unit]
Description=PostgreSQL Replication Manager Daemon
After=network.target postgresql.service

[Service]
Type=simple
User=postgres
ExecStart=/usr/pgsql/bin/repmgrd -f /etc/repmgr/repmgr.conf --daemonize=false
Restart=on-failure

[Install]
WantedBy=multi-user.target

 

# pg_hba.conf (primary)

# 로컬 관리
local   all             all                                     peer
# Replication 허용
host    replication     repmgr          192.168.0.0/24          md5
# repmgr 메타데이터 DB 접근 허용
host    repmgr          repmgr          192.168.0.0/24          md5

 

자동 스크립트(OpenAI)

  • 유지 보수를 위해 Python3 로 변경필요
#!/bin/bash
# PostgreSQL repmgr 자동화 설치 스크립트 v2 (멀티 모드, 환경변수 PGPASSWORD)
# 사용법 예시:
# PGPASSWORD='repmgr_pass' ./setup_repmgr.sh --role=primary --node-id=1 --node-name=node1 --host=192.168.0.11
# PGPASSWORD='repmgr_pass' ./setup_repmgr.sh --role=standby --node-id=2 --node-name=node2 --host=192.168.0.12 --primary-host=192.168.0.11 --clone-method=pg_basebackup
# PGPASSWORD='repmgr_pass' ./setup_repmgr.sh --role=witness --node-id=3 --node-name=witness --host=192.168.0.13 --primary-host=192.168.0.11

set -e

# 기본값
PG_VERSION=15
CLONE_METHOD="pg_basebackup"

# 매개변수 파싱
for arg in "$@"; do
  case $arg in
    --role=*) ROLE="${arg#*=}";;
    --node-id=*) NODE_ID="${arg#*=}";;
    --node-name=*) NODE_NAME="${arg#*=}";;
    --host=*) HOST="${arg#*=}";;
    --primary-host=*) PRIMARY_HOST="${arg#*=}";;
    --clone-method=*) CLONE_METHOD="${arg#*=}";;
  esac
done

# 필수 인자 확인
if [[ -z "$ROLE" || -z "$NODE_ID" || -z "$NODE_NAME" || -z "$HOST" ]]; then
  echo "[ERROR] 필수 인자 누락: --role --node-id --node-name --host"
  exit 1
fi

if [[ -z "$PGPASSWORD" ]]; then
  echo "[ERROR] 환경변수 PGPASSWORD 가 설정되어야 합니다."
  exit 1
fi

# 경로 자동 감지
PG_BIN=$(command -v initdb | xargs dirname)
REPMGR_BIN=$(command -v repmgrd)
if [[ -z "$PG_BIN" || -z "$REPMGR_BIN" ]]; then
  echo "[ERROR] PostgreSQL 또는 repmgrd 바이너리를 찾을 수 없습니다."
  exit 1
fi

# node-id 기반 데이터 디렉토리
PGDATA="/data/node${NODE_ID}/data"
mkdir -p "$PGDATA"

REPMGR_CONF="/etc/repmgr/${PG_VERSION}/repmgr.conf"
mkdir -p $(dirname $REPMGR_CONF)

echo "========================================"
echo " PostgreSQL repmgr 자동 설정 시작 "
echo " ROLE=$ROLE NODE_ID=$NODE_ID NODE_NAME=$NODE_NAME HOST=$HOST"
echo " PGDATA=$PGDATA CLONE_METHOD=$CLONE_METHOD"
echo "========================================"

# repmgr.conf 생성
cat > $REPMGR_CONF <<EOF
node_id=${NODE_ID}
node_name='${NODE_NAME}'
conninfo='host=${HOST} user=repmgr dbname=repmgr port=5432'
data_directory='${PGDATA}'
pg_bindir='${PG_BIN}'
use_replication_slots=1
monitoring_history=yes
log_level=INFO
EOF

echo "[INFO] repmgr.conf 생성 완료: $REPMGR_CONF"

# OS 서비스 이름 감지 (systemctl)
if systemctl list-unit-files | grep -q "postgresql-${PG_VERSION}"; then
  PG_SERVICE="postgresql-${PG_VERSION}"
elif systemctl list-unit-files | grep -q "postgresql@${PG_VERSION}-main"; then
  PG_SERVICE="postgresql@${PG_VERSION}-main"
else
  PG_SERVICE=""
fi

restart_postgres() {
  if [[ -n "$PG_SERVICE" ]]; then
    systemctl restart $PG_SERVICE
  else
    $PG_BIN/pg_ctl -D $PGDATA restart -w
  fi
}

wait_pg_ready() {
  for i in {1..15}; do
    $PG_BIN/pg_isready -d repmgr -U repmgr -h $HOST && return
    sleep 2
  done
  echo "[ERROR] PostgreSQL 시작 실패"
  exit 1
}

# Primary 설정
if [[ "$ROLE" == "primary" ]]; then
  echo "[INFO] Primary initdb"
  $PG_BIN/initdb -D $PGDATA

  # 최소 replication 설정 적용
  cat >> $PGDATA/postgresql.conf <<EOF
wal_level = replica
max_wal_senders = 10
max_replication_slots = 10
EOF

  # pg_hba.conf 수정
  cat >> $PGDATA/pg_hba.conf <<EOF
host    replication     repmgr          192.168.0.0/24          md5
host    repmgr          repmgr          192.168.0.0/24          md5
EOF

  restart_postgres
  wait_pg_ready

  echo "[INFO] Primary repmgr 등록"
  repmgr -f $REPMGR_CONF primary register
fi

# Standby 설정
if [[ "$ROLE" == "standby" ]]; then
  if [[ -z "$PRIMARY_HOST" ]]; then
    echo "[ERROR] Standby는 --primary-host 필요"
    exit 1
  fi

  rm -rf $PGDATA/*

  if [[ "$CLONE_METHOD" == "pg_basebackup" ]]; then
    echo "[INFO] pg_basebackup 방식 Standby 초기화"
    PGPASSWORD=$PGPASSWORD $PG_BIN/pg_basebackup -h $PRIMARY_HOST -U repmgr -D $PGDATA -Fp -Xs -P -R
    touch $PGDATA/standby.signal
  elif [[ "$CLONE_METHOD" == "repmgr" ]]; then
    echo "[INFO] repmgr standby clone 방식 초기화"
    PGPASSWORD=$PGPASSWORD repmgr -h $PRIMARY_HOST -U repmgr -d repmgr -f $REPMGR_CONF standby clone
  else
    echo "[ERROR] 알 수 없는 CLONE_METHOD: $CLONE_METHOD"
    exit 1
  fi

  restart_postgres
  wait_pg_ready

  echo "[INFO] Standby repmgr 등록"
  PGPASSWORD=$PGPASSWORD repmgr -f $REPMGR_CONF standby register
fi

# Witness 설정
if [[ "$ROLE" == "witness" ]]; then
  if [[ -z "$PRIMARY_HOST" ]]; then
    echo "[ERROR] Witness는 --primary-host 필요"
    exit 1
  fi
  echo "[INFO] Witness repmgr 등록"
  PGPASSWORD=$PGPASSWORD repmgr -h $PRIMARY_HOST -U repmgr -d repmgr -f $REPMGR_CONF witness register
fi

# repmgrd systemd 서비스 생성
cat > /etc/systemd/system/repmgrd.service <<EOF
[Unit]
Description=PostgreSQL Replication Manager Daemon
After=network.target postgresql.service

[Service]
Type=simple
User=postgres
ExecStart=$REPMGR_BIN -f $REPMGR_CONF --daemonize=false
Restart=on-failure

[Install]
WantedBy=multi-user.target
EOF

systemctl daemon-reload
systemctl enable repmgrd
systemctl start repmgrd

echo "========================================"
echo " repmgr 노드 설정 완료: ROLE=$ROLE (CLONE_METHOD=$CLONE_METHOD)"
echo "========================================"

 

 

# Primary 실행
PGPASSWORD='repmgr_pass' ./setup_repmgr.sh \
  --role=primary \
  --node-id=1 \
  --node-name=node1 \
  --host=192.168.0.11
  
# Standby 실행 (pg_basebackup 방식)
# --clone-method=repmgr 로 바꾸면 repmgr standby clone 방식으로 초기화 가능.
PGPASSWORD='repmgr_pass' ./setup_repmgr.sh \
  --role=standby \
  --node-id=2 \
  --node-name=node2 \
  --host=192.168.0.12 \
  --primary-host=192.168.0.11 \
  --clone-method=pg_basebackup

# Witness 실행
PGPASSWORD='repmgr_pass' ./setup_repmgr.sh \
  --role=witness \
  --node-id=3 \
  --node-name=witness \
  --host=192.168.0.13 \
  --primary-host=192.168.0.11

#repmgr Status
PGPASSWORD='repmgr_pass' repmgr cluster show

# Primary PostgreSQL 상태 확인
pg_isready -h 192.168.0.11 -p 5432

# Standby PostgreSQL 상태 확인
pg_isready -h 192.168.0.12 -p 5432

# Primary 장애 시 Standby 승격
PGPASSWORD='repmgr_pass' repmgr standby promote -f /etc/repmgr/15/repmgr.conf

# 서비스 상태 확인
systemctl status repmgrd

# 재시작
systemctl restart repmgrd

# 자동 시작 등록 확인
systemctl is-enabled repmgrd

출처

 

repmgr - Replication Manager for PostgreSQL clusters

What is repmgr? repmgr is an open-source tool suite for managing replication and failover in a cluster of PostgreSQL servers. It enhances PostgreSQL's built-in hot-standby capabilities with tools to set up standby servers, monitor replication, and perform

www.repmgr.org

 

DB 초보 운영자의 PostgreSQL 이중화 도전기

직접 DB를 운영해본 적 없으신 분들이나 이중화 구성을 해본 적 없으신 분들도 오픈 소스를 활용해 쉽게 따라할 수 있도록 설치부터 테스트까지 차근차근히 공유해드리려고 합니다.

developers.hyundaimotorgroup.com

 

반응형

+ Recent posts