데이터베이스 기술/POSTGRESQL

[PostgreSQL]Streaming Replication의 이해 및 한계

(주)비트나인 2023. 9. 18. 18:50

블로그 글을 보시기 전에 2024년 비트나인의 첫 번째 월간 백서인

'오픈소스 DB 전성시대, PostgreSQL을 선택하는 이유'를 읽어보세요!

 

 지금 다운로드하기!


Replication이란?

Replication(복제)을 이야기하려면 High Availability(고가용성)에 대한 이해가 우선시 되어야 합니다. 고가용성이란 시스템 운용의 신뢰를 보장하는 것을 뜻하는데 여기서의 신뢰란 사용자가 시스템을 사용할 수 있는지의 여부(Availability)를 뜻합니다. 그 척도는 주로 Uptime¹ 또는 Downtime과 연관지어 다양한 표현² 으로 단계를 분류하기도 합니다.

그렇다면 Replication(복제)은 그 고가용성이란 추상적인 개념을 구현하기 위해 사용되는 구현 중 하나입니다. 실시간 데이터베이스 복제를 통해 HA 환경을 구성하여 장애를 대비하는 기법이며 mission-critical한 도메인을 보조하는 목적으로도 사용되는 기법입니다. 동일한 데이터베이스를 두 개 이상 가질 수 있기 때문에 데이터베이스 이중화 또는 다중화라고 표현하기도 합니다.

 

Replication 타입

Postgresql에서는 다양한 Replication 구성 전략을 제공합니다. 물리적 복제를 통해 구성하는 방법과 논리적 복제를 구성하는 방법으로 크게 나눌 수 있습니다. 복제를 구성하는 전략은 다양하지만 이 글에서는 물리적인 복제에 초점을 맞추어 기술하도록 하겠습니다.

 

물리적 복제 

물리적 복제를 구현하는 핵심은 Primary에서 수행하는 WAL³ 파일의 전달과, Standby에서 수행하는 WAL Replay입니다. WAL파일의 전달은 마스터-스탠바이 간 프로토콜⁴ 메세지 교환을 통해 이루어집니다. 

클러스터의 물리적인 복제이기 때문에 동일한 pg 버전 간의 복제만 가능합니다.

 

논리적 복제 

논리적 복제를 구현하는 핵심은 WAL의 변경사항에 대한 부분을 분리하는 (decoding) 부분입니다. 논리적인 변경 부분에 대한 적용사항이 전달되므로 pg버전과는 상관없으며 다른 데이터베이스인 경우까지도 복제가 가능합니다.

하지만 몇몇 제한사항ⁿ이 있는데, 그 중 대표적인 것은 스키마와 DDL커맨드가 복제되지 않는다는 점입니다. 물리적 복제와 가장 다른 차이가 이 부분입니다.

publish-subscriber의 형태로서 n:n의 구조를 가질 수 있는 부분 또한 물리적 복제와의 큰 차이점입니다.

 



1.사용자가 시스템을 사용 가능한 시간. 반대는 Downtime

2. https://en.wikipedia.org/wiki/High_availability#Percentage_calculation

 

High availability - Wikipedia

From Wikipedia, the free encyclopedia Systems with high up-time, a.k.a. "always on" "Always-on" redirects here. For the software restriction, see Always-on DRM. High availability (HA) is a characteristic of a system that aims to ensure an agreed level of o

en.wikipedia.org

3. Write Ahead Log의 앞글자를 딴 줄임말. 변경사항에 대한 내용을 실행 전에 미리 로그에 쓴 파일

4. https://www.postgresql.org/docs/current/protocol-replication.html

 

55.4. Streaming Replication Protocol

55.4. Streaming Replication Protocol To initiate streaming replication, the frontend sends the replication parameter in the startup message. A Boolean value …

www.postgresql.org

n. https://www.postgresql.org/docs/current/logical-replication-restrictions.html

 

31.6. Restrictions

31.6. Restrictions Logical replication currently has the following restrictions or missing functionality. These might be addressed in future releases. The database …

www.postgresql.org


 

 

SR 프로토콜 메시지 교환(1)

