pgpool 4.1.4 auto fail-over, fail-back

2021. 6. 20. 23:22개발 이야기/Postgresql

이전글에서 postgresql stream replication 을 해봤고 pgpool 을 이용해서 로드밸런스까지 만들어봤습니다.

이제 추가적으로 하려고 하는 작업은

  • pgpool 을 이용한 자동 fail-over, fail-back
  • pgpool 을 이중화(watchdog 을 이용한 vip 적용)

이렇게 두가지까지 하면 DB쪽에서 제가 하려고 하는 것은 다 되는것 같습니다.

 

watchdog 이 무엇인지 몰라 한참을 찾아봤는데요.

두개의 pgpool 노드가 있을때 서로 서비스가 살아있는지를 지속적으로 체크해서 죽었다면 안죽은 쪽으로 vip를 셋팅해주는 역할을 하는것 같습니다. 

db도 master / slave 가 있듯이 pgpool 도 2개 이상 설치하면 master / slave 구조를 갖도록 셋팅을 할 수 있는 듯합니다.

만약 2개를 설치했는데 db1이 죽었었다면 자동으로 전환을 해야하는데 pgpool 두개중 어떤 프로세스가 돌아갈지 궁금했는데요.

자체 설정으로 master 로 셋팅된 노드가 실행하는게 아닌가 싶습니다. 그때 watchdog 이 체크하면서 안죽놈을 master 로 승격시킬테구요. 그리고 본래 별도로 사용할수도 있지만 pgpool 을 설치하면 내장 기능으로 같이 설치가 되는것 같구요.

 

vip라는 것을 저는 사용해본적이 없다보니까 그리고 클라우드 가상화에서 잘 적용이 될지는 모르겠습니다.

이것저것 찾아보면서 한번 셋팅해 보겠습니다.

 

Auto Fail-Over 셋팅하기

이전글에서 수동으로 하나씩은 해봤습니다.

  1. db1 stop
  2. db2 에서 명령을 통해 master 승격 (fail-over)
  3. db1 을 장애복구 하고
  4. db1을 다시 slave 셋팅 (fail-back)

일단 셋팅을 보다가 한가지 의문점이 생겼습니다.

/etc/postgresql/13/main/postgresql.conf

에 보면 promote_trigger_file 설정이 있습니다.

이 설정은 과거 trigger_file 이라는 설정이 이름이 바꼈다고 하는데요.

역할은 저기에 정의해둔 파일이 생성이 되면 slave 로 작동하는 서버를 master 로 승격하라는 일종의 명령이 되더군요.

실험해보니 정말 되더라구요.

 

그래서 auto failover 를 구성할때 스크립트를 통해서 해당 파일을 만들어 버리면 자동으로 승격되도록 한다는 시나리오입니다. 제가 테스해본 내용을 적은 포스트에서는 pg_ctl 이라는 명령을 이용하기도 했습니다.

아무튼 그러한 것들을 확인하는 과정에서 해결하지 못하는 문제가 있었는데요.

 

처음 slave 서버 구성시 다음과 같이 master 에서 데이터를 가져옵니다.

sudo -u postgres pg_basebackup -h 10.34.96.3 -D /var/lib/postgresql/13/main -U replication -v -P --wal-method=stream --write-recovery-conf

 

그러면 맨 마지막에 있는 --write-recovery-conf 옵션에 의해서 자동으로 데이터 파일 위치에 다음 파일이 생성됩니다.

  • standby.signal
  • postgresql.auto.conf

이렇게 두개가 생성이 됩니다.

일단 slave 로 동작하기 위해서는 trigger 파일처럼 standby.signal 파일이 있어야만 동작을 하는것 같습니다.

그리고 postgresql.auto.conf 안에는 master 의 연결 정보가 자동으로 들어가 있습니다.

근데 이 설정이 primary_conninfo 라고 postgresql.conf 에도 동일하게 존재합니다.

둘다 셋팅을 해보니 postgresql.auto.conf 가 나중에 적용되어 최종 설정으로 적용되는것 같더라구요.

저는 저 설정을 수동으로 설정을 하고 싶어서 --write-recovery-conf 옵션을 빼고 Master 를 카피하는 형태로 바꿔보려고 합니다.

postgresql.conf 쪽에 동일한 셋팅을 하구요. 어느쪽에 넣어도 동작은 하는것 같습니다.

일전에 썼던 블로그 내용도 조금 수정을 해놔야 겠습니다.

일단 아래 이어질 내용은 이러한 배경으로 진행하고자 합니다.

 

 

