변경 데이터 캡처

데이터베이스에서 **변경 데이터 캡처**(change data capture, CDC)는 변경된 데이터를 사용하여 동작을 취할 수 있도록 데이터를 결정하고 추적하기 위해 사용되는 여러 소프트웨어 디자인 패턴들의 모임이다. CDC는 기업 데이터 소스에 이루어지는 변경사항의 식별, 포착, 전송에 기반한 데이터 통합의 접근을 말한다. CDC는 데이터 웨어하우스 환경에서 주로 발생하는데, 그 이유는 시간에 걸쳐 데이터 상태를 포착하고 보존하는 일이 데이터 웨어하우스의 핵심 기능 가운데 하나이기 때문이다. 그러나 CDC는 모든 데이터베이스, 데이터 저장소 시스템에서 활용이 가능하다.
# 방법론
시스템 개발자들은 수많은 방식으로, 또 애플리케이션 로직의 시스템 레이어들 중 하나 이상에서부터 물리적 스토리지에 이르기까지 CDC 매커니즘을 구축할 수 있다. 단순한 CDC 환경에서 한 컴퓨터 시스템이 이전 시점에서 변경된 것으로 생각되는 데이터가 있으다면 두 번째 컴퓨터 시스템은 변경된 데이터에 기반한 동작을 취할 필요가 있다. 전자의 경우 소스(source), 후자의 경우 타겟(target)으로 부른다. 소스와 타겟이 물리적으로 동일한 시스템일 수 있지만 논리적으로 디자인 패턴을 바꾸지는 못한다. 여러 CDC 솔루션들이 한 시스템에 공존할 수 있다.
## 로우의 타임스탬프
변경이 포착되어야 하는 테이블은 마지막 변경 시간을 대표하는 컬럼을 가질 수 있다. LAST_UPDATE 등의 이름이 일반적이다. 마지막 시간 데이터보다 더 근래의 컬럼 내 타임스탬프를 보유하는 모든 테이블의 로우는 변경된 것으로 간주된다. 로우의 타임스탬프는 또한 낙관적인 잠금(optimistic locking)에 자주 사용되므로 이 컬럼을 종종 사용하게 되는 일이 있다.
## 로우의 버전 번호
데이터베이스 설계자들은 변경이 포착되어야 하는 테이블에 버전 번호를 포함한 컬럼을 제공한다. VERSION_NUMBER 등의 이름이 일반적이다. 한 기법으로, 변경되는 매 로우를 버전 번호로 표시하는 것이다. 현재 버전은 테이블이나 여러 테이블을 위해 유지관리된다. 이는 참조 테이블과 같은 지원 구성체에 저장된다. 변경 포착이 발생하면 최신 버전 번호의 모든 데이터는 변경된 것으로 간주된다. 변경 포착이 끝나면 참조 테이블은 새 버전 번호로 업데이트된다.
## 로우의 상태 표시기
이 기법은 타임스탬프와 버저닝을 보충하는 것이다. 로우 변경 지시를 위해 테이블 로우에 상태 컬럼을 구성한 경우에 대안으로 구성이 가능하다. 아니면 새 버전 번호나 이후의 날짜가 있더라도 로우가 타겟에 업데이트되면 안 되는 것을 지시하도록 이전 방식의 보완하는 방식으로 이용이 가능하다.
## 로우의 시간/버전/상태
이 접근은 앞서 논의된 3개의 방식을 합쳐놓은 것이다. 여러 CDC 솔루션이 하나의 시스템에서 동작하는 것을 보는 것은 일반적이지 않으나 시간, 버전, 상태를 하나로 합치면 특히 강력한 매커니즘을 제공하며 프로그래머는 이들을 함께 활용하게 된다. 이 요소들은 과잉이 아니다. 이들을 함께 이용하면 "상태 코드가 운용 서버에 준비가 된 것을 지시하는, 6/1/2005 오전 12:00와 7/1/2005 오전 12:00 사이에 변경된 버전 2.1의 모든 데이터를 포획하라"와 같은 로직을 허용한다.
## 테이블에 트리거
변경된 데이터를 여러 타겟에 통신하는 퍼블리시/서브스크라이브 패턴을 포함할 수 있다. 이 접근법에서 트리거는 트랜잭션 테이블에 발생할 이벤트를 기록하고 나중에 플레이백(play back)해본다. 예를 들어 Accounts 테이블이 있다고 치면 트랜잭션이 이 테이블에 발생할 때 트리거가 발생하면 이벤트의 역사를 저장한다. 큐 테이블은 다음의 필드를 가진 스키마를 보유할 수 있다: Id, TableName, RowId, TimeStamp, Operation. Account 테이블에 인서트된 데이터는 다음과 같을 수 있다: 1, Accounts, 76, 11/02/2008 12:15am, Update. 더 복잡한 디자인은 변경된 실제 데이터를 기록할 수 있다. 그러면 이 큐 테이블은 소스 시스템에서 타겟으로 데이터를 복제하기 위해 플레이백(play back)의 대상이 될 수 있다. 이 기법의 한 예는 로그 트리거라는 패턴이다.
## 이벤트 프로그래밍
이벤트 프로그래밍 방식이 단순히 프로그래밍이냐, 더 쉽게 구현하는 터무니없는 트리거이냐의 문제이긴 하지만 "COMMIT 후에만 처리", "특정 컬럼이 특정 값으로 변경된 후에만" 등처럼 더 정확하고 만족할만한 CDC를 제공한다.
## 로그 스캐너
대부분의 데이터베이스 관리 시스템은 데이터베이스 내용과 메타데이터의 변경을 기록하는 트랜잭션 로그를 관리한다. 데이터베이스 트랜잭션 로그의 내용을 해석함으로써 거슬리지 않는 방식으로 데이터베이스에 이루어진 변경을 포착할 수 있다. 변경 데이터 캡처에 트랜잭션 로그를 이용하는 것은 트랜잭션 로그의 구조, 내용, 이용이 특정 데이터베이스 관리 시스템에만 한정된다는 문제가 된다. 데이터 접근과 달리 트랜잭션 로그에는 표준이 존재하지 않는다. 대부분의 데이터베이스 관리 시스템은 자사의 트랜잭션 로그의 내부 포맷을 문서화해놓지 않으며 대신 트랜잭션 로그에 접근할 프로그래밍 인터페이스를 제공한다. (예: 오라클, DB2, SQL/MP, SQL/MX, SQL 서버 2008). 변경 데이터 캡처에 트랜잭션 로그를 사용 시 마주치는 다른 문제는 다음과 같다: * 트랜잭션 로그를 읽는 것과 로그 파일의 보관(아카이브)을 조율하는 문제(데이터베이스 관리 소프트웨어는 일반적으로 정기적으로 오프라인 상태에서 로그 파일을 보관 처리한다) * 트랜잭션 로그, 그리고 보통 데이터베이스 사용자가 예측하는 논리 포맷으로 기록된 물리적 스토리지 포맷들 간 변환 문제 (예: 일부 트랜잭션 로그는 고객에게 직접적으로 유용하지 않은 최소한의 버퍼 차이만 저장한다) * 데이터베이스 관리 시스템의 버전 간 트랜잭션 로그의 포맷 변경을 다루는 문제. * 데이터베이스가 트랜잭션 로그에 기록했으나 나중에 롤백 처리한, 커밋하지 않은 변경 내용을 제거하는 문제. * 데이터베이스 내 테이블의 메타데이터의 변경내용을 다루는 문제. 트랜잭션 로그 파일에 기반한 CDC 솔루션들은 다음과 같은 장점을 갖추고 있다: * 데이터베이스에 최소한의 영향을 준다 (특히 전용 호스트에서 로그를 처리하기 위해 로그 시핑/log shipping을 사용하는 경우 더욱) * 데이터베이스를 사용하는 애플리케이션에 프로그래밍적 변경을 할 필요가 없다. * 변경 내용 획득에 낮은 레이턴시를 보인다. * 트랜잭션 무결성: 로그 스캐닝은 커밋한 순서대로 오리지널 트랜잭션을 리플레이하는 변경 스트림을 만들 수 있다. 이러한 변경 스트림에는 포착된 트랜잭션에 관여한 모든 테이블의 변경 내용을 포함한다. * 데이터베이스 스키마를 변경할 필요가 없다
# 문제 요소
복잡한 도메인에서 종종 발생하는데, CDC 문제의 최종 해결책은 수많은 문제의 균형을 맞추는 것이다.
## 부적절한 소스 시스템
변경 데이터 캡처는 소스 시스템이 메타데이터 변경사항을 저장하는 경우 데이터 그 자체가 수정되지 않을 때 복잡도가 증가하고 가치는 하락한다. 예를 들어 일부 데이터 모델은 데이터를 변경하지 않았으나 마지막으로 보기만 한 사용자를 추적한다. 이는 변경 데이터 캡처에서 노이즈(noise)를 만들어낸다.
## 캡처 추적
실제로 변경을 추적하는 것은 데이터 소스에 달려있다. 데이터가 현대의 데이터베이스에 영송적이라면 변경 데이터 캡처는 단순 권한 문제일 뿐이다. 2개의 기법이 일반적으로 사용된다: * 데이터베이스 트리거를 이용하여 변경사항 추적 * 쓰기 직후 트랜잭션 로그를 읽기 데이터가 현대의 데이터베이스에 없는 경우 CDC는 프로그래밍적 문제를 앉게 된다.
## 푸시, 풀
* **푸시**(Push): 소스 프로세스는 자체 프로세스 내에서 변경 스냅샷을 만들고 다운스트림으로 로우를 전달한다. 이 다운스트림 프로세스는 스냅샷을 사용하고 자체 서브셋을 만든 다음에 이를 다음 프로세스에 전달한다. * **풀**(Pull): 소스로부터 즉시 다운스트림을 받은 타겟은 소스로부터의 데이터 요청을 준비한다. 다운스트림 타겟은 푸시 모델에서처럼 스냅샷을 다음 타겟으로 전달한다.
## 대안
Slowly changing dimension (SDC) 모델의 예시]] SDC()를 한 방식으로 사용하는 경우가 있다.year=2015