실제 XLOG 데이터를 전송하기 이전까지의 메시지 교환에 대해 설명합니다. F는 프런트엔드 메시지, B는 백엔드 메시지 ¹, SR은 physical replication walsender mode에서 처리할 수 있는 쿼리 ² 의미합니다. 이 부분까지의 메시지 교환이 완료되면 이후 primary와 standby모두 무한루프로 진입하여 XLOG 데이터의 전송 등의 명령어를 수행합니다.

  1. 복제를 요청하려는 클라이언트(Standby)에서 StartupMessage를 통해 서버(Master)와의 연결을 수립합니다. 이 과정에서 replication 파라미터 값을 true, on, yes, 1의 값으로 할당하여 서버를 walsender모드로 활성화시킵니다. 이 경우, 일반 쿼리 이외에 Streaming Replicaiton 전용 명령어의 처리가 가능한 연결이 수립됩니다.
  2. 클라이언트의 IDENTIFY_SYSTEM 쿼리 전송을 통해 서버의 정보를 확인합니다. 응답 : systemid, timeline, xlogpos, dbname.
  3. 클라이언트의 TIMELINE_HISTORY 쿼리 전송을 통해 서버의 타임라인 정보를 확인합니다. 응답 : filename, content.
  4. 클라이언트의 START_REPLICATION 쿼리 전송시 서버에서는 CopyBothResponse (B) 메시지를 통해 응답하며 서버의 COPY 모드가 활성화됩니다.
  5. 클라이언트의 status의 정보를 전송합니다. Hot standby feedback GUC옵션이 활성화되어있다면 뒤이어 피드백 메시지를 한번 더 전송합니다.
  6. 이후 실제 XLOG 데이터 전송이 시작되며 무한루프로 진입합니다.

1. https://www.postgresql.org/docs/current/protocol-message-formats.html

 

55.7. Message Formats

55.7. Message Formats This section describes the detailed format of each message. Each is marked to indicate that it can be …

www.postgresql.org

2.https://www.postgresql.org/docs/current/protocol-replication.html

 

55.4. Streaming Replication Protocol

55.4. Streaming Replication Protocol To initiate streaming replication, the frontend sends the replication parameter in the startup message. A Boolean value …

www.postgresql.org


 

SR 프로토콜 메시지 교환(2)

무한루프 진입 이후의 메세지 교환에 대해 설명합니다

  1. sender는 receiver로부터 받은 데이터를 확인 후, 다음 전송 완료 시점을 업데이트합니다.
  2. sender에서 실제 XLog 데이터를 메시지를 통해 전송(XLogData(B))합니다.
  3. receiver에선 받은 XLog데이터를 디스크에 write 요청 후 sender 쪽으로 스테이터스 메시지를  비동기로 전송합니다. 스테이터스 메시지의 write 시점이 업데이트되었습니다.
  4. receiver에서 이후 fsync 호출을 통해 쓰기 버퍼에 대한 flush작업을 수행합니다.
  5. receiver의 백그라운드에서 대기 중이었던 startupProcess를 깨우는 시그널을 발생시켜 WAL Replay를 수행하도록 합니다.
  6. sender 쪽으로 스테이터스 메시지를 한번 더 전송합니다. 스테이터스 메시지의 flush 시점이 업데이트되었습니다.
  7. receiver는 새로운 WAL 데이터가 오기까지 무한루프 내에서 기다립니다.

Replication 관련 설정 옵션

Replication과 연관된  설정값 목록 ¹ 중 Streaming Replication과 관련 있는 GUC 옵션 중 일부에 대해 서술합니다.

synchronous_commit

synchronous_commit 옵션은 Logical 또는 Physical Replication에 적용할 수 있는 옵션입니다. 기본이 비동기 모드인 복제 작업에 대해 standby들의 특정 단계까지의 수행을 기다리기  위해 생긴 옵션이며 remote_apply, on, remote_write, local, off  총 5단계의 설정이 가능합니다 주의사항으로는 synchronous_standby_names의 설정값을 반드시 같이 입력하여야 한다는 것입니다. 만약 synchronous_standby_names이 입력되지 않은 경우에는 synchronous_commit의 옵션이 켜져 있어도 replication의 상태를 기다리지 않습니다. 각 옵션에서 보장하는 범위에 대해 그림 ²과 함께 알아보겠습니다.

