본문으로 건너뛰기
4.4 동기/비동기 commit

4.4 동기/비동기 commit

PostgreSQL의 commit이 얼마나 안전해야 하는지는 synchronous_commit 파라미터로 조절합니다. WAL fsync를 commit 응답 전에 기다릴 것인가, 안 기다릴 것인가의 트레이드오프입니다. 클러스터 차원의 기본부터 트랜잭션별 오버라이드까지 제어가 세밀합니다.

값과 의미

commit 응답 시점
on (기본)로컬 WAL fsync 완료 후
local로컬 fsync 완료 후. 동기 복제 표준에서 standby 응답은 안 기다림
remote_write로컬 fsync + standby의 WAL receive (디스크 안 기다림)
remote_apply로컬 fsync + standby가 적용까지 완료
off로컬 WAL이 아직 메모리에 있을 때 응답 — fsync는 백그라운드에서

onoff의 차이가 가장 크고, local·remote_*는 복제 환경에서 의미가 있습니다.

synchronous_commit = on vs off

on (기본)

    sequenceDiagram
  participant Client
  participant Backend
  participant WAL
  Client->>Backend: COMMIT
  Backend->>WAL: WAL record + fsync 요청
  WAL-->>Backend: fsync OK
  Backend-->>Client: COMMIT (응답)
  
  • 디스크에 들어간 commit만 “성공"으로 인정
  • crash 시 직전 commit은 안전하게 살아남음
  • commit latency = WAL fsync 비용

off

    sequenceDiagram
  participant Client
  participant Backend
  participant WALMem as WAL buffer
  participant WALDisk as pg_wal
  Client->>Backend: COMMIT
  Backend->>WALMem: WAL record (메모리만)
  Backend-->>Client: COMMIT (즉시 응답)
  Note over WALMem,WALDisk: 다음 walwriter cycle에서<br/>일괄 fsync (기본 200ms 내외)
  
  • commit이 매우 빠름 (fsync 대기 없음)
  • crash 시 마지막 200ms 정도의 commit 손실 가능
  • 단, 데이터베이스 일관성은 깨지지 않음 — “이미 완료됐다고 말한 트랜잭션이 사라질 뿐”

사고 모델

사고onoff
PostgreSQL backend crash응답한 commit 모두 살아남음응답한 commit 일부 손실
호스트 power off / kernel panic응답한 commit 모두 살아남음응답한 commit 일부 손실
디스크 손상 (storage 측)data_checksums + backup으로 복구같음

일관성(constraint·FK·serializability)은 off에서도 깨지지 않습니다. 다만 클라이언트가 “성공"으로 보고받은 트랜잭션이 crash 후 없어질 수 있다는 점이 다릅니다.

트랜잭션 단위 오버라이드

전체를 on으로 두되, 로그성 데이터처럼 손실 허용 가능한 트랜잭션만 off로 풀 수 있습니다.

-- 한 트랜잭션만 비동기 commit
BEGIN;
SET LOCAL synchronous_commit = off;
INSERT INTO event_log(...) VALUES (...);
COMMIT;   -- 빠르게 응답

또는 세션 단위:

SET synchronous_commit = off;
-- 이 세션의 모든 commit이 비동기

이 패턴이 운영의 정석입니다. 민감한 데이터는 안전, 손실 허용 가능한 데이터만 빠르게.

복제 환경의 local / remote_*

synchronous_standby_names 파라미터로 동기 복제 대상을 정한 경우, 다음 의미가 추가됩니다.

의미 (동기 복제 활성 시)
localprimary의 디스크 fsync만 기다림. standby는 무시
onprimary fsync + 동기 standby의 flush까지
remote_writeprimary fsync + 동기 standby의 receive까지 (디스크 안 기다림)
remote_applyprimary fsync + 동기 standby가 WAL을 적용해 query에서도 보일 때까지

