참고:
- 이 사용지침서에서는 Oracle Cloud에 접근해야 합니다. 무료 계정에 등록하려면 Oracle Cloud Infrastructure Free Tier 시작하기를 참조하십시오.
- Oracle Cloud Infrastructure 인증서, 테넌시 및 구획에 대한 예제 값을 사용합니다. 실습을 마치면 사용자의 클라우드 환경과 관련된 값으로 대체합니다.
Oracle Cloud Infrastructure에 고가용성 Postgres 클러스터 배포
소개
이 자습서에서는 Patroni 및 기타 구성 요소를 사용한 HA 구성에서 Postgres의 설계 및 구현에 대해 간략하게 설명합니다. PostgreSQL에는 클러스터에 실패한 마스터를 다시 추가하기 위한 내장된 자동 페일오버 및 자동 방식이 없습니다. Patroni는 페일오버/스위치오버 및 자동화된 부트스트랩 및 복제 설정을 위한 클라우드 전용 기능과 고급 옵션을 갖춘 PostgreSQL의 새로운 HA(고가용성) 솔루션입니다.
Patroni는 Python을 사용하여 자체 커스터마이즈된 HA 솔루션을 만들고 최대한의 접근성을 위해 etcd와 같은 분산형 구성 저장소를 만드는 템플릿입니다.
다음은 네이티브 Postgres 복제와 Patroni 솔루션의 몇 가지 제한 사항입니다.
| 기본 Postgres 복제 제한 사항 | Patroni 기반 솔루션 |
|---|---|
| 기본 복제 방식은 자동 페일오버를 지원하지 않습니다. | Patroni는 자동 페일오버를 제공합니다. |
| 페일오버를 위해 외부 도구를 사용하려면 이러한 도구를 작동 및 실행 상태로 유지해야 할 수 있습니다. | Patroni는 페일오버를 처리합니다. |
| Postgres 모니터링도 문제가 될 수 있습니다. | Patroni에는 Postgres 서비스를 모니터링하는 내장 메커니즘이 있습니다. |
| 실패한 노드를 클러스터에 다시 자동으로 추가하려면 고급 스크립팅 기술이 필요합니다. | Patroni는 장애가 발생한 노드를 클러스터로 되돌릴 수 있도록 자동화 기능이 내장되어 있습니다. |
| 스플릿 브레인 시나리오를 처리할 수 없습니다. | ETCD의 도움으로 Patroni는 새로운 리더를 선택할 수 있습니다. |
기타 PostgreSQL HA 솔루션은 다음과 같습니다.
- 관리자
- PostgreSQL PAF(자동 복구)
- pglookout
- pgPool-II
그러나 Patroni를 Postgres 구현과 함께 사용하면 전체 클러스터 관리 수명 주기가 크게 간소화됩니다.
-
ETCD는 DCS(분산 구성 저장소)로 사용됩니다. PostgreSQL 클러스터의 상태를 저장합니다. PostgreSQL 노드의 상태가 변경되면 Patroni는 ETCD 키-값 저장소에서 상태 변경을 업데이트합니다. ETCD는 이 정보를 사용하여 마스터 노드를 선택하고 클러스터를 작동 및 실행합니다.
-
pgBackrest은 자동 백업을 위한 단순하고 안정적인 솔루션입니다. Pgbackrest의 이점:
- 물리적 백업 툴이며 Differential, Incremental 및 Full 백업을 수행할 수 있습니다.
- 백업을 수행하도록 병렬 작업을 구성할 수 있습니다.
- 대기 서버에서 백업을 수행할 수 있습니다.
- 비동기 WAL(Write Ahead Archive Log) 푸시 및 풀
- 여러 저장소를 구성할 수 있습니다.
- OCI/GCP/S3/Azure에 대한 클라우드 백업 옵션
-
OCI 네트워크 로드 밸런서는 HAProxy 대신 리더 노드와 통신하는 데 사용됩니다. 관리형 서비스인 OCI(Oracle Cloud Infrastructure) 네트워크 로드 밸런서는 이 설정과 간편하게 통합됩니다.
목표
이 사용지침서에서는 고객이 Postgres 데이터베이스(AWS 또는 기타 클라우드 공급업체)를 OCI로 마이그레이션할 수 있는 잠재적 대안과 더불어 실행 가능한 고성능 솔루션에 대해 설명합니다. 핵심 요구사항은 HA 및 실시간 데이터 마이그레이션입니다.
구조
다음 아키텍처는 ETCD 서버 3개, (Postgres + Patroni + Pgbackrest) 서버 3개, 오브젝트 스토리지 버킷 및 네트워크 로드 밸런서로 구성됩니다.

