Computer >> 컴퓨터 >  >> 프로그래밍 >> 데이터베이스

PostgreSQL 복제 완벽 가이드: 스트리밍 복제 개념부터 설정까지

복제(Replication)는 한 데이터베이스 서버인 소스(source)에서 다른 서버인 레플리카(replica)로 데이터를 복사하는 기술입니다. 복제는 데이터베이스의 강력한 기능으로, 고가용성(High Availability)을 제공하고 재해 복구(Disaster Recovery)를 지원합니다.

개요

또한 레플리카 서버를 테스트나 리포팅 용도로 활용하면 운영 환경의 OLTP(Online Transactional Processing) 데이터베이스 부하를 줄일 수 있습니다. 이 글에서는 PostgreSQL®의 다양한 복제 유형을 살펴보고, PostgreSQL 데이터베이스의 스트리밍 복제를 구현하는 데 필요한 단계를 자세히 안내합니다.

복제 상세

이제 PostgreSQL의 복제 모드와 모델, 복제 유형을 이해하고, WAL(Write-Ahead Logging)에 대해 알아보겠습니다.

비동기식과 동기식 모드

다음은 PostgreSQL 복제 모드를 보여주는 다이어그램입니다.

PostgreSQL 복제 완벽 가이드: 스트리밍 복제 개념부터 설정까지

비동기식(asynchronous) 복제에서는 소스 서버가 레플리카 서버로부터 트랜잭션 완료 확인 응답을 기다릴 필요가 없습니다. 복제 트랜잭션은 레플리카 서버에 대기열로 쌓이며, 처리가 완료될 때까지 두 서버는 지정된 시간 동안 동기화되지 않은 상태로 있을 수 있습니다.

동기식(synchronous) 모드 복제에서는 소스 서버가 각 복제 트랜잭션이 완료되었다는 확인 응답을 레플리카 서버(또는 여러 서버)로부터 받은 후에야 다음 작업을 진행합니다. 따라서 소스 서버와 레플리카 서버 모두 항상 사용 가능한 상태여야 합니다. 레플리카로부터 트랜잭션 실패 메시지를 수신하면 소스 서버는 해당 트랜잭션을 롤백합니다. 이 모드에서는 소스와 레플리카 서버가 항상 동기화 상태를 유지합니다. 단점은 레플리카 서버가 다운되거나 트랜잭션을 완료하지 못할 경우 소스 서버가 멈춤(hung) 상태에 빠질 수 있다는 점입니다.

단일 소스 및 다중 소스 복제 모델

단일 소스(Single-source) 복제에서는 하나의 소스 서버와 하나 이상의 레플리카 서버가 존재합니다. 소스 서버는 모든 레플리카에게 복제 트랜잭션을 전송합니다.

레플리카 서버는 오직 소스 서버로부터만 변경 사항을 받아들일 수 있습니다. 만약 소스가 아닌 다른 서버로부터 변경 사항을 받더라도, 레플리카는 그 트랜잭션을 소스로 다시 복제하지 않습니다.

다중 소스(Multi-source) 복제에서는 두 개 이상의 소스 서버가 존재합니다. 한 소스 데이터베이스에서 테이블 행이 변경되면, 해당 소스 서버는 다른 소스 서버들의 대응되는 테이블 행에 변경 사항을 복제합니다. 이 모델이 성공하려면 중복 기본 키(primary key) 등의 문제를 방지하기 위해 충돌 해결(conflict resolution) 방식을 도입해야 합니다.

복제 유형

복제에는 세 가지 유형이 있습니다.

  • 스트리밍 복제(Streaming Replication): PostgreSQL 버전 9 이상에서 제공되는 복제 방식입니다. 레플리카는 SELECT 쿼리만 실행할 수 있습니다. 이 방식의 필수 요건은 소스와 레플리카 데이터베이스가 동일한 메이저 버전이어야 한다는 것입니다.
  • 캐스케이딩 복제(Cascading Replication): PostgreSQL 9.2에서 도입된 이 방식은 소스 서버에서 직접 복제하는 대신 스탠바이(standby) 서버로부터 복제할 수 있게 해줍니다. 이를 통해 소스 서버의 부하를 줄일 수 있습니다.
  • 논리적 복제(Logical Replication): 선택한 데이터 세트나 데이터베이스 객체만 복제하거나, 서로 다른 메이저 버전의 PostgreSQL 간에 복제할 때 사용할 수 있습니다. 논리적 복제에서는 스탠바이 서버를 쓰기 용도로 사용할 수 있지만 몇 가지 제한이 있습니다. TRUNCATE, 대형 객체(lob, blob, clob 등), 시퀀스(sequence), 스키마, DDL은 복제할 수 없습니다.

