레플리카에서 읽기‑쓰기 일관성: PostgreSQL WAIT FOR LSN 및 MongoDB 인과 일관성

발행: (2026년 2월 22일 오전 06:36 GMT+9)
13 분 소요
원문: Dev.to

Source: Dev.to

(위의 소스 링크 아래에 번역하고 싶은 본문을 제공해 주시면, 해당 내용을 한국어로 번역해 드리겠습니다.)

개요

고가용성과 확장성을 위해 설계된 데이터베이스에서는 보조 노드가 기본(primary)보다 뒤처질 수 있습니다. 일반적으로 내구성을 보장하면서 가용성을 유지하기 위해 노드들의 쿼럼이 동기식으로 업데이트되며, 나머지 대기 인스턴스는 부분 장애를 처리하기 위해 최종 일관성을 가집니다.

가용성과 성능의 균형을 맞추기 위해 동기 복제본은 내구성이 확보되고 복구 가능한 경우에만 쓰기를 확인합니다(아직 읽을 수 없더라도).

결과: 애플리케이션이 데이터를 쓰고 바로 다른 노드에 쿼리를 날리면, 여전히 오래된 데이터를 볼 수 있습니다.

예시 이상 현상

주(primary)에서 주문을 커밋한 뒤 보고 시스템에서 해당 주문을 조회하려고 하면, 읽기 복제본이 아직 쓰기를 적용하지 않아 주문이 보이지 않을 수 있습니다.

PostgreSQLMongoDB 모두 이 문제를 피할 수 있는 메커니즘을 제공하지만, 접근 방식은 서로 다릅니다.

기능PostgreSQL WAIT FOR LSNMongoDB Causal Consistency
시계 유형Log Sequence Number (LSN) – 64비트 WAL 위치Hybrid Logical Clock (HLC) 타임스탬프
작동 방식대기 중인 스탠바이가 목표 LSN에 도달할 때까지 차단 (쓰기, 플러시, 혹은 재생)읽기에 afterClusterTime을 붙이고, 드라이버가 operationTime을 추적
일반적인 사용 사례읽기‑쓰기 일관성을 유지하면서 비용이 많이 드는 읽기를 복제본에 오프로드기본(primary)든 보조(secondary)든 어느 복제본에서든 읽을 수 있는 세션
추가 왕복예 – 기본에서 LSN을 가져온 뒤 복제본에서 대기아니오 – 드라이버가 타임스탬프를 자동으로 처리
세분성LSN (트랜잭션당)클러스터 시간 (작업당)
가용성 영향복제본이 따라잡는 동안 지연 시간이 증가할 수 있음복제본이 따라잡을 때까지 읽기가 짧게 차단될 수 있음
구현 상태PostgreSQL 19(개발 중) 예정MongoDB 4.0+ (세션)에서 사용 가능

PostgreSQL: WAIT FOR LSN (PG 19 – 현재 개발 중)

PostgreSQL은 Write‑Ahead Log (WAL) 에 모든 변경 사항을 기록합니다. 각 WAL 레코드에는 Log Sequence Number (LSN) 이 있으며, 이는 보통 두 개의 16진수 절반으로 표시되는 64‑비트 위치예: 0/40002A0 (상위/하위 32 비트) 입니다.

스트리밍 복제는 WAL 레코드를 기본 서버에서 스탠바이 서버로 전송하고, 스탠바이는 다음을 수행합니다:

  1. Write – WAL 레코드를 디스크에 기록
  2. Flush – 영구 저장소에 플러시
  3. Replay – 데이터를 파일에 적용하여 읽기 작업에 보이게 함
위치의미
standby_write스탠바이에서 WAL이 디스크에 기록된 상태 (아직 플러시되지 않음)
standby_flush스탠바이에서 WAL이 영구 저장소에 플러시된 상태
standby_replay (기본)WAL이 데이터 파일에 재생되어 읽는 사람에게 보이는 상태
primary_flush기본 서버에서 WAL이 플러시된 상태 (synchronous_commit = off 일 때 유용)

PostgreSQL 19용 최근 커밋에서는 세션이 지정한 LSN에 도달할 때까지 차단할 수 있는 WAIT FOR LSN 명령을 추가했습니다.

일반적인 워크플로우

  1. 기본 서버에서 쓰기 및 커밋.
  2. 현재 WAL 삽입 LSN을 가져오기.
  3. 복제본에서 대기하여 해당 LSN에 도달했는지 확인.
-- 1. 기본 서버에서 트랜잭션 시작
BEGIN;

-- 2. 행 삽입
INSERT INTO orders VALUES (123, 'widget');

-- 3. 트랜잭션 커밋
COMMIT;

-- 4. 현재 WAL 삽입 LSN 가져오기
SELECT pg_current_wal_insert_lsn();

결과 (예시):

 pg_current_wal_insert_lsn
---------------------------
 0/18724C0
(1 row)

이제 복제본에서 해당 LSN이 재생될 때까지 읽기를 차단합니다:

-- 복제본에서
WAIT FOR LSN '0/18724C0'
  WITH (MODE 'standby_replay', TIMEOUT '2s');

복제본이 제한 시간 내에 요청된 LSN에 도달하면 명령이 반환되고, 그렇지 않으면 시간 초과 오류와 함께 중단됩니다.

사용 시점

  • 비싼 읽기 작업을 복제본에 오프로드하면서도 읽기‑쓰기 일관성을 보장하고 싶을 때.
  • 이벤트‑드리븐 / CQRS 아키텍처에서 LSN 자체를 하위 소비자를 위한 변경 마커로 사용할 때.