권장 사항
- HA의 경우 ETCD 서버 3개, PostgreSQL의 노드 3개를 사용하여 다른 가용성 도메인에 배치합니다.
- 처리 능력을 향상시키려면 데이터, 임시, WAL 및 로그 파일에 대해 별도의 블록 볼륨을 생성하십시오.
- 클러스터를 만들 때
patroni.yaml부트스트랩 섹션에서 모든 사용자 정의 매개변수를 정의합니다.
PostgreSQL HA 구성 요소 구성 및 설치
설정은 두 부분으로 나뉩니다.
- 인프라 프로비저닝
- 소프트웨어 설치 및 구성
작업 1: 기반 구조 프로비전
-
컴퓨트 VM 생성:
- 3 ETCD 서버
- Postgres용 서버 3개 + Patroni(1개 리더 및 2개 복제)
-
백업 저장용 오브젝트 스토리지 버킷을 생성합니다.
-
위 객체 저장소 버킷에 대한 READ/WRITE 액세스 권한을 가진 OCI 테넌시 사용자를 생성합니다.
작업 2: 소프트웨어 설치 및 구성
-
ETCD를 구성합니다.
-
3대의 서버에 ETCD를 설치합니다.
cd /tmp wget https://github.com/etcd-io/etcd/releases/download/v3.5.2/etcd-v3.5.2-linux-amd64.tar.gz tar xzvf /tmp/etcd-v3.5.2-linux-amd64.tar.gz cd etcd-v3.5.2-linux-amd64 cp etcdutl etcdctl etcd /usr/local/bin/ mkdir -p /etc/etcd mkdir -p /var/lib/etcd groupadd -f -g 1501 etcd useradd -c "etcd user" -d /var/lib/etcd -s /bin/false -g etcd -u 1501 etcd chown -R etcd:etcd /var/lib/etcd -
모든 3개 서버에서 ETCD를 구성하고 시작합니다.
다음은 ETCD 서버 세부정보입니다.
| Hostname | IP Address | Availability Domain | | --- | --- | --- | | pg-etcd-01 | 192.0.2.4 | AD1 | | pg-etcd-02 | 192.0.2.5 | AD2 | | pg-etcd-03 | 192.0.2.6 | AD3 |주: 요구사항에 따라 IP를 수정합니다.
페이지-etcd-01
vi /etc/etcd/etcd.conf ###Node1 ##192.0.2.4 ETCD_NAME="pg-etcd-01" ETCD_INITIAL_CLUSTER="pg-etcd-01=http://192.0.2.4:2380" ETCD_LISTEN_CLIENT_URLS="http://192.0.2.4:2379,http://127.0.0.1:2379" ETCD_ADVERTISE_CLIENT_URLS="http://192.0.2.4:2379" ETCD_LISTEN_PEER_URLS="http://192.0.2.4:2380,http://127.0.0.1:7001" ETCD_INITIAL_ADVERTISE_PEER_URLS="http://192.0.2.4:2380" ETCD_INITIAL_CLUSTER_TOKEN="etcd-cluster" ETCD_INITIAL_CLUSTER_STATE="new" ETCD_DATA_DIR="/var/lib/etcd" ETCD_ELECTION_TIMEOUT="5000" ETCD_HEARTBEAT_INTERVAL="1000" ETCD_ENABLE_V2="true"페이지-etcd-02
vi /etc/etcd/etcd.conf ##Node2 ##192.0.2.5 ETCD_NAME=" pg-etcd-02" ETCD_INITIAL_CLUSTER="pg-etcd-01=http://192.0.2.4:2380,pg-etcd-02=http://192.0.2.5:2380" ETCD_INITIAL_CLUSTER_TOKEN="etcd-cluster" ETCD_INITIAL_CLUSTER_STATE="existing" ETCD_INITIAL_ADVERTISE_PEER_URLS="http://192.0.2.5:2380" ETCD_LISTEN_PEER_URLS="http://192.0.2.5:2380,http://127.0.0.1:7001" ETCD_LISTEN_CLIENT_URLS="http://192.0.2.5:2379,http://127.0.0.1:2379" ETCD_ADVERTISE_CLIENT_URLS="http://192.0.2.5:2379" ETCD_DATA_DIR="/var/lib/etcd" ETCD_ELECTION_TIMEOUT="5000" ETCD_HEARTBEAT_INTERVAL="1000" ETCD_ENABLE_V2="true"페이지-etcd-03
vi /etc/etcd/etcd.conf ##Node3 ##192.0.2.6 ETCD_NAME="pg-etcd-03" ETCD_INITIAL_CLUSTER="pg-etcd-01=http://192.0.2.4:2380,pg-etcd-02=http://192.0.2.5:2380,pg-etcd-03=http://192.0.2.6:2380" ETCD_INITIAL_CLUSTER_TOKEN="etcd-cluster" ETCD_INITIAL_CLUSTER_STATE="existing" ETCD_INITIAL_ADVERTISE_PEER_URLS="http://192.0.2.6:2380" ETCD_LISTEN_PEER_URLS="http://192.0.2.6:2380,http://127.0.0.1:7001" ETCD_LISTEN_CLIENT_URLS="http://192.0.2.6:2379,http://127.0.0.1:2379" ETCD_ADVERTISE_CLIENT_URLS="http://192.0.2.6:2379" ETCD_DATA_DIR="/var/lib/etcd" ETCD_ELECTION_TIMEOUT="5000" ETCD_HEARTBEAT_INTERVAL="1000" ETCD_ENABLE_V2="true" -
pg-etcd-01에 멤버를 추가합니다.
etcdctl member add pg-etcd-02 --peer-urls=http://192.0.2.5:2380 etcdctl member add pg-etcd-03 --peer-urls=http://192.0.2.6:2380 -
다음 명령을 실행하여 멤버 목록을 표시합니다.
etcdctl member list -
서비스를 만듭니다.
vi /etc/systemd/system/etcd.service [Unit] Description=Etcd Server After=network.target After=network-online.target Wants=network-online.target [Service] Type=notify WorkingDirectory=/var/lib/etcd EnvironmentFile=-/etc/etcd/etcd.conf User=etcd # set GOMAXPROCS to number of processors ExecStart=/bin/bash -c "GOMAXPROCS=$(nproc) /usr/local/bin/etcd" Restart=on-failure LimitNOFILE=65536 IOSchedulingClass=best-effort IOSchedulingPriority=0 [Install] WantedBy=multi-user.target systemctl daemon-reload systemctl enable etcd
-
-
모든 노드에 Postgres를 설치합니다. 다음 스크립트를 실행하여 Postgres를 설치합니다.
-
주: 복제의 경우 postgresql을 중지하고 데이터 디렉토리가 Patroni 구성이 완료되면 리더에서 복사되므로 삭제합니다.
/opt/pgsql/bin/pg_ctl -D /opt/pgsql/data/$MAJORVERSION stop cd /opt/pgsql/data/ rm *
-
-
확장자 설치: pg_squeeze 및 pgaudit.
-
PGAUDIT 설치
cd /usr/local/src/postgresql-12.6/contrib/ wget https://github.com/pgaudit/pgaudit/archive/refs/heads/REL_12_STABLE.zip unzip REL_12_STABLE.zip make install USE_PGXS=1 PG_CONFIG=/opt/pgsql/bin/pg_config -
PG_SQUEEZE 설치
cd /usr/local/src/postgresql-12.6/contrib/ wget https://github.com/cybertec-postgresql/pg_squeeze/archive/refs/heads/master.zip unzip master.zip make install USE_PGXS=1 PG_CONFIG=/opt/pgsql/bin/pg_config
-
-
모든 노드에 Patroni를 설치합니다.
yum update –y yum -y install epel-release yum -y install python3 yum install -y python3-devel yum install -y psutils yum install -y gcc yum install https://download.postgresql.org/pub/repos/yum/reporpms/EL-7-x86_64/pgdg-redhat-repo-latest.noarch.rpm yum install python3-psycopg2 pip3 install python-etcd pip3 install patroni -
모든 노드에 pgBackrest를 설치하고 구성합니다.
-
Pgbackrest 설치
yum install https://download.postgresql.org/pub/repos/yum/reporpms/EL-7-x86_64/pgdg-redhat-repo-latest.noarch.rpm sudo yum install pgbackrest -y -
모든 노드에서 Pgbackrest 구성
/etc/pgbackrest.conf [global] repo1-type=s3 repo1-path=/backup repo1-s3-uri-style=path repo1-s3-region=us-ashburn-1 repo1-s3-endpoint=https://xxxxx0011.compat.objectstorage.us-ashburn-1.oraclecloud.com repo1-s3-key=0000000a90d57eddexxxxxa3dc7c4f700000ed2e6 repo1-s3-key-secret=1UhXj69xxxx1e6OyF+00000cccccyyyuuu= repo1-s3-bucket=pg_backup repo1-retention-full=10 log-level-console=info log-level-file=debug log-path=/var/log/pgbackrest/ [stanza-name] pg1-path=/opt/pgsql/data pg1-user=Postgres -
모든 노드에서 부트스트랩 파일 만들기
vi /etc/patroni/boot_pgbackrest.sh #!/ usr / bin /env bash while getopts ": -:" optchar ; do [[ "${ optchar }" == "-" ]] || continue case "${ OPTARG }" in datadir =* ) DATA_DIR =${ OPTARG #*=} ;; scope =* ) SCOPE =${ OPTARG #*=} ;; esac done /bin/pgbackrest --stanza=$SCOPE --link-all restore
-
-
모든 노드에서 Patroni를 구성합니다.
호스트 이름 IP 주소 가용성 도메인 페이지-db-01 192.0.2.1 AD1 페이지-db-02 192.0.2.2 AD2 페이지-db-03 192.0.2.3 AD3 주: 요구사항에 따라 IP를 수정합니다.
mkdir -p /etc/patroni mkdir -p /opt/pgsql/patroni chown postgres:postgres -R /opt/pgsql/patroni chmod 700 /opt/pgsql/patroni vi /etc/patroni/patroni.yml scope:pg-ha-cluster name:pg-db-01 namespace:/opt/pgsql/patroni/ ### restapi: listen: "192.0.2.1:8008" connect_address: "192.0.2.1:8008" ###ETCD Configuration etcd: hosts: "192.0.2.4:2379,192.0.2.5:2379, 192.0.2.6:2379" ###Bootstrap bootstrap: dcs: ttl: 120 loop_wait: 10 retry_timeout: 10 maximum_lag_on_failover: 1048576 postgresql: use_pg_rewind: true use_slots: true parameters: archive_command: "pgbackrest --stanza=<stanza-name> archive-push %p" archive_mode: on archive_timeout: 900s log_file_mode: "0640" log_filename: postgresql-%u.log log_rotation_age: 1d log_truncate_on_rotation: "on" logging_collector: "on" max_connections: 2000 max_replication_slots: 10 max_wal_senders: 10 max_wal_size: 5GB max_worker_processes: 40 min_wal_size: 1GB wal_level: "replica" password_encryption: scram-sha-256 superuser_reserved_connections: 200 create_replica_methods: - pgbackrest pgbackrest: command: "/usr/bin/pgbackrest --stanza=<stanza-name> restore --delta --link-all" keep_data: True no_params: True recovery_conf: recovery_target_timeline: latest restore_command: '/usr/bin/pgbackrest --stanza=<stanza-name> archive-get %f %P' method: pgbackrest pgbackrest: command: /etc/patroni/boot_pgbackrest.sh keep_existing_recovery_conf: False recovery_conf: recovery_target_timeline: latest restore_command: '/usr/bin/pgbackrest --stanza=<stanza-name> archive-get %f %P' initdb: - encoding: UTF8 - data-checksums pg_hba: - host replication replicator 127.0.0.1/32 md5 - host replication replicator 192.0.2.1/32 md5 - host replication replicator 192.0.2.2/32 md5 - host replication replicator 192.0.2.3/32 md5 - host all all x.x.x.0/0 md5 users: admin: password: admin options: - createrole - createdb #####Local Postgresql Parameters postgresql: listen: "192.0.2.1:5432" connect_address: "192.0.2.1:5432" data_dir: /opt/pgsql/data pgpass: /opt/pgsql/patroni/pgpass authentication: replication: username: replicator password: password superuser: username: postgres password: password # rewind: # username: replicator # password: password parameters: unix_socket_directories: "/var/run/postgresql, /tmp" ###Any Tags tags: nofailover: false noloadbalance: false clonefrom: false nosync: false주: 노드마다 IP를 변경하십시오.
chmod 640 /etc/patroni/patroni.yml chown postgres:postgres -R /etc/patroni/patroni.yml- 모든 노드에 Patroni 서비스 생성
vi /etc/systemd/system/patroni.service [Unit] Description=Runners to orchestrate a high-availability PostgreSQL - patroni After=syslog.target network.target [Service] Type=simple User=postgres Group=postgres # Read in configuration file if it exists, otherwise proceed EnvironmentFile=-/etc/patroni_env.conf WorkingDirectory=~ # Where to send early-startup messages from the server # This is normally controlled by the global default set by systemd # StandardOutput=syslog# Pre-commands to start watchdog device # Uncomment if watchdog is part of your patroni setup #ExecStartPre=-/usr/bin/sudo /sbin/modprobe softdog #ExecStartPre=-/usr/bin/sudo /bin/chown postgres /dev/watchdog # Start the patroni process ExecStart=/usr/local/bin/patroni /etc/patroni/patroni.yml # Send HUP to reload from patroni.yml ExecReload=/bin/kill -s HUP $MAINPID # Only kill the patroni process, not its children, so it will gracefully stop postgres KillMode=process # Give a reasonable amount of time for the server to start up/shut down TimeoutSec=60 # Do not restart the service if it crashes, we want to manually inspect database on failure Restart=no [Install] WantedBy=multi-user.target sudo systemctl daemon-reload sudo systemctl enable patroni sudo systemctl start patroni sudo systemctl status patroni주: 복제 노드에서 Patroni를 구성하되 서비스는 시작하지 마십시오.
-
다음 명령을 실행하여 마스터에서 Patroni 클러스터 상태를 확인합니다.
patronictl -c /etc/patroni/patroni.yml list [root@pg-db-01 ~]# /usr/local/bin/patronictl -c /etc/patroni/patroni.yml list +--------------+-------------+---------+---------+----+-----------+ | Member | Host | Role | State | TL | Lag in MB | + Cluster: pg-ha-cluster (7089354141421597068) --+----+-----------+ | pg-db-01 | 192.0.2.1 | Leader | running | 1 | | +--------------+-------------+---------+---------+----+-----------+
-
Stanza를 만들고 전체 백업을 수행하십시오.
pgbackrest --stanza=<stanza-name> stanza-create pgbackrest --type=full --stanza= pgha --process-max=10 backup pgbackrest info -
Replica 노드에서 Patroni를 시작하면 Leader로부터 자동으로 캐치업이 시작됩니다.
sudo systemctl start patroni sudo systemctl status patroni- 다음 명령을 실행하여 클러스터 상태를 확인합니다.
patronictl -c /etc/patroni/patroni.yml list상태는 다음과 같아야 합니다.
[root@pg-db-01 ~]# /usr/local/bin/patronictl -c /etc/patroni/patroni.yml list +--------------+-------------+---------+---------+----+-----------+ | Member | Host | Role | State | TL | Lag in MB | + Cluster: pg-ha-cluster (7089354141421597068) --+----+-----------+ | pg-db-01 | 192.0.2.1 | Leader | running | 2 | | | pg-db-02 | 192.0.2.2 | Replica | running |2 | 0 | | pg-db-03 | 192.0.2.3 | Replica | running | 2 | 0 | +--------------+-------------+---------+---------+----+-----------+ -
마지막으로 로그 정리, 백업 등에 대한 cron 작업을 설정합니다.
crontab –e #Pgbackrest FULL Backup on Sunday @1AM 00 01 * * 0 postgres pgbackrest --type=full --stanza=ash1-adeprod1-pgcluster --process-max=10 backup &> /dev/null #Pgbackrest INC Backup on Mon-Sat @1AM 00 01 * * 1-6 postgres pgbackrest --type=diff --stanza=ash1-adeprod1-pgcluster --process-max=10 backup &> /dev/null #Delete PostgreSQL logs 08 * * * find /opt/pgsql/log/* -mtime +15 -exec rm {} \; &>/dev/null
추가 Patroni 명령
-
목록 구성원
patronictl -c /etc/patroni/patroni.yml list -
페일오버/재시작/전환
patronictl -c /etc/patroni/patroni.yml failover patronictl -c /etc/patroni/patroni.yml restart patronictl -c /etc/patroni/patroni.yml switchover -
매개변수 업데이트
patronictl -c /etc/patroni/patroni.yml edit-config -p log_directory='/opt/pgsql/log/' patronictl -c /etc/patroni/patroni.yml show-config -
새로 고침
patronictl -c /etc/patroni/patroni.yml reload <cluster_name>
관련 링크
- Linux 인스턴스를 만드는 방법
- 오브젝트 스토리지 버킷 개요
- IAM 유저 생성
- 네트워크 로드 밸런서를 생성하는 방법
- 고객 키 작업
- PostgreSQL 다운로드
- PostgresSQL 설치
- 파트로니
- Etcd 설치
승인
- Authors: Deepika Nayak, Shreyas Rane, Divya Das
추가 학습 자원
docs.oracle.com/learn에서 다른 실습을 살펴보거나 Oracle Learning YouTube 채널에서 보다 무료 학습 컨텐츠에 접근할 수 있습니다. 또한 education.oracle.com/learning-explorer을 방문하여 Oracle Learning Explorer가 됩니다.
제품 설명서는 Oracle Help Center를 참조하십시오.
Deploy a highly available Postgres cluster on Oracle Cloud Infrastructure
F74179-01
November 2022
Copyright © 2022, Oracle and/or its affiliates.