WAL(Write-Ahead Logging)

스트리밍 복제를 시작하기 전에 WAL(Write-Ahead Logging)과 그 작동 방식을 이해해야 합니다.

PostgreSQL에서는 시스템이 데이터베이스에 대한 변경 사항을 데이터 파일에 저장하기 전에 먼저 로그 파일에 기록하며, 이러한 변경 기록을 WAL 레코드라고 합니다. 모든 WAL 레코드에는 LSN(Log Sequence Number)이라는 고유 번호가 부여됩니다.

PostgreSQL의 스트리밍 복제에서는 레플리카 데이터베이스 서버가 WAL 파일을 사용하여 소스 데이터베이스 서버의 변경 사항을 복제합니다.

PostgreSQL 데이터베이스의 스트리밍 복제에서 중요한 역할을 하는 세 가지 필수 프로세스는 다음과 같습니다.

  • WAL sender
  • WAL receiver
  • Startup

WAL sender 프로세스는 소스 서버에서 실행되고, WAL receiver와 startup 프로세스는 레플리카 서버에서 실행됩니다. 복제를 시작하면 다음과 같은 순서로 이벤트가 발생합니다.

  1. WAL receiver 프로세스가 레플리카가 재생(replay)한 WAL 데이터의 LSN을 마스터에 전달합니다.
  2. 소스의 WAL sender 프로세스는 WAL receiver가 전달한 최신 LSN에 도달할 때까지 WAL 데이터를 레플리카로 전송합니다.
  3. 그런 다음 WAL receiver는 WAL sender가 보낸 WAL 데이터를 WAL 세그먼트에 기록합니다.
  4. 레플리카의 startup 프로세스가 WAL 세그먼트에 기록된 데이터를 재생합니다.
  5. 마지막으로 스트리밍 복제가 시작됩니다.

실습: 스트리밍 복제 구성

다음은 PostgreSQL에서 소스 서버와 하나의 레플리카 간에 스트리밍 복제를 설정하는 단계입니다.

1단계: 사전 준비

먼저 소스 서버와 레플리카 서버 모두에 패스워드 없는 SSH 인증이 구성되어 있는지 확인해야 합니다. 구성되어 있지 않다면 ssh-keygen을 사용하여 설정합니다.

패스워드 없는 SSH 구성 방법은 https://linuxize.com/post/how-to-setup-passwordless-ssh-login/ 을 참고하세요.

소스 노드: 192.168.24.28
레플리카 노드: 192.168.24.29
소스와 레플리카 모두 사용자명은 `postgres`

2단계: 방화벽 중지

두 서버에서 다음 명령을 실행하여 방화벽을 중지합니다.

$ sudo systemctl stop firewalld
$ sudo systemctl disable firewalld

3단계: 소스 서버 설정

  1. 소스 서버에서 데이터 디렉터리로 이동합니다.

    cd /var/lib/pgsql/11/data
    
  2. postgresql.conf 파일을 편집하고 다음과 같이 변경합니다.

    archive_mode = on
    archive_command = 'cp %p /var/lib/pgsql/archive/%f'
    max_wall_senders = 5
    wal_keep_segment = 32
    wal_level = replica
    listen_addresses = '*'
    
  3. pg_hba.conf 파일에 레플리카 서버 IP 주소 항목을 추가합니다.

    host    postgres         postgres         (ip_address)192.168.24.29/32 trust
    host    replication      postgres         (ip_address)192.168.24.29/32 trust
    
  4. pg_hba.conf 파일을 변경할 때마다 서비스를 리로드합니다.

    $ /usr/local/pgsql_11/bin/pg_ctl -D /var/lib/pgsql/11/ reload
    
  5. 아카이브 디렉터리 /var/lib/pgsql/archive/가 없다면 생성합니다.

  6. 변경 사항이 적용되도록 서버를 재시작합니다.

4단계: 레플리카 서버 베이스 백업