많은 워크로드에서는 기본 서버에서 직접 읽는 것이 더 간단하고 빠를 수 있습니다.

MongoDB: 인과 일관성

MongoDB는 oplog 타임스탬프하이브리드 논리 시계(Hybrid Logical Clock, HLC) 를 사용해 인과성을 추적합니다.

  • 레플리카 세트에서 기본(primary)에서 발생하는 각 쓰기는 local.oplog.rs에 항목을 생성합니다.
  • 각 항목은 물리적 시간과 논리 카운터를 결합한 HLC 타임스탬프를 가지고 있으며, 이는 단조 증가하는 클러스터 타임을 제공합니다.
  • 레플리카 세트 멤버는 타임스탬프 순서대로 oplog 항목을 적용합니다.

MongoDB는 동시 쓰기를 허용하기 때문에 “oplog 구멍”(oplog holes) 이 발생할 수 있습니다: 나중에 타임스탬프가 붙은 쓰기가 이전에 타임스탬프가 붙은 쓰기보다 먼저 커밋될 수 있습니다. 순진한 리더는 이전 작업을 건너뛸 수 있습니다.

MongoDB는 oplogReadTimestamp 라는, oplog에서 구멍이 없는 가장 높은 지점을 추적함으로써 이를 해결합니다. 세컨더리는 모든 이전 작업이 가시화될 때까지 이 지점을 넘어 읽는 것이 차단되어, 동시 커밋 상황에서도 인과 일관성을 보장합니다.

인과 일관성 강제

  • 드라이버는 세션 내 마지막 작업의 operationTime을 추적합니다.
  • causalConsistency: true 로 세션을 생성하면, 드라이버는 이후 읽기에서 자동으로 가장 높은 알려진 클러스터 타임과 동일한 afterClusterTime 을 포함합니다.
  • 서버는 자신의 클러스터 타임이 afterClusterTime 을 초과할 때까지 읽기를 차단합니다.

예시 (Node.js 드라이버)

// 인과 일관성 세션 시작
const session = client.startSession({ causalConsistency: true });

const coll = db.collection("orders");

// 이 세션에서 쓰기
await coll.insertOne({ id: 123, product: "widget" }, { session });

// 드라이버가 자동으로 afterClusterTime을 읽기 컨선에 주입
const order = await coll.findOne({ id: 123 }, { session });

읽기 선호도가 세컨더리와 프라이머리 모두에서 읽을 수 있도록 허용한다면, 이는 읽고 쓰기(read‑your‑writes) 동작을 보장합니다.

참고: 인과 일관성은 스냅샷 읽기에만 국한되지 않으며, 모든 읽기‑컨선 수준에 적용됩니다. 세션은 어떤 레플리카가 읽기를 제공하든, 이후 읽기가 이전 쓰기의 최소 효과를 관찰하도록 합니다.

결론

PostgreSQL과 MongoDB 모두 분산 환경에서 read‑your‑writes 의미를 달성하기 위한 메커니즘을 제공하지만 구현 방식은 다릅니다:

항목PostgreSQL WAIT FOR LSNMongoDB 인과 일관성
기본 좌표WAL 로그 시퀀스 번호 (LSN)하이브리드 논리 시계 (클러스터 시간)
클라이언트 참여 방식LSN을 명시적으로 가져온 뒤 복제본에서 WAIT FOR LSN을 실행인과 일관성 세션을 열고; 드라이버가 타임스탬프를 처리
일반적인 지연 영향추가 라운드 트립이 발생하고 복제본에서 대기할 수 있음읽기가 복제본이 따라잡을 때까지 잠시 차단될 수 있음
Primary와 복제본 읽기단순성을 위해 여전히 Primary에서 읽는 경우가 많음읽기는 안전하게 어느 복제본에서도 가능
사용 사례 초점순서를 유지하면서 무거운 읽기 작업을 오프로드모든 읽기에 대한 일반적인 세션 수준 일관성

애플리케이션의 일관성 요구사항, 지연 허용도 및 아키텍처 스타일에 가장 적합한 접근 방식을 선택하십시오.

WAL(LSN)에서 물리적 바이트 오프셋 vs. 하이브리드 논리 시계(HLC)

항목PostgreSQL (WAL)MongoDB (HLC)
메커니즘재생/쓰기/플러시 LSN에 도달할 때까지 차단afterClusterTime이 보일 때까지 차단
추적애플리케이션이 LSN을 캡처드라이버가 operationTime을 추적
세분성WAL 레코드 위치Oplog 타임스탬프
복제 모델물리적 스트리밍논리적 oplog 적용
홀 처리해당 없음 (직렬화된 WAL)oplogReadTimestamp
장애 조치 처리NO_THROW가 없으면 오류세션은 계속되며 복제 상태에 의해 제한됨

핵심 요점

  • PostgreSQL의 WAIT FOR LSN과 MongoDB의 인과 일관성은 읽기가 이전 쓰기를 관찰할 수 있도록 보장하지만, 서로 다른 계층에서 작동합니다:

    • PostgreSQL수동적인, WAL 수준 정밀도를 제공합니다.
    • MongoDB자동적인, 세션 수준 보장을 제공합니다.
  • 추가 조정 호출 없이 “읽은 내용이 바로 쓰여짐” 의미를 그대로 사용하고 싶다면, MongoDB의 세션 기반 모델이 강력한 선택입니다.

  • 일관성에 대한 지속적인 오해에도 불구하고, MongoDB는 수평 확장 가능한 시스템에서 강력한 일관성을 제공하면서 간단한 개발자 경험을 제공합니다.

0 조회
Back to Blog

관련 글

더 보기 »