← 기술 목록으로

바이너리 로그 동기화 4.0 — 단순 리플레이를 CDC·멱등 UPSERT로 전환

mysqlbinlog 파이프로 파일을 통째 리플레이하던 고객사 동기화를, binlog 이벤트를 직접 파싱해 UPSERT로 변환·적용하는 Go 기반 CDC 구조로 재설계 — 재시도해도 깨지지 않는 동기화를 만든 작업

기간2025.09 제안 · 2026.01–04 설계·구현·배포
소속래브라도랩스(LabradorLabs)
역할Data Engineer · CDC 전환 제안 및 설계·구현
GoCDCMySQL Binary LogUPSERTSHA256state.yaml

0작업자의 메모

레거시 동기화의 단위는 binlog "파일"이었습니다. 파일 안의 이벤트 하나가 실패해도 파일 전체가 막히고, 어디까지 들어갔는지는 stderr 텍스트를 긁어 세는 수준이라 복구 위치를 특정할 수 없었습니다. 품질 개선 회의에서 CDC 구조 전환을 직접 제안한 이유입니다.

설계 원칙은 한 줄입니다 — 전달은 중복될 수 있어도, 적용은 멱등하게. INSERT/UPDATE를 UPSERT로 변환하면 같은 이벤트를 두 번 적용해도 결과가 같으니 재시도가 두렵지 않은 시스템이 됩니다. at-least-once 전달에 멱등 적용을 더해 사실상 exactly-once 의미론을 얻는, 분산 데이터 시스템의 정석 패턴입니다.

1배경

레거시(v2/v3) Updater는 mysqlbinlog 유틸리티를 파이프로 실행해 binlog를 타겟 DB에 그대로 밀어넣는 단순 리플레이였습니다. SQL을 제어할 수 없으니 중복 키 에러가 나면 수동 개입이 필요했고, DEFINER 절·Virtual Column처럼 고객사 환경에서 깨지는 구문도 거를 수 없었습니다.

Before

파일 단위 All-or-Nothing 리플레이 → 이벤트 하나의 실패가 파일 전체를 막음, 중복 적용 시 에러, 복구 위치 추적 불가

After

이벤트 단위 파싱·변환·적용 → 멱등 UPSERT로 재시도 안전, state.yaml 체크포인트로 실패 지점부터 정확히 재개

2한 일

A아키텍처 (데이터 흐름)

Source DB사내 main / source 인스턴스
binlog →
Download Server v4실시간 암호화 스트리밍 · Smart Polling
암호화 파일 →
Updater (Go)복호화 → 파싱 → UPSERT 변환
SQL 적용 →
고객사 Target DBon-premise

다운로드와 임포트를 별도 모드로 분리해 각자의 커서(next_index)로 진행하고, 임포트 실패 유형에 따라 파일 재다운로드(손상)와 임포트만 재시도(DB lock·일시 장애)를 구분해 복구합니다.

3임팩트

정합성 — 멱등 UPSERT + 이벤트 단위 제어로 중복·누락 없이 재시도 가능, 사실상 exactly-once 적용
자동 복구 — 체크포인트 롤백이 내장되어 파일 손상·임포트 실패가 사람 개입 없이 다음 주기에 스스로 복구
처리 속도 — binlog 파일당 SSD 평균 96초 → 39초(2.56배), HDD 최대 5배. 데이터가 클수록 격차 확대

4역할

2025년 9월 품질 개선 회의에서 Binlog Shipping의 파일 단위 한계를 제기하며 CDC 구조 전환을 제안했고, 2026년 1분기에 설계·구현을 맡아 4월 배포까지 진행했습니다. 비교 검토(Debezium·Maxwell·커스텀)부터 Go Updater의 파싱·변환·상태 관리 설계, SSD/HDD 환경별 v2 대비 성능 측정까지 문서로 남기며 작업했습니다.

같은 v4에서 진행한 AES-256-GCM 암호화 전환(동기화 ③), 동기화 상태를 지켜보는 Grafana 모니터링(동기화 ④)과 함께 Binlog shipping service 4.0을 구성. 수집/배포 DB 경계를 세운 ETL DB 영역 분리에서 출발한 동기화 구조 개선의 현재 지점.