Postgresql 이중화하기

망7H·2021년 4월 3일
4

DB 이중화란 '기준이 되는 데이터베이스(Master)의 변경된 데이터를 물리적으로 떨어진 각각의 데이터베이스(Slave)에 동일하게 유지하여 관리하는 것'이라고 정의할 수 있습니다.
개인적인 프로젝트를 할 때는 이중화를 할 필요성을 그다지 느끼지 못했었는데, 실서비스에서는 데이터의 유실을 방지하거나 무중단 서비스를 위해서는 이중화가 필수입니다.

  • 이중화 시, 데이터의 복제 과정
    ① Master로 사용할려는 DB가 설치된 서버(이하 Master)의 WAL(Write Ahead Log)Master에서 발생하는 모든 작업을 로그로 기록합니다.
    이전 글에서 세팅한 AWS EC2 인스턴스 기준으로는 /var/lib/pgsql/data/pg_xlog 경로에 WAL 로그가 쌓이게 됩니다.
    (MySQL 이중화 진화기을 보면 MySQL Masterbinary log가 Postgresql MasterWAL라고 할 수 있습니다.)
    ② 이 로그를 Slave로 사용하려는 DB가 설치된 서버(이하 Slave)로 전달합니다.
    Slave에서 받은 로그를 재실행함으로써 Master와 데이터를 동일하게 유지할 수 있습니다.

이렇게 데이터의 복제 과정을 구현하는 복제 방식으로는 2가지가 있습니다.
Log-shippingStreaming이 있습니다.

  • 복제 방식
    - Log-shipping
    MasterWAL 파일 자체를 전송하는 방식으로 Async 방식만 가능합니다.
    Async 방식은 SlaveWAL 파일이 제대로 복제되었다는 응답을 받지 않기 때문에 속도는 빠르지만 데이터의 유실 가능성이 있습니다.
    또한, Log-shipping 방식은 MasterWAL 파일이 크기를 다 채워야만 Slave로 전송이 일어나기 때문에 전송에 필요한 WAL 파일의 크기를 채우는 동안은 MasterSlave는 동일하지 않은 데이터를 가지고 있습니다. 이때, Master에 장애가 발생하게 되면 데이터의 유실이 발생합니다.

    - Streaming (Postgresql 9.x ↑에서 사용가능)
    MasterWAL의 내용을 전송하는 방식으로 Async 방식과 Sync 방식 모두 가능합니다.
    Sync 방식은 Slave에 전달한 내용이 제대로 복제되었다는 응답을 받기 때문에 속도는 느리지만 데이터의 유실 가능성이 낮습니다.
    하지만, 다음과 같은 상황에서 데이터의 유실이 발생할 수 있습니다.
    ① 저장할 수 있는 WAL 파일의 최대 개수를 지정하는 postgresql.confwal_keep_segments 옵션의 값을 10으로 지정하였고.
    ② 갑자기 Slave에 긴 시간의 서버 장애가 발생하였다고 가정해보겠습니다.
    Master에는 장애가 발생하지 않았으므로 WAL를 지속적으로 쌓습니다.
    WAL 1(AAA), WAL 2(BBB), WAL 3(CCC)...
    Slave의 장애가 해결되지 않았는데 MasterWAL는 10번째 파일까지 쓰이고 나면 이후에는 가장 먼저 생성되었던 WAL 1(AAA)을 덮어쓰기 시작하고 덮어씌워진 WAL 1(KKK)에는 이전의 WAL 1(AAA)과는 다른 데이터를 기록하게 됩니다.
    ⑤ 이후 Slave의 장애가 해결되었고, Master로 부터 WAL의 내용을 전송이 재개되지만, 덮어씌워진 WAL 1에 의해 데이터(AAA)가 유실되었습니다.

    또한, Streaming 방식의 한가지 특징은 Master에서는 WAL Sender Process가 동작하며, Slave에서는 WAL Receiver Process가 동작합니다.

1. AWS EC2에 Postgresql 설치하기.

MasterSlave를 각각 사용해야 하므로 EC2 인스턴스를 2개 생성해주세요.
그리고 Master로 사용할 인스턴스와 Slave로 사용할 인스턴스에 각각 아래의 내용을 읽고 설치해주세요.

  • Master에 Postgresql 설치하기.

    AWS EC2에 Postgresql 설치하기
    이전에 작성한 글이 있으니 AWS EC2에 Postgresql을 설치하는 과정은 위 링크를 참고해주세요.
    위의 과정을 따라 Master만 먼저 세팅해주세요.
  • Slave에 Postgresl 설치하기.

    AWS EC2에 Postgresql 설치하기
    ※ 위 링크의 2-1) postgresql 설치 까지만 하시면 됩니다. 나중에 pg_basebackup 명령을 사용해서 Master의 설정 정보를 받아오고, 일부 수정하면서 세팅할거니까요.

