728x90
pgpool 테스트에 앞서 요구사항을 정리하겠습니다.
각 서버 인스턴스에는 pgpool, postgresql이 설치되어 있고, 동일한 네트워크 명에 속해야 합니다.
1. pgpool 및 postgresql 실행
# Primary 서버의 Postgresql 인스턴스 실행
[server1]# su - postgres
[server1]$ /usr/pgsql-17/bin/pg_ctl start -D $PGDATA
# 모든 서버의 pgpool 서비스 시작
[all servers]# systemctl start pgpool.service
# 참고 : 서버를 중단할 경우는 pgpool을 먼저 종료하고 postgresql을 종료합니다.
[all servers]# systemctl stop pgpool.service
2. _!show pool_nodes!_ 명령어를 통해 인스턴스(노드) 확인
~ 18.3s | 2 ❱ psql -h 192.168.122.199 -p 9999 -U pgpool postgres -c "show pool_nodes"
Password for user pgpool:
node_id | hostname | port | status | pg_status | lb_weight | role | pg_role | select_cnt | load_balance_node
| replication_delay | replication_state | replication_sync_state | last_status_change
---------+----------+------+--------+-----------+-----------+---------+---------+------------+-------------------
+-------------------+-------------------+------------------------+---------------------
0 | pg1 | 5432 | up | up | 0.333333 | primary | primary | 0 | true
| 0 | | | 2025-03-11 15:14:34
1 | pg2 | 5432 | down | down | 0.333333 | standby | unknown | 0 | false
| 0 | | | 2025-03-22 00:39:42
2 | pg3 | 5432 | down | down | 0.333333 | standby | unknown | 0 | false
| 0 | | | 2025-03-22 00:39:40
(3 rows)
3. 앞서 설정해두었던 _!pcp_recovery!_ 스크립트가 작동 테스트
# pg2 서버 recovery 동작
~ ❱ pcp_recovery_node -h 192.168.122.199 -p 9898 -U pgpool -n 1 -W
Password:
pcp_recovery_node -- Command Successful
# pg2 서버 recovery 동작
~ 2.5s ❱ pcp_recovery_node -h 192.168.122.199 -p 9898 -U pgpool -n 2 -W
Password:
pcp_recovery_node -- Command Successful
# 모든 서버가 구동된 것을 확인할 수 있습니다!
~ 3s ❱ psql -h 192.168.122.199 -p 9999 -U pgpool postgres -c "show pool_nodes"
Password for user pgpool:
node_id | hostname | port | status | pg_status | lb_weight | role | pg_role | select_cnt | load_balance_node
| replication_delay | replication_state | replication_sync_state | last_status_change
---------+----------+------+--------+-----------+-----------+---------+---------+------------+-------------------
+-------------------+-------------------+------------------------+---------------------
0 | pg1 | 5432 | up | up | 0.333333 | primary | primary | 0 | false
| 0 | | | 2025-03-11 15:14:34
1 | pg2 | 5432 | up | up | 0.333333 | standby | standby | 0 | true
| 0 | streaming | async | 2025-03-22 00:41:40
2 | pg3 | 5432 | up | up | 0.333333 | standby | standby | 0 | false
| 0 | streaming | async | 2025-03-22 00:41:40
(3 rows)
4. pgpool이 watchdog에 의해 서로 관리 테스트
# pg1 서버가 pgpool의 리더역할을 수행하고 있음을 알 수 있습니다!
~ ❱ pcp_watchdog_info -h 192.168.122.199 -p 9898 -U pgpool -W
Password:
3 3 YES pg1:9999 Linux pg1 pg1
pg1:9999 Linux pg1 pg1 9999 9000 4 LEADER 0 MEMBER
pg2:9999 Linux pg2 pg2 9999 9000 7 STANDBY 0 MEMBER
pg3:9999 Linux pg3 pg3 9999 9000 7 STANDBY 0 MEMBER
5. pgpool 서비스를 중단하고 watchdog에 의해 다른 pgpool 인스턴스가 리더를 위임 테스트
# pg1 서버에서 pgpool 중단
[root@pg1 pgsql]# systemctl stop pgpool
# pg1 서버가 중단되어 pg3으로 리더가 위임되었습니다!
~ 1.8s ❱ pcp_watchdog_info -p 9898 -h 192.168.122.199 -U pgpool -W
Password:
3 3 YES pg3:9999 Linux pg3 pg3
pg3:9999 Linux pg3 pg3 9999 9000 4 LEADER 0 MEMBER
pg1:9999 Linux pg1 pg1 9999 9000 10 SHUTDOWN 0 MEMBER
pg2:9999 Linux pg2 pg2 9999 9000 7 STANDBY 0 MEMBER
6. pgpool 서비스를 복구하고 standby member 로 복귀 테스트
# pgpool 서비스 시작
[root@pg1 pgsql]# systemctl start pgpool
# pg1가 복구되고 standby 멤버로 역할합니다.
~ 2.1s ❱ pcp_watchdog_info -p 9898 -h 192.168.122.199 -U pgpool -W
Password:
3 3 YES pg3:9999 Linux pg3 pg3
pg3:9999 Linux pg3 pg3 9999 9000 4 LEADER 0 MEMBER
pg1:9999 Linux pg1 pg1 9999 9000 7 STANDBY 0 MEMBER
pg2:9999 Linux pg2 pg2 9999 9000 7 STANDBY 0 MEMBER
7. postgresql 서비스가 종료되었을 경우 failover 테스트
# 위의 테스트를 마치고 모든 노드가 정상 동작하는지 확인
~ 2.7s | 2 ❱ psql -h 192.168.122.199 -p 9999 -U pgpool postgres -c "show pool_nodes"
Password for user pgpool:
node_id | hostname | port | status | pg_status | lb_weight | role | pg_role | select_cnt | load_balance_node
| replication_delay | replication_state | replication_sync_state | last_status_change
---------+----------+------+--------+-----------+-----------+---------+---------+------------+-------------------
+-------------------+-------------------+------------------------+---------------------
0 | pg1 | 5432 | up | up | 0.333333 | primary | primary | 0 | false
| 0 | | | 2025-03-22 00:49:58
1 | pg2 | 5432 | up | up | 0.333333 | standby | standby | 0 | true
| 0 | streaming | async | 2025-03-22 00:49:58
2 | pg3 | 5432 | up | up | 0.333333 | standby | standby | 0 | false
| 0 | streaming | async | 2025-03-22 00:49:58
(3 rows)
# 문제 없습니다!
# pg1의 postgresql 서비스를 중단해보겠습니다.
[postgres@pg1 ~]$ /usr/pgsql-17/bin/pg_ctl -D /var/lib/pgsql/17/data -m immediate stop
waiting for server to shut down.... done
server stopped
# pg1 서버가 중단되어 pg2 서버의 postgresql 인스턴스가 새로운 primary로 등록되었습니다.
~ 1.5s ❱ psql -h 192.168.122.199 -p 9999 -U pgpool postgres -c "show pool_nodes"
Password for user pgpool:
node_id | hostname | port | status | pg_status | lb_weight | role | pg_role | select_cnt | load_balance_node
| replication_delay | replication_state | replication_sync_state | last_status_change
---------+----------+------+--------+-----------+-----------+---------+---------+------------+-------------------
+-------------------+-------------------+------------------------+---------------------
0 | pg1 | 5432 | down | down | 0.333333 | standby | unknown | 0 | false
| 0 | | | 2025-03-22 00:52:09
1 | pg2 | 5432 | up | up | 0.333333 | primary | primary | 0 | true
| 0 | | | 2025-03-22 00:52:09
2 | pg3 | 5432 | down | up | 0.333333 | standby | standby | 0 | false
| 312960 | streaming | async | 2025-03-22 00:52:09
(3 rows)
# 중단된 서버를 원격으로 recovery 하겠습니다.
~ 1.9s ❱ pcp_recovery_node -h 192.168.122.199 -p 9898 -U pgpool -n 0 -W
Password:
pcp_recovery_node -- Command Successful
# 명령어가 제대로 동작해 pg1 postgresql 서비스가 복구되었습니다.
~ 3.7s ❱ psql -h 192.168.122.199 -p 9999 -U pgpool postgres -c "show pool_nodes"
Password for user pgpool:
node_id | hostname | port | status | pg_status | lb_weight | role | pg_role | select_cnt | load_balance_node
| replication_delay | replication_state | replication_sync_state | last_status_change
---------+----------+------+--------+-----------+-----------+---------+---------+------------+-------------------
+-------------------+-------------------+------------------------+---------------------
0 | pg1 | 5432 | up | up | 0.333333 | standby | standby | 0 | false
| 0 | streaming | async | 2025-03-22 00:53:59
1 | pg2 | 5432 | up | up | 0.333333 | primary | primary | 0 | true
| 0 | | | 2025-03-22 00:52:09
2 | pg3 | 5432 | down | up | 0.333333 | standby | standby | 0 | false
| 20304 | streaming | async | 2025-03-22 00:52:09
(3 rows)
# 그런데 pg3 서비스도 죽어있습니다. 마찬가지로 원격으로 복구하겠습니다.
~ 1.4s ❱ pcp_recovery_node -h 192.168.122.199 -p 9898 -U pgpool -n 2 -W
Password:
pcp_recovery_node -- Command Successful
~ 2.3s ❱ psql -h 192.168.122.199 -p 9999 -U pgpool postgres -c "show pool_nodes"
Password for user pgpool:
node_id | hostname | port | status | pg_status | lb_weight | role | pg_role | select_cnt | load_balance_node
| replication_delay | replication_state | replication_sync_state | last_status_change
---------+----------+------+--------+-----------+-----------+---------+---------+------------+-------------------
+-------------------+-------------------+------------------------+---------------------
0 | pg1 | 5432 | up | up | 0.333333 | standby | standby | 0 | true
| 0 | streaming | async | 2025-03-22 00:53:59
1 | pg2 | 5432 | up | up | 0.333333 | primary | primary | 0 | false
| 0 | | | 2025-03-22 00:52:09
2 | pg3 | 5432 | up | up | 0.333333 | standby | standby | 0 | false
| 0 | streaming | async | 2025-03-22 00:54:25
(3 rows)
# 성공하고 모든 인스턴스가 정상 작동하고 있습니다.
클러스터를 데이터베이스로서 사용
pgpool의 VIP:5432 포트로 데이터베이스에 접근 가능하며 평소처럼 사용 가능합니다.
단, 데이터베이스 사용자가 추가될 경우 pgpool의 _!.pool_passwd!_ 파일에도 반드시 해당 사용자와 비밀번호를 입력해주어야 pgpool이 인식하고 접속을 허가합니다. (pgpool과 postgresql의 인증은 개별적으로 관리되고 있습니다.)
정리하며
이로써 pgpool + watchdog의 기본 설정을 해보고 직접 기능 테스트까지 완료했습니다. 테스트 중에서도 드러났지만 (pg3 서버의 인스턴스가 down 표기), 유지보수 간 예상과 다르게 서비스가 동작하는 경우가 종종 있는 것 같습니다. 관련 데이터를 찾아보려고 했으나, 워낙 레퍼런스가 적은 기술이다 보니 확실히 할 수는 없었습니다. 그러나 _!pcp_recovery_node!_ 명령어가 명확히 동작하고 클러스터가 구성되었다는 것을 확인했습니다.
다음 포스팅에서는 이런 점을 고려한 내부용 데이터베이스 서버를 구성하며 도입한 _!repmgr + pgpool!_ 사례를 소개하도록 하겠습니다.