// docker를 이용한 PostgreSQL replication
// OS release : centos 7 (3.10.0-1127.el7.x86_64)
// docker 설치
[root@test]$ yum install docker -y
[root@test]$ systemctl enable docker
[root@test]$ systemctl start docker
// pgpool 설치 (failover 및 failback에 사용되는 패키지)
[root@test]$ yum install -y https://www.pgpool.net/yum/rpms/4.2/redhat/rhel-7-x86_64/pgpool-II-pg10-4.2.1-1pgdg.rhel7.x86_64.rpm
[root@test]$ yum install -y https://www.pgpool.net/yum/rpms/4.2/redhat/rhel-7-x86_64/pgpool-II-pg10-devel-4.2.1-1pgdg.rhel7.x86_64.rpm
[root@test]$ yum install -y https://www.pgpool.net/yum/rpms/4.2/redhat/rhel-7-x86_64/pgpool-II-pg10-debuginfo-4.2.1-1pgdg.rhel7.x86_64.rpm
[root@test]$ yum install -y https://www.pgpool.net/yum/rpms/4.2/redhat/rhel-7-x86_64/pgpool-II-pg10-extensions-4.2.1-1pgdg.rhel7.x86_64.rpm
// docker 디렉토리 확인 및 postgresql v.10 설치
[root@test]$ ls -l /var/lib/docker/
[root@test]$ docker pull postgres:10
// 설치된 docker 이미지 확인
[root@test]$ docker images
// docker 네트워크 생성 (각 노드의 ip를 static하게 주기위함)
[root@test]$ docker network create --subnet 172.18.0.0/16 mynet1
// docker 볼륨 생성 (각 노드의 저장소를 specific하게 지정하기 위함)
[root@test]$ docker volume create pgdata1
[root@test]$ docker volume create pgdata2
// postgresql docker container 생성
// 서로 다른 서버를 사용한다면 docker run 옵션에 --port를 추가하여 설정 (ex. 5432:5432/tcp)
[root@test]$ docker run -d -it --network mynet1 --ip 172.18.0.10 --name pg_node1 -e POSTGRES_PASSWORD=postgres -v pgdata1:/var/lib/postgresql/data postgres:10
[root@test]$ docker run -d -it --network mynet2 --ip 172.18.0.20 --name pg_node2 -e POSTGRES_PASSWORD=postgres -v pgdata1:/var/lib/postgresql/data postgres:10
// 생성된 postgresql docker container 확인
[root@test]$ docker ps
// pg_node1 이중화를 위한 서버 setting
[root@test]$ docker exec -it pg_node1 bash
#DOCKER> root@pg_node1 $ apt-get update
#DOCKER> root@pg_node1 $ apt-get install -y ssh rsync vim sudo net-tools iputils-ping procps
// postgres 계정 ssh 접속을 위해 비밀번호 설정
#DOCKER> root@pg_node1 $ passwd postgres
#DOCKER> root@pg_node1 $ su - postgres
// 테스트를 위해 데이터베이스와 테이블을 생성
#DOCKER> postgres@pg_node1 $ psql
postgres=# create database mydb;
postgres=# \connect mydb
mydb=# create table repl_test (no int, name varchar(20));
mydb=# insert into repl_test values (1,'AAAA');
mydb=# commit;
// replication setting
mydb=# select proname from pg_proc where proname like 'pg_create_physical%';
mydb=# select * from pg_create_pg_create_physical_replication_slot('repl_slot_01');
mydb=# create role replication with replication password 'replication' login;
// wal 상태 확인
mydb=# SELECT name, setting FROM pg_settings
mydb-# WHERE name IN ('archive_mode', 'archive_command', 'archive_timeout', 'wal_level', 'max_wal_senders');
name | setting
-----------------------+--------------------------------------
archive_command | cp %p /var/lib/postgresql/archive/%f
archive_mode | on
archive_timeout | 0
max_wal_senders | 2
wal_level | replica
(5 rows)
mydb=# \q
// 설정이 안되어 있다면 /var/lib/postgresql/data 에 있는 postgresql.conf 를 변경하고 다시 docker restart
#DOCKER> postgres@pg_node1 $ vi postgresql.conf
wal_level = replica -- 9.6 이전에는 archive
archive_mode = on
archive_command = 'cp %p /var/lib/postgresql/archive/%f'
max_wal_senders = 2
#DOCKER> postgres@pg_node1 $ mkdir /var/lib/postresql/archive
// pg_hba.conf 설정 (docker로 설치 시, 하단에 모든 접근 가능하도록 설정이 되어있긴함.)
#DOCKER> postgres@pg_node1 $ vi pg_hba.conf
host replication replication 172.18.0.0/16 md5 -- 하단에 추가
#DOCKER> postgres@pg_node1 $ exit
#DOCKER> root@pg_node1 $ exit
[root@test]$ docker restart pg_node1
// pg_node2에 pg_basebackup을 이용해 데이터베이스 복제
[root@test]$ docker stop pg_node2
[root@test]$ cd /var/lib/docker/volumes/pgdata2/_data
[root@test]$ rm -rf ./*
[root@test]$ pg_basebackup -h 172.18.0.10 -p 5432 -D /var/lib/docker/volumes/pgdata2/_data -U replication -P -v -X stream
[root@test]$ chown -R polkitd:input .
[root@test]$ vi ./recovery.conf
standby_mode=on
primary_conninfo='host=172.18.0.10 port=5432 user=replication password=replication'
primary_slot_name='repl_slot_01'
trigger_file='/var/lib/postgresql/data/failover_trigger'
// pg_node2 server setting 및 replication 확인
[root@test]$ docker start pg_node2
[root@test]$ docker exec -it pg_node2 bash
#DOCKER> root@pg_node2 $ apt-get update
#DOCKER> root@pg_node2 $ apt-get install -y ssh rsync vim sudo net-tools iputils-ping procps
#DOCKER> root@pg_node2 $ su - postgres
#DOCKER> postgres@pg_node2 $ mkdir /var/lib/postgresql/archive
#DOCKER> postgres@pg_node2 $ psql
postgres=# select proname from pg_proc where proname like '%recovery%';
// 아래 명령어를 입력해서 결과 값이 t가 나온다면 pg_node2 는 standby로 동작 중임을 의미한다.
postgres=# select * from pg_is_in_recovery();
// 정확한 확인을 위해 pg_node1에서 쿼리 실행해본다.
postgres=# select * from pg_stat_replication;
postgres=# \connect mydb
postgres=# insert into repl_test values (2,'BBBB');
// pgpool을 위해 각 node에 ssh 서비스를 실행시켜준다.
#DOCKER> root@pg_node1 $ service ssh start
#DOCKER> root@pg_node2 $ service ssh start
// docker로 설치해서 linux가 debian으로 동작하는데 redhat만 쓰다보니 ssh runlevel을 변경해서 부팅 시 start 되며 올라오게 하고 싶지만, 잘 되지 않음.
// update-rc.d 및 sysv-rc-conf 를 사용하면 된다고 하지만, 시도 결과 되지 않았음.
'PostgreSQL' 카테고리의 다른 글
[PostgreSQL] 복구 시 테이블에 AccessExclusiveLock (0) | 2021.03.15 |
---|---|
[PostgreSQL] PostgreSQL standby recovery script (0) | 2021.02.08 |
[PostgreSQL] PostgreSQL PGPOOL with failover (0) | 2021.02.08 |
[PostgreSQL] PostgreSQL Parameter (0) | 2021.01.11 |