먼저 시스템이 다운되었을 때 failover 동작을 실행시키기 위해서 설정파일을 수정합니다.

 

root@ggmoney-db1:/var/lib/postgresql/13/main# vi /etc/pgpool2/pgpool.conf

#------------------------------------------------------------------------------
# FAILOVER AND FAILBACK
#------------------------------------------------------------------------------

failover_command = '/etc/pgpool2/failover.sh %d %P %H %R'

지장한 파일을 만들도록 합니다.

root@ggmoney-db1:/var/lib/postgresql/13/main# vi /etc/pgpool2/failover.sh

#! /bin/sh -x
# Execute command by failover.
# special values:  %d = node id
#                  %h = host name
#                  %p = port number
#                  %D = database cluster path
#                  %m = new master node id
#                  %H = new master node host name
#                  %M = old master node id
#                  %P = old primary node id
#                  %r = new master port number
#                  %R = new master database cluster path
#                  %% = '%' character

falling_node=$1          # %d
old_primary=$2           # %P
new_primary=$3           # %H
pgdata=$4                # %R

pghome=/usr/lib/postgresql/13
log=/var/log/pgpool/failover.log

date >> $log
echo "failed_node_id=$falling_node new_primary=$new_primary" >> $log

if [ $falling_node = $old_primary ]; then
    if [ $UID -eq 0 ]
    then
       su postgres -c "ssh -T postgres@$new_primary $pghome/bin/pg_ctl promote -D $pgdata"
    else
        ssh -T postgres@$new_primary $pghome/bin/pg_ctl promote -D $pgdata
    fi
    exit 0;
fi;
exit 0;

서비스가 해당 파일을 실행시킬수 있도록 권한도 조정해 줍니다.

root@ggmoney-db1:/var/lib/postgresql/13/main# chmod 755 /etc/pgpool2/failover.sh

로그파일이 생성될 디렉토리도 만들어준다.

root@ggmoney-db1:/var/lib/postgresql/13/main# mkdir /var/log/pgpool/
root@ggmoney-db1:/var/lib/postgresql/13/main# chown root:postgres /var/log/pgpool/
root@ggmoney-db1:/var/lib/postgresql/13/main# chmod 775 /var/log/pgpool/

failover 되었을때 slave로 접속해서 master 승격 메세지를 보내야하는데 이때 ssh 를 사용한다.

스크립트 내에서 패스워드를 치고 들어가는 것을 자동으로 하기 위해서 sshkey 를 생성해준다.

# ssh 키 파일의 위치는 아래와 같네요
root@ggmoney-db1:/var/lib/postgresql# ls -al
total 28
drwxr-xr-x  4 postgres postgres 4096 Jun 20 13:53 .
drwxr-xr-x 41 root     root     4096 Jun 17 10:32 ..
drwxr-xr-x  7 postgres postgres 4096 Jun 18 22:08 13
-rw-------  1 postgres postgres  867 Jun 20 13:57 .bash_history
-rw-------  1 postgres postgres  268 Jun 19 08:46 .psql_history
drwx------  2 postgres postgres 4096 Jun 20 13:56 .ssh
-rw-------  1 postgres postgres 1353 Jun 19 08:50 .viminfo

root@ggmoney-db1:/var/lib/postgresql# su - postgres

root@ggmoney-db1:/var/lib/postgresql# ssh-keygen

계속 엔터

# 생성된 키를 slave 에도 넣어줍니다.
root@ggmoney-db1:/var/lib/postgresql# ssh-copy-id postgres@10.34.96.4

블로그에는 짧게 적었지만 여기까지 작독하고 테스트 해보는데 시간이 엄청 오래 걸렸습니다.

위 설정까지 마치고 강제로 master 의 postgresql 을 down 시켜봤습니다.

 node_id |  hostname  | port | status | lb_weight |  role   | select_cnt | load_balance_node | replication_delay | replication_state | replication_sync_state | last_status_change
---------+------------+------+--------+-----------+---------+------------+-------------------+-------------------+-------------------+------------------------+---------------------
 0       | 10.34.96.3 | 5432 | down   | 0.500000  | standby | 31         | false             | 0                 |                   |                        | 2021-06-20 14:09:29
 1       | 10.34.96.4 | 5432 | up     | 0.500000  | primary | 354        | true              | 0                 |                   |                        | 2021-06-20 14:09:29
(2 rows)

그랬더니 보시는 것처럼 slave (node_id 1) 가 role이 primary 로 변경되었습니다.

자동 failover 가 된 것이죠.

 

이제 failback 과 watchdog 을 해보겠습니다.