// code/schema-compatibility.example
// Registry: BACKWARD — new consumer reads old + new messages
// FORWARD — old consumer reads new messages (additive only)
// FULL — both directions
DDL
영향
ADD COLUMN nullable
보통backwardOK
DROP COLUMN
forward주의 · breaking
RENAME
breaking — 새topic·마이그레이션
TYPE change
connector재스냅샷·수동조정
ALTER ADD COLUMN → schema v2 registered → consumer with v2 reader OK (BACKWARD)
ALTER DROP COLUMN → old messages still have field → plan deprecation window
운영
Schema history topic
보존무기한 — 삭제금지
Consumerupgrade
새스키마먼저배포 (backward)
Breaking DDL
blue/greentable · dualwrite기간
Architecture이벤트계약 — 서비스API; 여기서는 DBDDL → Avro진화
3. Ordering과 exactly-once
DBcommit순 ≈ LSN순 — 단일테이블단일partitiontopic내.
보장
범위
현실
DB commit order
source테이블stream
LSN단조
Kafka partition
key동일 → 순서
hash설계
At-least-once
Connect기본
중복가능
EOS
Kafkatransaction
broker내부 — sink별개
Debezium → Kafka (at-least-once default)
Consumer → Elasticsearch (no EOS unless idempotent upsert by _id)
exactly-once 착각
실제
"Kafka EOS 켰다"
producer·streams범위
"한 번만 처리"
sink멱등필수 (20편)
"전역 순서"
불가 — partitionkey
# code/idempotent-sink.example — DB primary key as document id
def index_product(change: dict):
doc_id = change["after"]["id"]
op = change["op"]
if op == "d":
es.delete(index="products", id=doc_id, ignore=[404])
else:
es.index(index="products", id=doc_id, document=change["after"])
# code/dlq-replay.example
# 1. Fix consumer / schema
# 2. Replay DLQ messages to target topic with same key (preserve order)
for msg in dlq_consumer:
producer.send("shop.public.orders", key=msg.key, value=msg.value)
Connect 장애
대응
Connector FAILED
로그 · slot활성여부
Deserialization
schemahistory · registry버전
Slotinactive
재시작 — offset이어읽기
Offsetreset실수
snapshot재실행 — sink멱등필수
앞서멱등consumer — replay전제
수동skip — offsetcommit — 감사로그남기기
5. Snapshot과 incremental
snapshot.mode
initial
첫기동fullread + stream
never
stream만 — 기존데이터없음
when_needed
offset없을때만
no_data
스키마만
Phase 1: consistent snapshot (SELECT ... EXPORT_SNAPSHOT)
Phase 2: stream from LSN captured at snapshot start
→ no gap if connector coordinates correctly
주의
대형테이블
snapshot부하 — off-peak · signaltable
Replicafrom
읽기부하분리 (설정 시)
Resume
interrupt후이어읽기
6. 운영 런북
시나리오
조치
Slot lag증가
consumer lag · connector 상태 · downsink
Disk압박
lag해소전 slot 삭제금지 — WAL폭주
DDL배포
registrycompatibility확인 · consumer순서
Connector업그레이드
staging검증 · offset백업
재동기화
새connector + snapshot · sinktruncate·멱등
-- code/slot-monitor.sql
SELECT slot_name,
active,
confirmed_flush_lsn,
pg_size_pretty(pg_wal_lsn_diff(pg_current_wal_lsn(), confirmed_flush_lsn)) AS lag_bytes
FROM pg_replication_slots;
-- emergency: only after stopping connector and accepting data re-sync
-- SELECT pg_drop_replication_slot('debezium_orders');
해당 내용은 Database System Concepts, 7/E (Avraham Silberschatz, Henry F. Korth, S. Sudarshan), Designing Data-Intensive Applications (Martin Kleppmann), Debezium · Confluent Schema Registry 공식 문서 의 내용을 기반으로 합니다.