운영 트레이드오프:

    flowchart LR
  L["local<br/>가장 빠름"] --> O["on<br/>표준"] --> RW["remote_write"] --> RA["remote_apply<br/>가장 강함, 느림"]
  classDef fast fill:#d1fae5,stroke:#047857,color:#064e3b
  classDef mid fill:#fef3c7,stroke:#b45309,color:#78350f
  classDef strong fill:#fed7aa,stroke:#c2410c,color:#7c2d12
  class L fast
  class O mid
  class RW,RA strong
  

대부분 동기 복제는 on 또는 remote_write로 운영합니다. remote_apply는 복제 지연 없이 standby에서 같은 결과를 봐야 하는 매우 엄격한 시나리오에서만.

관련 fsync 옵션

파라미터기본의미
fsyncon마스터 스위치. off는 절대 금지 — 데이터 손상 가능
synchronous_commiton위 표
wal_sync_methodOS별 자동fdatasync/fsync/open_datasync/open_sync 등. 보통 기본값으로 충분
commit_delay0μs. 여러 commit을 묶어 한 번에 fsync (group commit). 매우 높은 TPS에서만 의미
commit_siblings5commit_delay가 작동할 최소 동시 트랜잭션 수
fsync = off는 어떤 상황에서도 운영 금지. 약간의 성능 이득이 있지만 power-off 시 클러스터 자체가 깨질 수 있습니다. “검증 환경이라 잠깐만” 같은 사용도 사고로 이어진 사례가 많습니다.

TPS 영향 — 간단한 수치 감

synchronous_commit = on 환경에서 commit latency는 보통 storage의 fsync 지연에 좌우됩니다.

스토리지대략적인 fsync 지연
로컬 NVMe SSD50200 μs
데이터센터 SATA SSD200500 μs
네트워크 SSD (EBS gp3)5002000 μs
HDD510 ms

OLTP TPS는 single-thread commit 기준 1 / fsync_latency 가까이로 묶입니다. 여러 backend가 동시에 commit해도 WAL fsync는 직렬화되는 경우가 많아서 같은 지연이 모두에게 영향.

synchronous_commit = off로 풀면 이 직렬화가 사라져 TPS가 수배~수십 배 증가 가능합니다. 단, 위에서 본 손실 위험과 짝입니다.

진단

-- commit 지연 추적
SELECT mean_exec_time, calls, query
  FROM pg_stat_statements
 WHERE query ILIKE 'commit%'
 ORDER BY mean_exec_time DESC
 LIMIT 5;

-- WAL fsync 통계 (PG 14+)
SELECT * FROM pg_stat_wal;

pg_stat_walwal_sync_time / wal_sync로 평균 fsync 지연 추정 가능합니다.

흔한 안티패턴

패턴문제
synchronous_commit = off 클러스터 디폴트로결제·금융 등 손실이 절대 안 되는 트랜잭션도 비동기
fsync = off절대 금지 (위 callout)
commit_delay 무리하게 큼latency 증가가 처리량 증가보다 큼
동기 복제 대상이 1개뿐이고 standby가 자주 끊김primary commit이 영원히 멈춤
동기 복제는 quorum으로 운영: synchronous_standby_names = 'ANY 2 (s1, s2, s3)'로 3대 중 2대 응답을 받는 식이 표준입니다. 1대만 동기로 두면 그 1대가 죽을 때 primary가 멈춥니다.

정리

  • synchronous_commit = on(기본) = 안전, commit latency = WAL fsync 비용
  • off로 풀면 빠르지만 직전 ~200ms commit 손실 가능합니다. 일관성은 유지
  • 트랜잭션 단위 SET LOCAL로 부분 비동기 운영이 정석
  • 복제 환경에서는 local / on / remote_write / remote_apply 단계 선택
  • fsync = off는 어떤 경우에도 금지
  • 동기 복제 대상은 quorum(2 of 3 등)으로 정상 운영 보장

다음 절(4.5)에서는 PostgreSQL의 디스크 위치 분할에 쓰는 tablespace를 봅니다.