remote_apply

쿼리가 실행되는 master에서의 wal 데이터가 전달되어 standby에서의 wal 데이터가 replay를 완료하였을 때 master의 커밋을 완료합니다. 그림의 7번 작업이 완료되었을 때에 해당됩니다.

on

쿼리가 실행되는 master에서의 wal 데이터가 전달되어 standby에서의 영구 저장소(디스크)에 fsync(system call)가 완료되었을 때 master의 커밋을 완료합니다. 그림의 6번 작업이 완료되었을 때에 해당됩니다.

 


1. https://www.postgresql.org/docs/current/runtime-config-replication.html

 

20.6. Replication

20.6. Replication # 20.6.1. Sending Servers 20.6.2. Primary Server 20.6.3. Standby Servers 20.6.4. Subscribers These settings control the behavior of the …

www.postgresql.org

2. https://www.pgcon.org/2008/schedule/events/76.en.html

 

PGCon2008: Synchronous Log Shipping Replication

PGCon2008 - Final - we hope PGCon 2008 The PostgreSQL Conference Schedule Day Talks - first day (2008-05-22) Room B Start time 15:00 Duration 01:00 Info ID 76 Event type lecture Track Horizontal Scaling Language en Feedback Did you attend this event? Give

www.pgcon.org


remote_write

쿼리가 실행되는 master에서의 wal 데이터가 전달되어 standby에서의 영구 저장소(디스크)에 write(system call)가 완료되었을 때 master의 커밋을 완료합니다. 그림의 6번 작업을 진행 중일 때 실행하는 write(system call)가 완료되었을 때에 해당됩니다.

local

쿼리가 실행되는 master에서의 wal 데이터가 영구 저장소(디스크)에 fsync가 완료되었을 때 master의 커밋을 완료합니다. 그림의 3번 작업이 완료되었을 때에 해당됩니다.

off

synchronous_commit 옵션을 사용하지 않습니다. 별도의 대기 지점 없이 쿼리가 수행되는 즉시 master의 커밋을 완료합니다.

 

synchronous_standby_names

앞서 synchronous_commit 옵션을 사용할 때 반드시 이 옵션을 같이 설정해 주어야 의도한 대로의 작동이 이루어진다고 언급하였습니다. 이번엔 설정 방법과 그 이유를 알아보겠습니다.

 

설정 문법

  • priority-based 설정
  • quorum-based 설정

옵션이 강제되었던 이유

앞서 synchronous_commit 설정과 같이 synchronous_standby_names 옵션이 강제되었던 이유는 ‘복제 완료 판단'의 기준이 되기 때문입니다. 마스터 노드는 스탠바이 노드들에게 복제작업을 한 후 진행사항에 대한 정보를 응답받는데, 이 응답들에 대한 정보를 기준으로 대기 상태를 해제하기 때문입니다.

해당 옵션이 제공되지 않으면 대기 해제 기준이 없는 것이므로 싱크를 기다리지 않고 완료처리할 수밖에 없습니다. 따라서 해당 옵션을 반드시 제공해야 한다는 조건이 옵션 설명에 명시되어 있습니다.

 

 

리소스 매니저

pg에는 다양한 리소스 타입이 존재합니다. 그리고 리소스 타입과 연관 있는 기능 또한 함수포인터로 정의되어 있는데 바로 이 부분입니다. pg extension을 위한 기능이므로 GUC에  shared_preload_libraries 옵션에 정의해야 합니다.

WAL에 대한 커스텀이 가능합니다. redo시의 기능 등을 커스텀할 수 있고 Logical Replication 구성시의 decoding또한 커스텀 할 수 있도록 제공합니다.

 

pg에 등록되어 있는 빌트인 리소스 매니저들 목록. 다양한 리소스들에 대한 기능이 함수 포인터로 참조 및 선언되어 있습니다.

 

리소스 매니저의 id가 충돌하는 상황을 방지하기 위해 외부에 공개 시 별도의 위키 페이지 ¹에 등록하여 번호를 선점하도록 권유합니다. 또한 공개되지 않고 개발 중이거나 실험용의 id는 128로 고정되어 있습니다. 


