1. Key (기본키, 후보키, 슈퍼키 등등...) 에 대해 설명해 주세요.
기본 답변
키는 테이블에서 튜플을 식별하거나 관계를 표현하기 위해 사용하는 속성 또는 속성 집합입니다.
슈퍼키는 행을 유일하게 식별할 수 있는 모든 속성 집합이고, 후보키는 슈퍼키 중 최소성을 만족하는 키입니다.
기본키는 후보키 중 대표로 선택한 키이고, 외래키는 다른 테이블의 기본키나 유니크 키를 참조해 테이블 간 관계와 참조 무결성을 유지합니다.
핵심 키워드
- Super Key
- Candidate Key
- Primary Key
- Foreign Key
- Unique Key
- Referential Integrity
꼬리질문
질문 기본키는 수정이 가능한가요?
답변 포인트 기술적으로는 가능할 수 있지만 권장되지 않습니다.
기본키는 식별자이므로 변경 시 참조 무결성, 외래키, 인덱스, 캐시 등에 영향이 큽니다.
질문 MySQL의 경우, 기본키를 설정하지 않아도 테이블이 만들어집니다. 어떻게 가능한 걸까요?
답변 포인트 InnoDB는 명시적 PK가 없으면 NOT NULL UNIQUE 인덱스를 클러스터링 키로 선택하고, 그것도 없으면 내부 hidden row id를 생성합니다.
질문 외래키 값은 NULL이 들어올 수 있나요?
답변 포인트 컬럼이 nullable이면 가능합니다.
NULL은 참조 대상이 없음을 의미하며, 외래키 검사는 일반적으로 NULL이 아닌 값에 대해 수행됩니다.
질문 어떤 칼럼에 UNIQUE가 붙으면 쿼리 성능은 어떻게 달라질까요?
답변 포인트 DB는 UNIQUE 제약을 위해 인덱스를 만들므로 해당 컬럼 조회 성능이 좋아질 수 있습니다.
대신 삽입/수정 시 중복 검사와 인덱스 유지 비용이 듭니다.
주의할 점
- 기본키와 인덱스는 관련 있지만 같은 개념은 아닙니다. 기본키는 제약이고, 인덱스는 접근 구조입니다.
2. RDB와 NoSQL의 차이에 대해 설명해 주세요.
기본 답변
RDB는 테이블, 행, 열, 스키마, SQL을 기반으로 데이터를 관리하고 관계와 트랜잭션을 강하게 지원합니다.
NoSQL은 문서, 키-값, 컬럼 패밀리, 그래프 등 다양한 모델을 사용하며 확장성, 유연한 스키마, 특정 접근 패턴에 최적화된 저장 방식을 제공합니다.
둘 중 무엇이 더 빠르다고 단정할 수 없고, 데이터 모델, 일관성 요구, 트랜잭션, 확장 방식, 쿼리 패턴을 기준으로 선택해야 합니다.
핵심 키워드
- RDBMS
- NoSQL
- Schema
- ACID
- CAP
- Scale-out
꼬리질문
질문 NoSQL의 강점과, 약점이 무엇인가요?
답변 포인트 강점은 유연한 스키마, 수평 확장, 특정 패턴에서 높은 성능입니다.
약점은 조인, 복잡한 트랜잭션, 강한 일관성, 표준화된 질의 측면에서 RDB보다 불리할 수 있다는 점입니다.
질문 RDB의 어떠한 특징 때문에 NoSQL에 비해 부하가 많이 걸릴 수 있을까요?
답변 포인트 정규화된 구조의 조인, 강한 트랜잭션, 제약 조건, 인덱스 유지, 수직 확장 중심 구조가 부하 요인이 될 수 있습니다.
질문 NoSQL을 활용한 경험이 있나요? 있다면 왜 RDB가 아니라 해당 DB를 선택했나요?
답변 포인트 예시는 Redis 캐시, MongoDB 문서 저장, Elasticsearch 검색처럼 접근 패턴이 명확한 경우를 들면 좋습니다.
단순히 빠르기 때문이 아니라 요구사항에 맞았다고 설명해야 합니다.
주의할 점
- NoSQL은 하나의 제품군이 아니라 다양한 데이터 모델의 묶음입니다.
3. 트랜잭션이 무엇이고, ACID 원칙에 대해 설명해 주세요.
기본 답변
트랜잭션은 데이터베이스에서 하나의 논리적 작업 단위를 의미합니다.
여러 SQL이 포함되어도 모두 성공하면 commit되고, 중간에 실패하면 rollback되어 작업 전체가 적용되지 않아야 합니다.
ACID는 원자성, 일관성, 격리성, 지속성을 의미합니다.
트랜잭션은 데이터 정합성을 지키기 위해 이 네 가지 성질을 보장하려고 합니다.
핵심 키워드
- Transaction
- Atomicity
- Consistency
- Isolation
- Durability
- Commit/Rollback
꼬리질문
질문 ACID 원칙 중, Durability를 DBMS는 어떻게 보장하나요?
답변 포인트 redo log, WAL 같은 로그를 디스크에 기록해 commit된 변경이 장애 후에도 복구될 수 있게 합니다.
질문 트랜잭션을 사용해 본 경험이 있나요? 어떤 경우에 사용할 수 있나요?
답변 포인트 주문 생성과 재고 차감, 계좌 이체, 게시글 작성과 첨부파일 메타데이터 저장처럼 여러 변경이 하나의 작업 단위여야 할 때 사용합니다.
질문 읽기에는 트랜잭션을 걸지 않아도 될까요?
답변 포인트 애플리케이션에서 명시적인 다중 문장 트랜잭션을 생략할 수는 있지만, 일반적인 DB에서는 단일 조회도 autocommit 트랜잭션 안에서 실행됩니다.
여러 쿼리 간 일관된 스냅샷이 필요하거나 JPA 지연 로딩, repeatable read가 필요하면 읽기 작업에도 명시적인 트랜잭션 경계가 의미가 있습니다.
주의할 점
- 트랜잭션은 길게 유지할수록 락과 리소스 점유가 늘어 성능에 영향을 줄 수 있습니다.
4. 트랜잭션 격리 레벨에 대해 설명해 주세요.
기본 답변
트랜잭션 격리 레벨은 동시에 실행되는 트랜잭션들이 서로의 변경을 어느 정도 볼 수 있는지 정하는 기준입니다.
낮은 격리 수준은 동시성이 좋지만 이상 현상이 생길 수 있고, 높은 격리 수준은 정합성이 강하지만 성능 비용이 커질 수 있습니다.
대표 레벨은 Read Uncommitted, Read Committed, Repeatable Read, Serializable입니다.
각각 dirty read, non-repeatable read, phantom read 같은 현상을 얼마나 막는지가 다릅니다.
핵심 키워드
- Dirty Read
- Non-repeatable Read
- Phantom Read
- Read Committed
- Repeatable Read
- Serializable
꼬리질문
질문 모든 DBMS가 4개의 레벨을 모두 구현하고 있나요?
답변 포인트 표준 레벨은 있지만 DBMS마다 구현 방식과 실제 보장 범위가 다릅니다.
MVCC, lock, snapshot isolation 등에 따라 차이가 있습니다.
질문 MySQL InnoDB 기준 Undo 영역과 Redo 영역에 대해 설명해 주세요.
답변 포인트 undo log는 rollback과 MVCC 일관 읽기에 사용되고, redo log는 장애 복구를 위해 변경 내용을 재적용하는 데 사용됩니다.
질문 스토리지 엔진이 정확히 무엇을 하는 건가요?
답변 포인트 실제 데이터 저장, 인덱스 관리, 트랜잭션, 락, 복구 등을 담당하는 DBMS 내부 컴포넌트입니다.
MySQL에서는 InnoDB, MyISAM 등이 있습니다.
주의할 점
- 격리 레벨 이름이 같아도 DBMS별 동작이 완전히 같지 않을 수 있습니다.
5. 인덱스가 무엇이고, 언제 사용하는지 설명해 주세요.
기본 답변
인덱스는 테이블 데이터를 더 빠르게 찾기 위한 별도 자료구조입니다.
책의 목차처럼 특정 컬럼 값을 기준으로 데이터 위치를 빠르게 찾게 해줍니다.
RDB에서는 B+Tree 인덱스가 일반적이고, 해시 인덱스나 전문 검색 인덱스도 있습니다.
인덱스는 조회 성능을 높일 수 있지만, 삽입/수정/삭제 시 인덱스도 함께 갱신해야 하므로 쓰기 비용과 저장 공간이 증가합니다.
핵심 키워드
- Index
- B+Tree
- Selectivity
- Composite Index
- Clustered Index
- Covering Index
꼬리질문
질문 수정이 잦은 테이블에서 인덱스를 권하지 않는 이유는 무엇인가요?
답변 포인트 데이터 변경 때마다 인덱스도 갱신되어 쓰기 비용이 증가하고, 페이지 분할이나 락 경합이 생길 수 있습니다.
질문 인덱스에서 사용하지 않겠다고 선택한 값은 위 정책을 그대로 따라가나요?
답변 포인트 인덱스가 없는 컬럼은 쓰기 시 해당 인덱스 갱신 비용은 없지만, 조회 시 full scan 가능성이 커집니다.
자주 조회되는 조건인지가 기준입니다.
질문 ORDER BY/GROUP BY는 인덱스와 어떤 관계가 있나요?
답변 포인트 인덱스 순서가 정렬/그룹 조건과 맞으면 별도 sort 비용을 줄일 수 있습니다.
복합 인덱스의 컬럼 순서가 중요합니다.
질문 기본키는 인덱스라고 할 수 있을까요?
답변 포인트 기본키는 제약 조건이고, DB는 이를 보장하기 위해 인덱스를 생성합니다.
InnoDB에서는 기본키가 클러스터드 인덱스입니다.
질문 외래키는요?
답변 포인트 외래키는 참조 무결성 제약입니다.
DBMS에 따라 인덱스가 자동 생성되거나 별도 생성이 필요합니다.
MySQL InnoDB는 외래키 컬럼에 인덱스가 필요합니다.
질문 인덱스가 데이터의 물리적 저장에도 영향을 미치나요?
답변 포인트 클러스터드 인덱스는 데이터 저장 순서에 영향을 줍니다.
InnoDB 테이블 데이터는 기본키 클러스터드 인덱스의 leaf에 저장됩니다.
질문 NoSQL도 인덱스를 갖고 있나요?
답변 포인트 MongoDB, Redis, Elasticsearch 등도 각 모델에 맞는 인덱스나 검색 구조를 제공합니다.
RDB B+Tree와 목적은 비슷하지만 구현과 쿼리 모델은 다릅니다.
질문 (A, B) 인덱스에서 A 조건 없이 B 조건만 사용하면 인덱스를 탈까요?
답변 포인트 일반적인 B+Tree 복합 인덱스는 leftmost prefix 원칙이 있어 A 없이 B만으로는 효율적으로 사용하기 어렵습니다.
DBMS 최적화에 따라 skip scan 등 예외는 있을 수 있습니다.
주의할 점
- 인덱스는 많을수록 좋은 것이 아닙니다. 쿼리 패턴과 선택도, 쓰기 비용을 함께 봐야 합니다.
6. RDBMS, NoSQL에서의 클러스터링/레플리케이션 방식에 대해 설명해 주세요.
기본 답변
레플리케이션은 같은 데이터를 여러 노드에 복제해 가용성과 읽기 확장성을 높이는 방식입니다.
클러스터링은 여러 노드가 하나의 시스템처럼 동작하도록 구성하는 방식으로, 제품과 문맥에 따라 의미가 조금씩 다릅니다.
RDBMS에서는 primary-replica, multi-primary, shared-nothing sharding 등을 사용하고, NoSQL은 처음부터 분산 저장과 복제를 전제로 설계된 제품이 많습니다.
핵심 키워드
- Replication
- Primary/Replica
- Sharding
- Consistency
- Failover
- Distributed Transaction
꼬리질문
질문 이러한 분산 환경에선, 트랜잭션을 어떻게 관리할 수 있을까요?
답변 포인트 요구하는 보장 수준에 따라 접근이 다릅니다. 2PC는 여러 참여자의 commit을 원자적으로 조정하지만 coordinator와 가용성 비용이 있습니다.
Saga는 여러 로컬 트랜잭션과 보상 동작으로 장기 작업의 최종 일관성을 관리하고, Transactional Outbox는 로컬 데이터 변경과 이벤트 기록을 같은 트랜잭션에 묶어 메시지 발행 유실을 줄이는 패턴입니다.
각 방식의 원자성, 지연, 장애 복구, 정합성과 가용성 트레이드오프를 구분해서 선택해야 합니다.
질문 마스터, 슬레이브 데이터 동기화 전 까지의 데이터 정합성을 지키는 방법은 무엇이 있을까요?
답변 포인트 동기 복제, semi-sync 복제, read-your-writes 보장을 위해 primary read, replication lag 모니터링, 세션별 라우팅을 사용할 수 있습니다.
질문 다중 트랜잭션 상황에서 Deadlock 상황과, 이를 해결하기 위한 방법에 대해 설명해 주세요.
답변 포인트 서로 다른 트랜잭션이 서로의 락을 기다리면 발생합니다.
DB는 deadlock detection 후 하나를 rollback할 수 있고, 애플리케이션은 락 순서 고정, 짧은 트랜잭션, 재시도로 대응합니다.
질문 샤딩 방식은 무엇인가요? 레플리케이션과 샤딩 중 어떤 것을 사용할 것 같나요?
답변 포인트 샤딩은 데이터를 기준에 따라 여러 노드에 나누어 저장하는 방식입니다.
읽기 확장과 가용성이 목적이면 레플리케이션, 데이터 크기와 쓰기 부하 분산이 목적이면 샤딩을 고려합니다.
주의할 점
- 레플리케이션은 복제, 샤딩은 분할입니다. 해결하는 문제가 다릅니다.
7. 정규화가 무엇인가요?
기본 답변
정규화는 데이터 중복과 이상 현상을 줄이기 위해 테이블을 구조화하는 과정입니다.
함수 종속성을 기준으로 데이터를 적절히 분해해 삽입, 수정, 삭제 이상을 줄입니다.
정규화는 데이터 정합성에 유리하지만 조인이 늘어 성능이 떨어질 수 있습니다.
조회 성능이나 운영 편의가 중요할 때는 의도적으로 역정규화를 하기도 합니다.
핵심 키워드
- Normalization
- Functional Dependency
- 1NF
- 2NF
- 3NF
- Denormalization
꼬리질문
질문 정규화를 하지 않을 경우, 발생할 수 있는 이상현상에 대해 설명해 주세요.
답변 포인트 삽입 이상, 수정 이상, 삭제 이상이 발생할 수 있습니다.
중복 데이터 때문에 일부만 변경되어 불일치가 생길 수 있습니다.
질문 각 정규화에 대해, 그 정규화가 진행되기 전/후의 테이블의 변화에 대해 설명해 주세요.
답변 포인트 1NF는 원자값, 2NF는 부분 함수 종속 제거, 3NF는 이행 함수 종속 제거가 핵심입니다.
질문 정규화가 무조건 좋은가요?
답변 포인트 아닙니다.
읽기 성능, 조인 비용, 리포팅 요구 때문에 역정규화를 선택할 수 있습니다.
단 정합성 유지 방안을 함께 설계해야 합니다.
주의할 점
- 정규화는 성능 최적화가 아니라 데이터 정합성을 위한 설계 원칙입니다.
8. View가 무엇이고, 언제 사용할 수 있나요?
기본 답변
View는 하나 이상의 테이블을 기반으로 정의한 가상 테이블입니다.
실제 데이터를 별도로 저장하지 않고, 정의된 쿼리를 통해 결과를 보여주는 경우가 일반적입니다.
복잡한 쿼리를 재사용하거나, 특정 컬럼만 노출해 보안을 강화하거나, 애플리케이션에 단순한 조회 인터페이스를 제공할 때 사용할 수 있습니다.
핵심 키워드
- View
- Virtual Table
- Query Reuse
- Security
- Updatable View
- Materialized View
꼬리질문
질문 View의 값을 수정해도 실제 테이블에는 반영되지 않나요?
답변 포인트 단순 view는 조건을 만족하면 updatable할 수 있고 실제 base table에 반영됩니다.
조인, 집계, group by 등이 포함되면 수정이 제한될 수 있습니다.
materialized view는 별도 저장 구조라 갱신 방식이 다릅니다.
주의할 점
- View가 항상 성능을 높이는 것은 아닙니다. 복잡한 view는 오히려 쿼리 최적화를 어렵게 할 수 있습니다.
9. DB Join이 무엇인지 설명하고, 각각의 종류에 대해 설명해 주세요.
기본 답변
Join은 둘 이상의 테이블을 관련 컬럼을 기준으로 결합해 하나의 결과를 만드는 연산입니다.
정규화된 데이터베이스에서는 데이터를 여러 테이블에 나누기 때문에 join이 중요합니다.
대표적으로 inner join, left/right outer join, full outer join, cross join, self join이 있습니다.
join 성능은 데이터 크기, 인덱스, 조인 조건, 실행 계획에 크게 영향을 받습니다.
핵심 키워드
- Inner Join
- Outer Join
- Cross Join
- Nested Loop Join
- Hash Join
- Execution Plan
꼬리질문
질문 JOIN은 내부적으로 어떤 구현 방식을 사용하나요?
답변 포인트 nested loop join, hash join, sort-merge join 등이 있습니다.
DBMS와 실행 계획에 따라 선택됩니다.
질문 입력한 쿼리에서 어떤 구현 방식을 사용하는지는 어떻게 알 수 있나요?
답변 포인트
EXPLAIN, EXPLAIN ANALYZE 같은 실행 계획을
확인합니다.
질문 JOIN의 성능도 인덱스의 영향을 받나요?
답변 포인트 매우 큽니다.
조인 조건 컬럼에 적절한 인덱스가 있으면 nested loop join 비용이 크게 줄 수 있습니다.
질문 3중 조인 부터는 동작 방식이 약간 바뀝니다. 어떻게 동작하나요?
답변 포인트 옵티마이저가 조인 순서를 결정하고 중간 결과를 만들어 다음 테이블과 조인합니다.
조인 순서와 중간 결과 크기가 성능에 큰 영향을 줍니다.
주의할 점
- join은 무조건 느린 것이 아닙니다. 올바른 인덱스와 실행 계획이 있으면 정규화된 구조에서도 효율적으로 동작합니다.
10. B-Tree와 B+Tree에 대해 설명해 주세요.
기본 답변
B-Tree는 하나의 노드가 여러 key와 child를 가질 수 있는 균형 탐색 트리입니다.
디스크나 SSD 같은 블록 기반 저장장치에서 적은 I/O로 많은 데이터를 탐색하기 좋습니다.
B+Tree는 내부 노드에는 key만 저장하고 실제 데이터 포인터는 leaf 노드에 모아두며, leaf 노드끼리 연결되어 range scan에 유리합니다.
많은 RDBMS 인덱스가 B+Tree 기반입니다.
핵심 키워드
- B-Tree
- B+Tree
- Disk I/O
- Fan-out
- Leaf Node
- Range Scan
꼬리질문
질문 B+Tree가 B-Tree에 비해 반드시 좋다고 할 수 있을까요?
답변 포인트 B+Tree는 range scan과 높은 fan-out에 유리하지만, 특정 key 조회에서 내부 노드에 데이터가 있는 B-Tree가 이점이 있을 수도 있습니다.
사용 목적에 따라 다릅니다.
질문 DB에서 RBT를 사용하지 않고, B-Tree/B+Tree를 사용하는 이유가 있을까요?
답변 포인트 RBT는 메모리 내 탐색에는 좋지만 노드 fan-out이 작아 디스크 I/O가 많아질 수 있습니다.
B+Tree는 한 노드에 많은 key를 담아 트리 높이를 낮춥니다.
질문 오름차순 인덱스에서 내림차순 정렬을 시도할 경우 성능은 어떻게 될까요?
답변 포인트 B+Tree는 양방향 탐색이 가능해 역순 스캔으로 처리할 수 있습니다.
다만 복합 인덱스의 정렬 방향과 쿼리 조건에 따라 추가 정렬이 필요할 수 있습니다.
주의할 점
- B+Tree가 DB 인덱스에서 중요한 이유는 Big-O뿐 아니라 디스크 I/O와 range scan 때문입니다.
11. DB Locking에 대해 설명해 주세요.
기본 답변
DB Locking은 동시에 여러 트랜잭션이 같은 데이터에 접근할 때 정합성을 지키기 위한 제어 방식입니다.
읽기 락, 쓰기 락, row lock, table lock, gap lock 등 다양한 락이 있습니다.
락은 정합성을 보장하지만 오래 유지되면 대기와 데드락이 발생할 수 있습니다.
따라서 트랜잭션 범위를 짧게 유지하고 적절한 인덱스로 잠금 범위를 줄이는 것이 중요합니다.
핵심 키워드
- Shared Lock
- Exclusive Lock
- Row Lock
- Table Lock
- Optimistic Lock
- Pessimistic Lock
꼬리질문
질문 Optimistic Lock/Pessimistic Lock에 대해 설명해 주세요.
답변 포인트 비관적 락은 충돌이 날 것으로 보고 먼저 락을 잡습니다.
낙관적 락은 충돌이 드물다고 보고 version 컬럼 등으로 update 시점에 충돌을 감지합니다.
질문 물리적인 Lock을 건 요청이 비정상 종료되면 Lock이 절대 해제되지 않는 문제가 생길 수도 있지 않나요?
답변 포인트 DB는 연결 종료나 트랜잭션 rollback 시 락을 해제합니다.
애플리케이션 레벨 분산 락은 TTL, fencing token, finally 해제, watchdog 등을 고려해야 합니다.
주의할 점
-
SELECT ... FOR UPDATE같은 비관적 락은 트랜잭션 안에서 의미가 있습니다.
12. 트래픽이 높아질 때, DB는 어떻게 관리를 할 수 있을까요?
기본 답변
DB 트래픽이 높아지면 먼저 쿼리 최적화, 인덱스 개선, 커넥션 풀 조정, 캐시 도입, 읽기/쓰기 분리, 배치 처리 등을 고려합니다.
이후에도 한계가 있으면 레플리케이션, 샤딩, 파티셔닝, 스케일업/스케일아웃을 검토합니다.
중요한 것은 병목이 CPU, I/O, 락, 커넥션, 쿼리 계획 중 어디인지 측정하고 해결하는 것입니다.
핵심 키워드
- Query Optimization
- Index
- Cache
- Read Replica
- Partitioning
- Sharding
꼬리질문
질문 DB 서버를 분산하지 않고, 트래픽을 감당할 수 있는 방법은 없을까요?
답변 포인트 쿼리 튜닝, 인덱스 최적화, 캐싱, connection pool 제한, batch 처리, 불필요한 조회 제거, 스케일업, 파티셔닝 등을 먼저 고려할 수 있습니다.
주의할 점
- 무조건 샤딩부터 생각하면 운영 복잡도가 크게 늘어납니다. 단일 DB 최적화와 캐시 전략이 먼저인 경우가 많습니다.
13. Schema가 무엇인가요?
기본 답변
스키마는 데이터베이스의 구조와 제약 조건을 정의한 것입니다.
테이블, 컬럼, 타입, 관계, 인덱스, 제약 조건 등이 스키마에 포함됩니다.
스키마는 데이터가 어떤 형태로 저장되고 어떤 규칙을 만족해야 하는지 정하는 설계도 역할을 합니다.
핵심 키워드
- Schema
- Table
- Constraint
- Logical Schema
- Physical Schema
- External Schema
꼬리질문
질문 Schema의 3계층에 대해 설명해 주세요.
답변 포인트 외부 스키마는 사용자 관점, 개념 스키마는 전체 논리 구조, 내부 스키마는 물리 저장 구조를 의미합니다.
주의할 점
- MySQL에서 schema가 database와 유사하게 쓰이는 것처럼 제품마다 용어 사용이 다를 수 있습니다.
14. DB의 Connection Pool에 대해 설명해 주세요.
기본 답변
Connection Pool은 DB 연결을 미리 만들어두고 재사용하는 구조입니다.
매 요청마다 DB 연결을 새로 만들면 TCP 연결, 인증, 초기화 비용이 크기 때문에 pool을 통해 성능과 안정성을 높입니다.
Pool 크기는 무작정 크게 하면 안 됩니다.
DB가 처리할 수 있는 동시 연결 수, 애플리케이션 스레드 수, 쿼리 지연 시간, 트랜잭션 길이를 고려해야 합니다.
핵심 키워드
- Connection Pool
- HikariCP
- max pool size
- timeout
- transaction
- DB connection
꼬리질문
질문 DB와 Client가 Connection을 어떻게 구성하는지 설명해 주세요.
답변 포인트 일반적으로 TCP 연결을 맺고, DB 프로토콜 handshake와 인증을 거쳐 세션을 생성합니다.
애플리케이션은 이 연결을 통해 SQL을 전송하고 결과를 받습니다.
주의할 점
- 커넥션 풀 크기를 늘리면 처리량이 항상 증가하는 것이 아닙니다. DB 병목이 심해질 수 있습니다.
15. Table Full Scan, Index Range Scan에 대해 설명해 주세요.
기본 답변
Table Full Scan은 테이블의 모든 행을 읽어 조건에 맞는 데이터를 찾는 방식입니다.
Index Range Scan은 인덱스에서 조건에 맞는 범위만 탐색한 뒤 필요한 데이터를 조회하는 방식입니다.
일반적으로 선택도가 높은 조건에는 인덱스 스캔이 유리하지만, 많은 행을 읽어야 한다면 full scan이 더 효율적일 수 있습니다.
핵심 키워드
- Full Scan
- Index Range Scan
- Selectivity
- Cardinality
- Covering Index
- Optimizer
꼬리질문
질문 인덱스를 타는 쿼리임에도 Table Full Scan 방식으로 동작하는 경우가 있습니다. 왜 그럴까요?
답변 포인트 조건 선택도가 낮아 많은 행을 읽어야 하거나, 통계 정보상 full scan이 더 싸다고 판단되거나, 함수/형변환 때문에 인덱스를 활용하지 못할 수 있습니다.
질문 COUNT는 어떻게 동작하나요? COUNT(1), COUNT(*), COUNT(column)의 차이가 있나요?
답변 포인트
COUNT(*)와 COUNT(1)은 전체 행 수를 세는
의미로 DBMS가 비슷하게 최적화합니다.
COUNT(column)은 NULL이 아닌 값만 셉니다.
주의할 점
- 인덱스 사용 여부는 실행 계획으로 확인해야 합니다.
16. SQL Injection에 대해 설명해 주세요.
기본 답변
SQL Injection은 사용자 입력이 SQL 문자열에 그대로 합쳐질 때 공격자가 의도한 SQL을 삽입해 쿼리 의미를 바꾸는 공격입니다.
인증 우회, 데이터 조회/수정/삭제, 권한 상승 등의 피해가 발생할 수 있습니다.
가장 기본적인 방어는 prepared statement와 parameter binding을 사용하는 것입니다.
입력 검증, 최소 권한, 에러 메시지 제한도 함께 필요합니다.
핵심 키워드
- SQL Injection
- Prepared Statement
- Parameter Binding
- Escaping
- Least Privilege
- ORM
꼬리질문
질문 서버 개발 과정에서 사용하는 DB 라이브러리들은 이 문제를 어떻게 해결할까요?
답변 포인트 prepared statement를 사용해 SQL 구조와 값을 분리합니다.
값은 파라미터로 바인딩되어 SQL 코드로 해석되지 않습니다.
ORM도 내부적으로 parameter binding을 사용하지만, raw query 문자열 조합은 여전히 위험합니다.
주의할 점
- 단순 문자열 escape만 믿는 것은 위험합니다. SQL 구조와 값을 분리하는 것이 핵심입니다.
17. 데이터베이스의 Buffer Pool은 무엇이며 어떻게 동작하나요?
기본 답변
Buffer Pool은 디스크의 테이블과 인덱스 페이지를 DBMS가 관리하는 메모리에 보관하는 영역입니다. 필요한 페이지가 있으면 logical read만으로 처리하고, 없으면 physical I/O로 읽어 빈 프레임이나 교체 대상 프레임에 올립니다. 사용 중이라 교체할 수 없는 페이지는 pin하고, 교체 정책은 제품에 따라 LRU 계열이나 clock 계열 방식을 사용합니다.
메모리에 올라온 페이지가 변경되면 아직 데이터 파일에 반영되지 않은 dirty page가 됩니다. WAL 기반 DBMS는 데이터 페이지를 디스크에 쓰기 전에 그 변경을 설명하는 WAL 또는 redo log를 먼저 안정적인 저장장치에 기록해야 합니다. 이 write-ahead 규칙 덕분에 장애가 나도 로그를 재적용해 페이지를 복구할 수 있습니다.
일반적인 동기 commit에서는 해당 트랜잭션의 로그와 commit record가 내구성을 만족하는 지점까지 flush되면 응답할 수 있고, 모든 dirty page를 그 순간 데이터 파일에 쓸 필요는 없습니다. dirty page는 background writer나 page eviction 과정에서 나중에 내려갈 수 있습니다. 다만 비동기 commit이나 저장장치 설정처럼 내구성 정책은 DBMS와 구성에 따라 달라집니다.
Checkpoint는 복구가 시작할 로그 위치를 앞으로 옮길 수 있도록 특정 시점 이전의 dirty page와 로그 상태를 정리하고 checkpoint record를 남기는 과정입니다. commit이 개별 트랜잭션의 완료와 내구성에 관한 것이라면 checkpoint는 전체 복구 범위와 쓰기 부하를 관리합니다. 너무 잦으면 I/O가 늘고, 너무 드물면 장애 복구와 로그 보관 비용이 커질 수 있습니다.
Buffer Pool 크기는 자주 쓰는 working set, 동시 쿼리, 정렬·해시 같은 다른 메모리 수요와 운영체제 Page Cache를 함께 고려해야 합니다. 적중률만 높이는 것이 목표는 아니며, 메모리를 과도하게 할당해 swapping이 발생하면 오히려 지연이 크게 악화될 수 있습니다.
핵심 키워드
- Buffer Pool
- Page
- Dirty Page
- Checkpoint
- WAL
꼬리질문
질문 commit할 때 모든 변경 페이지도 즉시 데이터 파일에 기록되나요?
답변 포인트 반드시 그렇지는 않습니다. 일반적인 WAL 기반 DB에서는 트랜잭션의 WAL·redo 기록과 commit record를 내구성 정책에 맞게 먼저 영속화하고, dirty page는 이후에 기록할 수 있습니다.
장애가 나면 데이터 파일에 아직 반영되지 않은 commit 변경을 로그에서 다시 적용합니다. 반대로 commit되지 않은 변경의 처리 방식은 undo log, MVCC와 복구 구현에 따라 달라집니다.
질문 운영체제 Page Cache와 DB Buffer Pool은 어떤 관계인가요?
답변 포인트 둘 다 디스크 데이터를 캐시해 이중 캐싱이 생길 수 있습니다. DBMS는 직접 I/O나 자체 Buffer Pool 설정으로 역할을 조정합니다.
질문 Checkpoint를 너무 자주 또는 너무 드물게 수행하면 어떤 문제가 생기나요?
답변 포인트 너무 자주 하면 dirty page 쓰기와 checkpoint 이후의 추가 로그 비용이 빈번해져 정상 트랜잭션 I/O와 경합할 수 있습니다. 쓰기를 일정 시간에 분산해 급격한 지연을 피하는 설정이 필요합니다.
너무 드물면 장애 후 재적용할 로그가 늘어 복구 시간이 길어지고 로그 보관 공간도 커질 수 있습니다. 목표 복구 시간과 정상 시점의 쓰기 부하 사이에서 조정해야 합니다.
질문 Buffer Pool에서 교체할 페이지가 dirty page라면 어떻게 하나요?
답변 포인트 write-ahead 규칙에 필요한 로그가 먼저 영속화됐는지 확인한 뒤 데이터 파일에 페이지를 기록해야 해당 프레임을 재사용할 수 있습니다. 즉시 쓰기 비용을 피하려고 background writer가 미리 dirty page를 내리기도 합니다.
현재 쿼리가 pin한 페이지는 교체할 수 없고, dirty page가 과도하게 쌓이면 eviction 시점의 지연이 커질 수 있으므로 checkpoint와 background flush 속도를 함께 관리합니다.
질문 Buffer Pool hit ratio가 높으면 데이터베이스 성능이 항상 좋은가요?
답변 포인트 아닙니다. 비효율적인 쿼리가 같은 페이지를 반복해서 읽어도 hit ratio는 높을 수 있고, CPU, 락, 로그 flush, 네트워크와 커넥션 경합이 다른 병목일 수 있습니다.
물리 읽기, 쿼리 지연 분포, working set, eviction과 dirty page 쓰기를 실행 계획과 함께 관찰해야 합니다.
주의할 점
- checkpoint와 개별 트랜잭션 commit은 같은 개념이 아닙니다.
- Buffer Pool은 Redis 같은 애플리케이션 결과 캐시와 역할이 다릅니다.
18. Offset 기반 페이지네이션과 Cursor 기반 페이지네이션을 비교해 주세요.
기본 답변
Offset 방식은 LIMIT n OFFSET m처럼 정렬된 결과의 앞
m개를 건너뛰고 다음 n개를 반환합니다. 구현이
단순하고 전체 개수와 페이지 번호를 보여주거나 임의 페이지로 이동하기
쉽습니다. 반면 offset이 커지면 DB가 인덱스나 결과에서 앞 행을 찾아
버리는 비용이 늘 수 있습니다.
각 요청이 서로 다른 시점의 데이터를 보면 앞 페이지에 행이 삽입되거나 삭제될 때 다음 페이지에서 중복 또는 누락이 생길 수 있습니다. 높은 격리 수준이나 하나의 긴 snapshot으로 줄일 수 있지만 여러 HTTP 요청 동안 트랜잭션을 유지하는 비용이 크므로 일반 페이지 API에서는 보통 이 현상을 요구사항으로 판단합니다.
Cursor 또는 Keyset 방식은 마지막으로 본 정렬 키를 경계로 다음 데이터를
조회합니다. 예를 들어 ORDER BY created_at DESC, id DESC라면
(created_at, id) < (?, ?) 조건과 같은 순서의 복합
인덱스를 사용할 수 있습니다. 고유한 보조 키까지 포함해 전체 순서를
결정적으로 만들어야 큰 offset 없이 다음 범위를 탐색할 수 있습니다.
외부 cursor는 정렬 키뿐 아니라 필터, 정렬 방향과 버전을 함께 담은 opaque token으로 만들고 필요하면 서명해 변조를 막습니다. Keyset 방식은 연속 스크롤과 대용량 목록에 유리하지만 임의 페이지 이동이 어렵고 정렬 키가 수정되면 이동이나 중복이 생길 수 있습니다. 작은 관리자 목록이나 정확한 페이지 번호가 필요하면 Offset, 대규모 피드나 무한 스크롤이면 Keyset이 일반적으로 더 적합합니다.
핵심 키워드
- Offset Pagination
- Cursor Pagination
- Keyset Pagination
- Stable Sort
- Composite Index
꼬리질문
질문 정렬 컬럼 값이 중복되면 Cursor를 어떻게 구성하나요?
답변 포인트 중복 가능한 값에
고유한 ID를 함께 넣어 (created_at, id)처럼 전체 순서를
결정적으로 만듭니다. 쿼리의 ORDER BY, 경계 비교 조건과
인덱스의 컬럼 순서·방향도 서로 맞아야 합니다.
NULL이 가능한 키라면 DBMS의 NULL 정렬 규칙을 명시하거나 cursor용 정렬 키를 별도로 설계해야 같은 행을 안정적으로 이어갈 수 있습니다.
질문 이전 페이지로 이동하는 Cursor는 어떻게 구현하나요?
답변 포인트 정렬 방향과 비교 연산을 반대로 적용해 조회한 뒤 화면 순서로 다시 정렬합니다.
질문 페이지를 넘기는 사이 데이터가 삽입·삭제·수정되면 Keyset 방식은 항상 중복과 누락을 막나요?
답변 포인트 새 행이 이미 지나간 경계 앞에 추가되는 경우 Offset보다 기존 행의 위치 변화에 강하지만, 여러 요청을 같은 snapshot으로 묶어주는 것은 아닙니다. 삭제된 행은 보이지 않고 정렬 키가 바뀐 행은 경계를 넘어 이동해 중복되거나 누락될 수 있습니다.
정확한 시점 일관성이 필요하면 snapshot 식별자, 변경되지 않는 정렬 키나 별도의 버전 조건을 도입해야 하며 저장소 비용과 보존 기간을 함께 고려합니다.
질문 클라이언트가 Cursor 값을 임의로 바꾸거나 필터를 변경하면 어떻게 하나요?
답변 포인트 서버는 cursor에 정렬 키, 필터 식별자, 방향과 버전을 포함하고 Base64URL 같은 형태로 불투명하게 인코딩할 수 있습니다. Base64URL은 기밀성이나 무결성을 보장하지 않으므로 변조 탐지에는 MAC이나 서명을, 정보 노출 방지에는 암호화를 사용하거나 처음부터 민감 정보를 넣지 않아야 합니다. 재사용 범위를 제한하려면 만료 시간도 둡니다.
다음 요청의 필터와 cursor에 묶인 조건이 다르면 잘못된 페이지가 되므로 서버가 일치 여부를 검증하고 유효하지 않은 cursor를 명확한 오류로 처리해야 합니다.
주의할 점
- 여기서 cursor는 DB 서버 측 cursor 객체와 같은 의미가 아닐 수 있습니다.
- Keyset 방식도 요청 전체의 시점 일관성을 자동으로 보장하지는 않습니다.
19. OLTP와 OLAP의 차이를 설명해 주세요.
기본 답변
OLTP는 주문, 결제와 회원 변경처럼 짧고 빈번한 업무 트랜잭션을 낮은 지연으로 처리하는 워크로드입니다. 적은 수의 행을 키나 인덱스로 읽고 쓰는 요청이 많으며, 높은 동시성에서 제약 조건과 트랜잭션 정합성을 지키는 것이 중요합니다.
OLTP 시스템에서는 중복 갱신을 줄이는 정규화 모델과 한 행의 여러 컬럼을 함께 읽고 쓰기 좋은 row store가 흔합니다. 다만 이는 일반적인 설계 경향이지 OLTP의 정의는 아니며, 읽기 패턴과 성능 요구에 따라 일부 비정규화나 다른 저장 구조를 사용할 수 있습니다.
OLAP는 장기간 축적된 많은 행을 스캔하고 필터링·집계해 분석하는 워크로드입니다. 필요한 컬럼만 읽고 같은 타입의 값을 압축·벡터화하기 좋은 column store, 분석하기 쉬운 star schema와 사전 집계가 흔합니다. 개별 행의 짧은 갱신보다 처리량과 대규모 집계 효율이 중요한 경우가 많습니다.
운영 DB와 별도의 데이터 웨어하우스나 분석 저장소를 두어 서로 다른 워크로드의 CPU와 I/O를 격리하고, ETL·ELT·CDC는 그 저장소로 데이터를 옮기는 수단으로 사용합니다. Batch는 단순하고 비용 효율적이지만 최신성이 낮을 수 있고, CDC 기반 증분 반영은 지연을 줄이는 대신 중복, 순서, 스키마 진화와 재처리 복잡도가 늘어납니다.
핵심 키워드
- OLTP
- OLAP
- Row Store
- Column Store
- Data Warehouse
꼬리질문
질문 분석 시스템에서 컬럼 저장이 유리한 이유는 무엇인가요?
답변 포인트 필요한 컬럼만 읽고 같은 타입의 연속 값에 압축과 벡터화 실행을 적용하기 좋습니다.
질문 Read Replica에서 모든 분석 쿼리를 실행하면 충분한가요?
답변 포인트 일부 읽기 부하는 분리할 수 있지만 대규모 스캔과 정렬이 replica의 CPU·I/O를 소모해 복제 로그 적용을 지연시킬 수 있습니다. 운영 스키마도 장기간 분석과 다차원 집계에 최적화되어 있지 않을 수 있습니다.
데이터 크기와 최신성 요구가 작다면 replica로 충분할 수 있지만, 복잡한 분석이 지속되면 별도의 컬럼 저장소나 웨어하우스를 사용하고 운영 DB에는 영향 한도를 두는 편이 안전합니다.
질문 OLTP는 항상 정규화하고 OLAP는 항상 비정규화해야 하나요?
답변 포인트 아닙니다. 정규화와 저장 형식은 워크로드를 지원하기 위한 선택입니다. OLTP에서도 조회 병목을 줄이기 위해 파생 컬럼이나 요약 테이블을 둘 수 있고, OLAP에서도 데이터 품질과 재사용을 위해 정규화된 계층을 유지할 수 있습니다.
중요한 것은 갱신 정합성, 주요 쿼리의 join·scan 비용, 저장 중복과 데이터 계보를 측정해 모델을 선택하는 것입니다.
질문 운영 데이터의 최신성을 분석 시스템에 가깝게 유지하려면 어떻게 하나요?
답변 포인트 트랜잭션 로그 기반 CDC로 변경을 지속적으로 전달하고 분석 저장소에서 작은 batch나 stream으로 병합할 수 있습니다. 이벤트의 source position과 primary key를 이용해 중복 적용에 안전하게 만듭니다.
지연 시간뿐 아니라 누락 감지, schema evolution, 삭제 전파와 주기적인 원본 대조가 필요합니다. 강한 실시간성이 꼭 필요하지 않다면 단순한 micro-batch가 운영 비용 측면에서 더 나을 수 있습니다.
주의할 점
- OLTP와 OLAP는 워크로드 분류이며 제품을 한쪽으로만 단정하면 안 됩니다.
- 분석 데이터의 반영 지연과 최신성 요구를 명확히 해야 합니다.
20. 무중단에 가깝게 데이터베이스 스키마를 변경하려면 어떻게 해야 하나요?
기본 답변
Rolling 배포 중에는 구버전과 신버전 애플리케이션이 동시에 같은 DB를 사용할 수 있으므로 스키마 변경이 양쪽 버전과 호환되어야 합니다. Expand-Contract는 변경을 추가, 전환, 제거 단계로 나눠 배포와 스키마를 한 번에 바꾸지 않는 방식입니다.
Expand 단계에서는 nullable 컬럼, 새 테이블이나 새 인덱스처럼 기존 코드가 무시할 수 있는 구조를 먼저 추가합니다. 신버전이 새 구조에 값을 쓰도록 하되 구버전도 계속 동작해야 하므로 필요한 기간에는 양쪽 쓰기, DB trigger 또는 변경 이벤트 중 하나를 선택합니다. 이중 쓰기를 사용하면 부분 실패와 순서 차이를 별도로 해결해야 합니다.
기존 데이터는 작은 chunk로 나누어 backfill하고, 실행 중인 쓰기와 충돌하지 않도록 조건부 갱신과 재시작 지점을 둡니다. 작업은 멱등하게 만들고 처리량을 제한해 DB 부하와 replication lag를 관찰합니다. 완료 후 row count, null 비율, checksum이나 업무 불변식으로 구·신 데이터가 일치하는지 검증합니다.
전환 단계에서는 먼저 읽기를 새 구조로 옮기고 지표와 오류를 관찰하면서 구 구조를 rollback 경로로 유지합니다. 모든 애플리케이션 인스턴스와 비동기 작업이 새 구조를 사용하고 충분한 롤백 기간이 지난 뒤에만 구버전 쓰기를 중단합니다.
Contract 단계의 컬럼·테이블 삭제는 비가역적일 수 있으므로 가장 마지막에 수행합니다. 파괴적 변경 뒤에는 단순 rollback 대신 forward fix와 백업 복구가 필요할 수 있습니다. 큰 테이블의 DDL은 online·concurrent 기능을 사용해도 짧은 메타데이터 락, 추가 I/O와 로그 증가가 생길 수 있으므로 DBMS 버전별 동작을 확인해야 합니다.
핵심 키워드
- Expand-Contract
- Backfill
- 하위 호환성
- Online DDL
- Rolling Deployment
꼬리질문
질문 대형 테이블에 NOT NULL 컬럼을 추가하려면 어떻게 하나요?
답변 포인트 먼저 nullable 컬럼을 추가하고 신버전 애플리케이션이 새 행에 값을 쓰게 합니다. 기존 행은 작은 batch로 채우며 누락과 부하를 관찰합니다.
모든 행이 조건을 만족하는지 검증한 뒤 default와
NOT NULL 제약을 적용합니다. 일부 DBMS는 제약 검증이나
default 추가가 테이블 재작성 또는 강한 락을 일으킬 수 있으므로
제품과 버전별 실행 방식을 확인해야 합니다.
질문 마이그레이션 중 문제가 생기면 어떻게 rollback하나요?
답변 포인트 구 구조를 유지해 애플리케이션을 되돌릴 수 있게 하고 backfill은 중단·재개와 재실행이 가능하게 만듭니다.
이미 구 구조를 삭제하거나 손실 변환을 수행했다면 rollback이 안전하지 않을 수 있습니다. 이 경우 쓰기를 제한하고 forward fix를 배포하거나 검증된 백업과 변경 로그로 복구해야 합니다.
질문 운영 중인 컬럼 이름을 바꾸려면 어떻게 하나요?
답변 포인트 기존 컬럼을 즉시 rename하면 구버전 코드가 깨질 수 있으므로 새 이름의 컬럼을 추가하고 일정 기간 양쪽에 쓰거나 한쪽에서 다른 쪽으로 동기화합니다. 기존 값을 backfill한 뒤 신버전 읽기를 새 컬럼으로 전환합니다.
구버전 인스턴스와 배치·리포트·외부 소비자가 모두 사라진 것을 확인한 후 기존 컬럼을 제거합니다. DBMS가 rename alias나 호환 view를 제공한다면 요구사항에 맞게 활용할 수 있습니다.
질문 큰 테이블에 인덱스를 추가할 때 online 또는 concurrent 옵션만 사용하면 안전한가요?
답변 포인트 쓰기 차단 시간을 줄일 수는 있지만 인덱스 생성 중 전체 테이블 읽기, 추가 CPU·I/O, WAL·redo 증가와 replica 지연은 여전히 발생할 수 있습니다. 시작과 완료 시 짧은 메타데이터 락이 필요한 제품도 있습니다.
낮은 트래픽 시간, statement·lock timeout, 진행률과 디스크 여유를 확인하고 실패 후 남는 invalid index나 재시작 절차까지 준비해야 합니다.
주의할 점
- DDL의 트랜잭션과 잠금 방식은 DBMS 버전마다 다릅니다.
- 애플리케이션 이중 쓰기는 부분 실패를 고려해 멱등성과 대조 작업을 마련해야 합니다.
21. CDC(Change Data Capture)가 무엇이며 언제 사용하나요?
기본 답변
CDC는 데이터베이스에서 commit된 삽입·수정·삭제를 감지해 변경 이벤트로 전달하는 방식입니다. timestamp polling, trigger와 log-based 방식이 있으며, WAL이나 binlog를 읽는 log-based CDC는 애플리케이션 테이블을 반복 조회하는 부하를 줄이고 commit된 변경의 source position을 함께 얻을 수 있습니다.
처음 도입할 때는 기존 행을 consistent snapshot으로 읽는 동시에 그 snapshot과 대응하는 로그 위치를 확보하고, snapshot 이후의 변경을 그 위치부터 이어서 stream해야 합니다. Connector는 마지막으로 안전하게 처리한 LSN, binlog position 같은 offset을 저장해 재시작하며, snapshot과 stream의 경계에서 같은 행이 겹칠 수 있으므로 중복과 충돌을 조정해야 합니다.
변경 순서는 보통 하나의 원본 로그, connector 또는 대상 topic partition 범위에서만 의미가 있습니다. 여러 샤드나 서로 다른 토픽을 아우르는 전역 순서는 자동으로 만들어지지 않으며, 하나의 트랜잭션이 만든 여러 이벤트의 관계가 필요하면 transaction ID와 로그 위치 같은 metadata를 함께 보존해야 합니다.
장애 시 offset 저장보다 이벤트 발행이 앞서거나 뒤설 수 있어 at-least-once 구성에서는 중복 이벤트가 발생할 수 있습니다. 소비자는 source position이나 안정적인 event ID와 업무 키를 저장해 같은 이벤트를 다시 적용해도 결과가 같도록 만들어야 합니다. Broker의 exactly-once 기능만으로 외부 DB, 검색엔진과 API까지 포함한 종단 간 exactly-once가 자동 보장되지는 않습니다.
CDC는 검색 인덱스, 캐시, 데이터 웨어하우스와 stream 처리에 유용하지만 schema evolution, 삭제·tombstone 의미, connector lag, 로그 보존 기간, 재처리와 개인정보 전파를 운영해야 합니다. 파이프라인이 오래 멈춰 필요한 로그가 원본에서 사라지면 offset만으로 재개할 수 없어 snapshot을 다시 수행해야 할 수 있습니다.
핵심 키워드
- Change Data Capture
- WAL/Binlog
- Snapshot
- Offset
- Idempotent Consumer
꼬리질문
질문 CDC와 Transactional Outbox는 어떻게 다른가요?
답변 포인트 일반 CDC는 업무 테이블의 row-level 변경을 그대로 관찰하므로 소비자가 여러 변경에서 비즈니스 의미를 추론해야 할 수 있습니다. Outbox는 애플리케이션이 발행할 비즈니스 이벤트를 outbox 테이블에 업무 변경과 같은 트랜잭션으로 명시합니다.
Outbox relay는 polling이나 CDC로 이 테이블을 읽어 broker에 전달할 수 있습니다. DB commit과 이벤트 의도 기록은 원자적이지만 broker 전달은 재시도될 수 있으므로 event ID와 멱등 소비자는 여전히 필요합니다.
질문 CDC에서 삭제는 어떻게 전달하나요?
답변 포인트 원본 DB 로그의 DELETE 이벤트는 보통 행의 key와 connector 설정에 따라 before image를 담습니다. Broker의 log compaction에서 사용하는 null-value tombstone은 원본 삭제 이벤트와 역할이 다를 수 있으므로 포맷 계약을 명확히 해야 합니다.
소비자는 key를 기준으로 hard delete, soft delete 또는 법적 보존 정책을 멱등하게 적용하고, 중복되거나 늦게 도착한 삭제가 더 최신 데이터를 지우지 않도록 source position이나 version을 비교합니다. 개인정보 삭제 기한이 있다면 각 downstream의 처리 완료와 재처리 로그까지 추적해야 합니다.
질문 초기 Snapshot을 수행하는 동안 원본 데이터가 바뀌면 누락이나 중복을 어떻게 막나요?
답변 포인트 Connector는 일관된 snapshot을 시작한 로그 위치를 기록하고, snapshot 중 발생한 변경도 로그에서 계속 보존합니다. Snapshot이 끝나면 기록한 위치 이후의 변경을 이어서 처리합니다.
Snapshot의 READ 이벤트와 streaming UPDATE·DELETE가 같은 키에서 겹치거나 순서가 교차할 수 있으므로 source position과 primary key를 기준으로 buffering·deduplication하거나 최신 이벤트가 이기도록 병합해야 합니다.
질문 CDC 이벤트의 순서를 어디까지 신뢰할 수 있나요?
답변 포인트 하나의 원본 트랜잭션 로그와 동일한 connector stream 안에서는 로그 위치로 순서를 추적할 수 있습니다. 하지만 테이블별 토픽이나 여러 Kafka partition으로 나뉘면 서로 다른 partition 사이의 소비 순서는 보장되지 않습니다.
여러 샤드의 변경을 하나의 전역 순서로 합치려면 별도의 sequence나 조정 계층이 필요하고 비용과 가용성 trade-off가 생깁니다. 필요한 일관성 단위를 row, aggregate 또는 transaction으로 먼저 정해야 합니다.
질문 CDC Connector가 오래 중단됐다가 다시 시작하면 어떻게 되나요?
답변 포인트 저장된 offset이 가리키는 WAL이나 binlog가 원본에 남아 있다면 그 위치부터 다시 읽을 수 있습니다. 중단 기간 동안 로그가 계속 쌓이므로 원본의 보존 공간과 connector lag를 모니터링해야 합니다.
필요한 로그가 이미 삭제됐다면 연속 스트리밍을 재개할 수 없으므로 새로운 snapshot으로 상태를 다시 맞추고 downstream 데이터의 중복·교체 정책을 적용해야 합니다.
주의할 점
- CDC만으로 전체 파이프라인의 exactly-once가 보장되지는 않습니다.
- CDC 로그는 업무 감사 로그를 자동으로 대체하지 않습니다.