2. 세팅순서

1) DB 동작시키기 - Master & Slave

먼저, 두 대의 DB를 모두 동작 시킨다. sudo service postgresql start

2) 관리자 비밀번호 초기화 - Master & Slave

3) OS의 postgres 계정 비밀번호 변경 - Master & Slave

4) 아카이브 디렉토리 생성 및 권한 추가 - Master & Slave

5) 복제 계정 생성 - Master

(이전글에서 생성한 testuser 유저는 권한이 없다...)

6) postgresql.conf 수정 - Master

vim /var/lib/pgsql/data/postgresql.conf
postgres.conf 설정 파일의 내용 중 아래의 내용처럼 각각 바꾸어 준다.

listen_addresses='*'
port = 5432
wal_level=hot_standby
wal_log_hint=on
archive_mode=on
archive_command='test ! -f /var/lib/pgsql/archive/%f && cp %p /var/lib/pgsql/archive/%f'
max_wal_senders=3
wal_keep_segments=64
hot_standby=on
logging_collector=on

7) pg_hba.conf 수정 - Master

추가하는 host의 ADDRESS에는 Slave의 public ip를 입력한다.
이제 Slave에서 해당 host로 접근할 수 있게 되었다.

8) Master 설정 정보 Slave로 복제 - Slave

위의 명령어들을 순차적으로 따라하면 Master의 data 폴더가 Slave에 정상적으로 복제된다.

9) postgresql.conf 수정 - Slave

Master에서 복제한 postgresql.conf 중에서 Slave에 맞게 수정해야 할 내용을 각각 바꾸어 준다.

listen_addresses='*'
port=5432
wal_level=hot_standby
wal_log_hints=on
#archive_mode=on
#archive_command='test ! -f /var/lib/pgsql/archive/%f && cp %p /var/lib/pgsql/archive/%f'
max_wal_senders=3
wal_keep_segments=64
hot_standby=on
logging_collector=on

10) recovery.conf 추가 - Slave

recovery.conf 파일의 내용은 아래와 같이 입력해준다.
여기까지 작업이 끝났다면, MasterSlave를 각각 재시작 시켜준다.
sudo service postgresql restart

3. 이중화 테스트

1. recovery mode 확인하기

SELECT pg_is_in_recovery(); 쿼리를 실행해보면 Master의 경우 f, Slave의 경우 t로 나오면 정상적으로 이중화 세팅이 된 것이다.

2. 테이블 생성, 데이터 입력, 데이터 확인

1) Master에서 테이블 생성 및 데이터 입력

CREATE TABLE t_replication (
  name	VARCHAR(20),
  age	INT
);
INSERT INTO t_replication VALUES('jwpark', 20);

2) Slave에서 데이터가 동기화 되었는지 확인

SELECT * FROM t_replication;

정상적으로 하나의 데이터가 노출되었다면, 이중화가 정상적으로 된 것이다.




Postgresql의 이중화를 해보는데 무척 오랜 시간이 걸렸다.
필자가 설치한 Postgresql의 버전과 참고했던 링크에서의 버전이 다름으로써 설정파일에 replication 옵션이 없다던지, 필자의 실수(오타 or 누락)로 인한 것도 시간을 몹시 많이 잡아먹었다.
위에서 사용한 여러 명령들에 대하여 설명은 계속해서 추가할 예정이다.
어떻게든 실습을 먼저 진행해서 완료하고, 해당 명령을 이해하는 편이 공부하기에는 무척 좋은것 같다.
아무튼 이중화가 완료된 DB를 보고 나니 무척 뿌듯하다.

해당 글 작성에 참고한 링크

https://browndwarf.tistory.com/4
https://jinisbonusbook.tistory.com/70
https://it-sunny-333.tistory.com/122
https://bingbingpa.github.io/database/postgresql-replication/
https://idchowto.com/?p=44332
https://devegoist.tistory.com/1

profile
망한 개발자의 개발 기록입니다. 저를 타산지석으로 삼으시고 공부하세요.

3개의 댓글

comment-user-thumbnail
2022년 10월 14일

글 잘봤습니다
마침 포스트그레스 이중화 업무가 내려왔는데 많은 도움이 되었습니다^^

1개의 답글
comment-user-thumbnail
2024년 8월 17일

진심으로 감사합니다. 몇 주 동안 실패했던 게 덕분에 해결되었습니다. 감사합니다.

ps. 2줄 오타가 있어요!
"wal_log_hint" -> "wal_log_hints"
"restor_command" -> "restore_command"

답글 달기