DBAtlas · 데이터베이스 운영 아틀라스

복제 지연 / 중지

standby/replica가 primary보다 뒤처지거나 복제가 완전히 멈췄다. 이 트리는 지연 유형(증가, 일정, 중지)을 단계적으로 좁혀 apply 오류, 단일 스레드 병목, recovery conflict, 손상 같은 근본 원인에 도달한다.

지연이 어떻게 움직이는가?

먼저 상황을 측정한다. replica 스트림과 지연 지표를 본다: 지연이 시간에 따라 증가하는가, 일정 수준에 머무는가, 아니면 apply가 완전히 멈췄는가? 이에 따라 조사가 세 가지 주요 분기로 나뉜다.

SELECT client_addr, state, write_lag, flush_lag, replay_lag,
       pg_wal_lsn_diff(sent_lsn, replay_lsn) AS bytes_behind
FROM pg_stat_replication;
  • apply가 완전히 멈춤 / 오류가 있음
  • 지연이 계속 증가함 (따라잡지 못함)
  • 지연은 일정하지만 긴 쿼리가 의심됨
  • 크게 뒤처짐 / 불일치로 보임

apply 오류 메시지는 무엇인가?

복제가 멈췄다면 보통 적용 중인 이벤트에 오류가 있다. 오류 메시지를 본다: 대상에 행/테이블이 없는가, primary key 충돌인가, 연결/네트워크 끊김인가?

SHOW REPLICA STATUS\G  -- Last_Error, Last_SQL_Error, Replica_IO_Running, Replica_SQL_Running
  • 충돌/누락된 행 또는 테이블 오류
  • 네트워크/연결 끊김, IO 스레드 중지

왜 따라잡지 못하는가?

지연이 계속 증가하면 replica가 primary의 쓰기 속도를 따라가지 못하는 것이다. 단일 스레드 apply가 병목인가, replica의 디스크/IO가 느린가? apply worker 상태와 IO 대기를 본다.

SHOW REPLICA STATUS\G  -- Seconds_Behind_Source and apply thread state
SELECT * FROM performance_schema.replication_applier_status_by_worker;
  • 단일 스레드 apply + 많은 쓰기 부하
  • replica의 디스크/IO가 느리다

standby에 긴 쿼리가 있는가?

읽기 전용 standby에서 실행되는 긴 쿼리는 apply(recovery)를 막을 수 있다. PostgreSQL에서는 이렇게 recovery conflict가 발생한다. standby의 활성 쿼리와 conflict 카운터를 본다.

SELECT now()-query_start AS dur, pid, state, query
FROM pg_stat_activity WHERE state='active' ORDER BY query_start;
SELECT confl_snapshot, confl_lock, confl_bufferpin FROM pg_stat_database_conflicts WHERE datname=current_database();
  • 예, 긴 쿼리가 apply를 막고 있다
  • 아니요, 쿼리는 없지만 여전히 뒤처져 있다

근본 원인: apply 오류 (데이터 충돌)

replica가 적용할 수 없는 이벤트에 멈춰 있다: 대상에 없는 행, primary key 충돌, 또는 누락된 테이블. 맹목적으로 건너뛰지 말고 불일치의 원인을 해결한다.

근본 원인: 연결 / 네트워크 끊김

수신(IO/receiver) 스레드가 primary에 연결하지 못한다. 네트워크, 인증, 또는 누적/삭제된 로그 segment가 문제일 수 있다.

근본 원인: 단일 스레드 apply 병목

primary는 병렬로 쓰는데 replica는 변경을 단일 순서로 적용하여 따라가지 못한다. apply를 병렬화한다.

근본 원인: replica IO 병목

apply 스레드가 CPU가 아니라 디스크를 기다리고 있다. replica의 스토리지가 primary의 쓰기 속도를 따라가지 못한다.

근본 원인: standby recovery conflict

standby의 긴 읽기 전용 쿼리가 primary의 변경 적용을 막고 있다(vacuum/락 충돌). PostgreSQL은 apply를 지연하거나 쿼리를 취소하여 이를 해결한다.

근본 원인: replica가 너무 뒤처짐 / 손상 - 재구축

replica가 복구하기에 너무 뒤처졌거나, 필요한 로그가 삭제되었거나, 데이터가 불일치한다. 가장 안전한 방법은 새 백업에서 재구축하는 것이다.

DBAtlas에서 열기 →