레플리카 서버에서 다음 작업을 수행합니다.

  1. 데이터 디렉터리로 이동하여 서비스를 중지합니다.

    $ /usr/pgsql-11/bin/pg_ctl -D /var/lib/pgsql/11/data/ stop
    
  2. 레플리카의 데이터 디렉터리 내용을 모두 삭제하고, 다음 명령으로 소스에 연결되는지 확인합니다.

    $ /usr/pgsql-11/bin/psql -h 192.168.24.28
    
  3. 연결이 정상이라면 레플리카에서 베이스 백업을 시작합니다.

    $ cd /var/lib/pgsql/11/data
    $ /usr/pgsql-11/bin/pg_basebackup -D /var/lib/pgsql/11/data/ -X fetch -h 192.168.24.28 -R -P
    

이 명령들은 소스 데이터베이스의 데이터 디렉터리에 있는 모든 데이터를 레플리카 데이터 디렉터리로 복사하고 recovery.conf 파일을 생성합니다.

5단계: recovery.conf 확인 및 수정

베이스 백업이 완료되면 recovery.conf 파일을 확인해야 합니다. 데이터 디렉터리에 recovery.conf 파일이 있는 서버는 레플리카 서버이며, 소스 서버 정보를 포함하고 있습니다. 다음과 같이 수정합니다.

Standby_mode = 'on'
Primary_conninfo = 'user=postgres host=192.168.24.28 port=5432'

파일은 아래와 같은 형태여야 합니다.

$ vi recovery.conf
Standby_mode = 'on'
Primary_conninfo = 'user=postgres passfile=''/home/postgres/.pgpass'' host=192.168.24.28 port=5432 sslmode=disable sslcompression=0 target_session_attrs=any'

6단계: 서버 시작 및 검증

이제 서버를 시작하고 변경 사항을 검증합니다.

  1. 소스 서버에 로그인합니다.

    /usr/local/pgsql_11/bin/psql
    Postgres=#
    
    Postgres=# Select * from pg_stat_replication;
    
    -[ RECORD 1 ]----+------------------------------
    pid              | 1934
    usesysid         | 26712
    usename          | postgres
    application_name | walreceiver
    client_addr      | 192.168.24.29
    client_hostname  |
    client_port      | 52143
    backend_start    | 2020-11-07 11:30:31.035614-05
    backend_xmin     |
    state            | streaming
    sent_lsn         | 0/50000E34
    write_lsn        | 0/50000E34
    flush_lsn        | 0/50000E34
    replay_lsn       | 0/50000E34
    write_lag        |
    flush_lag        |
    replay_lag       |
    sync_priority    | 0
    sync_state       | async
    
  2. 레플리카 서버에 로그인합니다.

    /usr/local/pgsql_11/bin/psql
    Postgres=#
    
    Postgres=# Select * from pg_is_in_recovery();
    Pg_is_in_recovery
    ----------------------------------
    t
    
  3. 소스 서버에서 OS 레벨 명령으로 확인합니다.

    $ ps -ef|grep sender
    
    postgres  1934
    1718  0 11:31 ?        00:00:00 postgres: wal sender process replicator 192.168.24.29(52143) streaming 0/50000E34
    
  4. 레플리카 서버에서 OS 레벨 명령으로 확인합니다.

    $ ps -ef|grep receiver
    
    postgres  1358
    1748  0 11:31 ?        00:00:04 postgres: wal receiver process   streaming 0/50000E34
    

    sender와 receiver 트랜잭션이 동일해야 하며, 레플리카는 항상 읽기 전용(read-only) 모드로 유지됩니다.

  5. (선택 사항) 기본적으로 복제는 비동기식 모드로 동작합니다. 동기식 복제로 전환하려면 소스 서버의 postgresql.conf 파일에 다음 내용을 추가합니다.

    synchronous_standby_names = '*'
    

    그런 다음 서비스를 재시작합니다.

    $ /usr/local/pgsql-11/bin/pg_ctl -D /var/lib/pgsql/11/ restart
    

결론

이 글에서는 PostgreSQL의 복제 유형과 스트리밍 복제를 설정하는 단계를 설명했습니다. 스트리밍 복제는 특히 분석(analytics) 업무에서 읽기 전용 레플리카를 제공하여 기본(primary) 서버의 부하를 덜어주는 용도로 널리 사용됩니다.

또한 고가용성 환경이 필요하거나, 기본 서버에 장애가 발생했을 때 핫 스탠바이(hot standby) 서버로 페일오버(failover)해야 하는 경우에도 매우 유용합니다.

데이터 서비스에 대해 더 자세히 알아보세요.

피드백 탭을 통해 의견을 남기거나 질문할 수 있습니다. 언제든지 저희와 대화를 시작해 주세요.