1.  https://wiki.postgresql.org/wiki/CustomWALResourceManagers

 

CustomWALResourceManagers - PostgreSQL wiki

Custom WAL Resource Manager (rmgr) Extensions can register their own custom WAL resource managers to support custom redo, physical replication, and logical replication/decoding. Each resource manager needs to register using a unique ID (across all extensio

wiki.postgresql.org


SR의 한계

앞서 말했듯이 복제를 만드는 과정은 네트워크를 통해 보내는 WAL데이터가 핵심이라고 할 수 있습니다. 하지만 여기서 한계가 몇 가지 존재합니다.

중앙집중형 네트워크 구성

일반적인 SR 구성으로는 다중 standby 구성시에 네트워크 토폴로지가 자연스럽게 별 모양의 형태 (중앙집중형)으로 형성됩니다. 그에 따라 네트워크 부하가 master에 몰리게 됩니다. 이러한 현상의 의 대안으로는 Cascading Replication¹의 구성으로서 네트워크를 링 형태로 구성하는 것입니다.

Cascading Replication

데이터의 흐름을 upstream/downstream으로 구성하여 Master 노드에 집중되었던 네트워크 대역폭을 분산한 구성입니다. GUC 옵션값의 설정값 조정을 통해 구성 가능하며 일반 SR을 구성하는 것과 방법은 크게 다르지 않습니다.

 


1. https://www.postgresql.org/docs/current/warm-standby.html#CASCADING-REPLICATION

 

27.2. Log-Shipping Standby Servers

27.2. Log-Shipping Standby Servers # 27.2.1. Planning 27.2.2. Standby Server Operation 27.2.3. Preparing the Primary for Standby Servers 27.2.4. Setting Up …

www.postgresql.org


전송 도중에 끊긴다면?

만약 Master노드에서의 이상이 생겨 Replication에 WAL데이터가 제대로  전송되지 못한다면 어떻게 될까요? 간단한 실험을 통해 알아보도록 하겠습니다.

실험 환경

docker 가상 환경으로 SR 환경을 구성한 후 master에 500만 건의 데이터를 임의로 넣은 후, pgbench를 통해 무작위 업데이트를 진행하여, 변경사항이 있는 것만 추려내는 작업을 진행하였고, 작업 도중 postmaster 프로세스를 강제 종료하여, SR 복제가 진행되는 상태에서의 비정상 종료 시나리오를 만들었습니다.

실험 결과

Master노드에서 디스크에 저장되었지만 standby노드에 전달되지 못한 WAL 로그만큼의 데이터 손실이 발생한 것을 알 수 있습니다. synchronous_commit 옵션을 변경하면서까지 테스트를 해보았지만 네트워크를 통해 전송되지 못한 데이터만큼의 차이가 발생하였습니다. 

WAL 로그를 통해 복제를 구성하였기 때문에 WAL로그가 전달되지 못하면 원본과의 복제가 제대로 이루 어지 않는 결과를 볼 수 있습니다. 몇몇 pg커뮤니티의 사람들은 이 현상 ¹에 대해 질문한 흔적이 있으나 이것은 자연스러운 현상입니다.


1. https://postgrespro.com/list/thread-id/2460840

 

Thread: Urgent :: Postgresql streaming replication issue - sync mode

 

postgrespro.com


결론

Replication을 만드는 작업 중에서도 물리적인 복제를 만드는 Streaming Replication에 대하여 알아보았습니다. 그리고 실험을 통해 만약 WAL로그가 전송되지 못한다면 복제되지 못한 트랜잭션만큼의 손실이 발생하는 것 또한 알 수 있었습니다. 하지만 이것은 어찌 보면 당연한 게, 복제를 만드는 것은 싱크와는 별개의 문제이기 때문입니다. 그럼에도 불구하고 복제를 구성하는 여러 방법 중 하나인 SR은 많은 제약을 해결해 주기 때문에 널리 쓰이고 있습니다.

 

글: 서광원 선임 ( 비트나인 R&D Lead팀 )