1회: 메인 메모리 DBMS의 등장 배경과
개요
2회: 메인 메모리 DBMS 기술
3회: 메인 메모리 DBMS의 안정성과
이중화 4회: 메인 메모리 DBMS 현황 및 전망
데이터베이스를 활용하고자 하는 근본적인 목적은 데이터를
체계적으로 관리하고 응용 프로그램을 보다 쉽게 개발하며 어떠한
상황에서도 데이터를 안전하게 관리하기 위함이다. 특히 통신
시스템이나 다수의 가입자를 관리하는 인터넷 서비스 시스템 등과 같은
분야는 고속의 데이터 처리가 필수적이기 때문에 데이터베이스의 처리
성능을 필요로 한다. 최근 이들 시스템은 메인 메모리 DBMS를
활용함으로써 데이터의 안정성과 데이터 고속 처리의 일석이조 효과를
거두고 있다.
일반적으로 DBMS는 데이터베이스의 안정성을 보장하기 위해 데이터
변경에 대한 로깅을 수행한다. 로깅(Logging)이란 발생하는 데이터의
삽입/삭제/변경을 디스크와 같이 안전한 저장 장치(stable storage)에
실시간으로 기록함으로써, 장애 발생시 이를 활용하여 최종의
데이터베이스 상태로 되돌리기 위한 DBMS의 기본 기능이다. 또한 앞서
언급한 것처럼 고성능 시스템에 적용되는 메인 메모리 DBMS는 어떠한
장애 상황에서도 중단 없는 서비스를 보장해야 하는데, 이를 충족시키기
위해 데이터베이스 이중화 기능을 제공하고 있다. 이번 호에서는 메인
메모리 DBMS가 지원하는 데이터베이스의 안정성과 이중화에 관하여
살펴보기로 한다.
데이터베이스의 지속성
데이터베이스 관리 시스템(DBMS)에서 지속성(durability)의 개념은
트랜잭션 처리에서 중요한 ACID(Atomic, Consistency, Isolation,
Durability) 성질 중 하나로, 트랜잭션이 성공적으로 완료되면(COMMIT),
어떠한 시스템 오류에도 트랜잭션 처리 결과는 데이터베이스에 반영됨을
보장해야 한다"로 정의할 수 있다.
일반적으로 DBMS는 트랜잭션 처리 중 발생하는 데이터베이스의 상태
변화에 대한 내용을 로그로 남기며, 이 로그를 안전한 저장
장치(일반적으로 디스크)에 저장한다. 로그는 데이터베이스의 상태
변경에 대한 기록으로, 이를 기반으로 redo 또는 undo를 수행하여
데이터베이스 상태를 일관성 있게 유지할 수 있도록 지원한다.
지속성의 보장은 안전한 저장 매체의 사용과 엄밀한 데이터베이스
상태의 변경 절차가 필요하다. 단순한 방법으로 모든 트랜잭션의 변경
내역을 디스크의 로그 파일에 기록하면 되지만, 이 경우 트랜잭션 내의
각 연산마다 디스크 I/O를 수반하게 되어 성능이 매우 떨어지게 된다.
또한 보다 효율적인 처리를 위해 커밋 시점으로 디스크 I/O를 연기하게
되면 성능상의 이점은 얻을 수 있으나, 메모리와 디스크 간의 용량
불일치로 인한 부작용이 발생하여 데이터베이스 상태의 일관성을
보장하기 어려운 점이 있다. 따라서, 데이터베이스 상태의 일관성을
보장하기 위해서는 일정한 상태 변경 절차가 요구되어진다. 이 때 상태
변경 절차는 데이터베이스의 변경과 로그 기록 간의 순서를 엄격히
적용하는 것으로 정의되는데, 일반적으로 데이터베이스 상태의 일관성은
WAL(Write-Ahead Log) 프로토콜과 Force-log-at-commit 규칙을 통해
보장된다.
? WAL 프로토콜: 완료되지 않은 트랜잭션의 변경
내용이 디스크에 저장될 경우 부작용을 제거하기 위해, 로그를 먼저
디스크에 저장하고 DB 페이지를 디스크에 저장하는 절차
? Force-log-at-commit 규칙: 트랜잭션 로그가 디스크에 기록된 후 커밋
결과를 리턴함으로써 커밋된 트랜잭션의 변경 결과에 대한 지속성을
보장하는 규칙
데이터베이스의 상태는 디스크에 존재하는 DB(PV:Persistent page
Version), 메모리 버퍼에 존재하는 DB(VV: Volatile page Version),
디스크에 존재하는 로그(DL:Durable Log)와 메모리에 존재하는
로그(VL:Volatile Log)에 의해 결정된다. 이러한 계층이 발생하는
이유는 디스크 I/O 속도와 메모리 접근 속도 측면에서 큰 차이가 있기
때문이다. 디스크는 지속적(durable)으로 데이터를 저장할 수 있지만
상대적으로 속도가 느리며, 메모리는 상대적으로 속도가 빠른 반면
휘발성의 특성이 있다. 즉, DBMS의 지속적인 속성과 성능 사이에
발생하는 trade-off의 격차를 좁히기 위해, 디스크 기반 DBMS는 메모리
버퍼에 데이터베이스의 일부분을 매핑하고, 메모리 기반 DBMS는
데이터베이스 전체를 매핑하며, 로그 버퍼를 활용해 로그를 안전하고
지속성있게 기록하는 정책을 선택한다.
<그림 1> 특정 시점의 데이터베이스 상태를 결정하는 요소
이러한 저장매체의 계층화로 트랜잭션 처리 중에 VV와 PV, VL과 DL
사이에 불일치가 발생할 수 있다(<그림 1>참조). 디스크 기반
DBMS에서 VV와 PV 사이의 불일치는 주기적인 체크포인트와 메모리 버퍼
페이지 교체 시점에 부분적으로 일치된다. 반면, 메모리 기반 DBMS는
체크 포인트 시점에만 일치된다. 또한, 정상적인 상황에서 VL과 DL
사이의 불일치는 성능 우선 정책에 의해 VL 기록과 DL 기록 사이의
의도적인 지연을 통해 발생한다.
데이터베이스 상태의 일관성이 깨지는 현상은 저장매체 간의 순간적인
불일치가 발생하는 경우 이외에 데이터베이스 상태 변경과 로그 기록
절차에 의해서도 발생한다. 이 상황은 메모리-디스크 동기화
메커니즘(페이지 교체, 체크포인트)에 의해 발생하게 되는데,
일반적으로 성능상의 이유 때문에 동기화는 페이지 단위로 발생한다.
즉, 현재 진행중인 트랜잭션의 상태 변경이 포함된 페이지가 디스크로
내려갈 수 있게 된다. 이 후, DBMS가 다운되는 상황이 발생되면, DL에
해당 트랜잭션의 변경 로그가 기록되어 있는지의 여부에 따라 DBMS의
재가동 시점에서 데이터베이스의 일관성이 결정된다. 또한, 트랜잭션
처리 중 데이터베이스 변경과 로그 기록의 절차가 지켜지지 않으면, 즉,
데이터베이스가 먼저 변경되고 로그를 기록하기 전에 에러가 발생한
경우 트랜잭션을 롤백할 수 있는 방법이 없게 되어 온라인 시점에서
일관성이 위배될 수 있다.
성능과 안정성 모두 보장
메인 메모리 DBMS의 성능이 좋은 이유는 의외로 간단하다.
데이터베이스 전체를 물리적인 메모리에 모두 상주시키기 때문이다.
이로써 ‘메모리 상주형 DBMS’라고도 불리우는데, 보다 정확한
표현이라고 할 수 있겠다. 메인 메모리 DBMS가 응용 프로그램에서
요구하는 데이터를 메모리에서 직접 읽어 보내 주므로 빠른 성능을
보장하는 건 지극히 당연해 보인다. 그런데 우리가 흔히 말하는 메인
메모리는 속성상 전원 공급이 차단되면 저장 내용을 잃어버리는
휘발성(volatile)을 갖고 있어서 컴퓨터 시스템의 전원이 차단되거나
OS의 운영이 멈춘다면, 메모리에 상주하고 있던 데이터베이스는 모두
지워지게 될 것이다.
이를 해결하기 위해 메인 메모리 DBMS도 디스크 기반 DBMS와 동일하게
데이터의 변경이 발생할 때 마다 디스크와 같이 안전한 저장 장치에
실시간으로 로깅한다. 데이터베이스의 안전성을 위해 실시간으로
로깅해야 한다면, 디스크의 I/O 성능 때문에 메인 메모리 DBMS의 성능을
빠르게 한다는 것은 어불성설이 아닌가? 데이터베이스의 성능과
안정성이란 두 마리 토끼를 동시에 좇아야 하는 메인 메모리 DBMS의
고충이 여기에 있는 것이다.
말 그대로 메인 메모리 DBMS라 함은 모든 데이터베이스가 메모리에
상주하고 디스크 I/O는 전혀 발생하지 않는 환경이어야 한다. 컴퓨터
시스템의 모든 메모리가 비휘발성(non-volatile)의 속성을 지니면 되는
것이다. 그러면 정전이 발생하더라도 데이터베이스와 로깅 정보는
메모리에 그대로 남이 있을 테니, DBMS를 재가동하여 메모리에 남아
있는 데이터베이스와 로깅 정보를 이용하여 회복(recovery) 절차만을
수행해 주면 되기 때문이다. 그러나 위와 같은 환경은 특수 분야에
사용되는 컴퓨터를 제외하고는 일반적인 환경에서는 구현하기 어려운
것이 현실이다. 우리가 쉽게 접하는 컴퓨터 시스템은 대부분 휘발성
메모리를 장착하고 있고, 메인 메모리 DBMS는 일반적인 컴퓨터
시스템에서 주로 활용되기 때문이다.
때문에 적어도 로깅만큼은 비휘발성 메모리에 해야만 메인 메모리
DBMS의 성능이 보장될 수 있다고 주장했던 시기도 있었다. 그래서
썬마이크로시스템즈에서는 NVSIMM이라는 비휘발성 메모리 모듈을
장착하여 사용할 수 있도록 한 경우도 있었으나, 이제 대부분의 컴퓨터
시스템 벤더들은 이러한 특수 아키텍처를 갖는 시스템의 공급을
중단하였다. 메인 메모리 DBMS로서는 더욱 더 상황이 좋지않게 된
것이다.
안정성 보장을 위한 메인 메모리 DBMS의 노력
그럼에도 불구하고 메인 메모리 DBMS가 데이터베이스의 변경 정보를
디스크에 실시간으로 로깅하면서도 디스크 기반 DBMS보다 빠른 성능을
구현할 수 있는 것은 기본적으로 메모리 DB(VV)와 디스크 DB(PV) 간에는
1:1 매핑 관계를 갖기 때문이다. 즉, 메인 메모리 DBMS는 디스크 기반
DBMS에서처럼 메모리 버퍼에 대한 페이지 교체는 발생하지 않으므로,
체크포인트 시점에만 메모리와 디스크간의 DB 동기화가 발생하게 된다.
이것은 디스크 기반 DBMS에 비해 로그 버퍼가 강제적으로 디스크에
flush되는 상황이 보다 적게 발생하게 되어 디스크 I/O 횟수가 줄어드는
효과가 있다. 또 다른 이유는 구현 알고리즘 관점에서도 메모리 버퍼
교체 알고리즘이 고려되지 않아도 되고 체크포인트 알고리즘에서만 로그
버퍼의 flush를 수행하는 것으로 WAL 프로토콜을 구현한다는 것이다.
그러나 이것만으로는 실시간 로깅에 따른 디스크 I/O의 느린 성능을
뛰어 넘어 원하는 성능을 낼 수 없으므로, 보다 적합한 로깅 방법을
제공해야만 한다.
우선 로깅 정보를 최대한으로 줄여 디스크 I/O 양과 횟수에 따르는 성능
저하 현상을 최소화하는 방법이 있다. 실제로 데이터 변경이 발생하면
이에 수반되는 로깅 정보는 변경된 데이터 양보다 많게 된다. 로깅
정보를 수록하는 단위를 로그 레코드라고 하는데, 이 로그 레코드는
변경된 데이터뿐만 아니라 장애 발생 시 데이터를 회복하기 위한 여러
가지 정보를 함께 포함하게 된다. 이 로그 레코드를 가능하면 작게
가져가고 심한 경우에는 압축하여 저장하는 메인 메모리 DBMS도 있다.
물론 로그 레코드를 압축하는데 비용이 수반되지만, 그 비용이 디스크
I/O 비용을 상쇄하고도 남는 것이라면 이것도 좋은 방법 중의
하나이다.
또 다른 방법으로는 로깅하는 메커니즘 자체를 새롭게 개발하는 것이다.
예를 들어 여러 트랜잭션에 의해 동시에 많은 로그 레코드들이 생성될
경우 병렬로 로깅(parallel logging)하는 것이다. 디스크에 여러 개의
I/O 채널이 존재한다면, 로그 파일을 각각 다른 채널에 할당된 파일
시스템에 생성하고 여기에 로그 레코드를 병렬로 저장하는 것이다. 이
방법은 로그 정보를 저장하는 것도 데이터베이스를 회복할 때에도 매우
세심한 작업이 요구되며, 다채널의 디스크 시스템을 구비한 환경에서만
실효성을 거둘 수 있다는 단점을 갖고 있다. 그 만큼 완벽하고 성능이
좋은 메인 메모리 DBMS를 제공하기란 여간 어려운 일이
아니다.
다양한 지속성 레벨을 통한 데이터의 안정성
메인 메모리 DBMS는 빠른 트랜잭션 특성을 최대한 살리면서
데이터베이스의 지속성도 보장해야만 한다. 그러나, 지속성과 성능을
동시에 보장하기란 결코 쉬운 일이 아니다. 지속성을 보장하기 위해서는
디스크 I/O 가 수반되어야 하는데, 성능을 얻기 위해서는 디스크 I/O를
최소화 하는 것이 요구되기 때문이다. 이러한 문제 때문에 요즘
선보이고 있는 메인 메모리 DBMS는 응용 시스템 환경에 맞게 트랜잭션의
지속성을 다양하게 제공함으로써 응용 시스템의 고성능을 실현하고
있다.
첫째, 디스크에 로깅하지 않는 방법이다. 이는 초기 데이터베이스
상태의 일관성을 보장하는 방법으로, 디스크 I/O를 가급적 수행하지
않음으로써 데이터베이스의 처리 성능을 최대화하는 것이다. 즉, DBMS
운영 중 데이터베이스 변경은 메모리에서만 일어나고 이 변경 내용을
디스크의 데이터베이스 파일에 전혀 기록하지 않는 것이다. 또한 로그
정보도 로그 버퍼에만 기록하고 디스크로 flush하지 않는다. 로그
파일을 기록하지도 않으면서 로그 버퍼를 운영하는 이유는 적어도
실패한 트랜잭션에 대해서는 롤백을 수행하여 DBMS를 운영할 때만이라도
데이터베이스의 일관성을 유지하기 위함이다. 이러한 종류의 트랜잭션
지속성을 지원하는 경우에는 DBMS를 재가동할 때에는 최종 상태의
데이터베이스를 필요로 하지 않고 항상 초기 데이터베이스를 가지고
운영해도 무방한 환경에서 유용하다. 또한 디스크가 없는(diskless)
컴퓨터 시스템에서도 유용한 방법이 되겠다. 이 경우에는 시스템 구동
시 네트워크를 통해서 원격 서버에 저장된 초기 데이터베이스를
로딩하는 형태로 운영할 수 있다.
<그림 2> 초기 데이터베이스 상태의 일관성 보장
둘째, 로그를 지속성 있게 유지하는 책임을 OS에 일임하는 방법이다.
이는 로그 파일을 Memory-mapped File(mmap)로 구성하여 로그를
기록하는 방법으로, 다음의 두 가지 측면에서 이점을 얻을 수 있다.
? 트랜잭션은 로그 기록에 의한 실질적인 디스크
I/O를 기다리지 않고 사용자에게 결과를 리턴함으로써, 성능상의 이점을
얻고 디스크 I/O의 병목현상으로부터 어느 정도 해방되는 이점이
있다.
? 로그를 지속성 있게 유지하는 책임을 OS에게 일임함으로써, OS의
유연한 스케줄링에 의해 디스크 I/O를 지연 분산시키는 효과와 동시에
DBMS 서버만 다운되는 경우, mmap 파일에 대한 변경이 커널 메모리에
유지되는 특성을 통해 OS가 sync를 책임지므로 지속성이 보장되는
상황이 확대되는 이점이 있다.
이는 H/W 고장, 정전과 같은 다운 상황이 발생할 확률이 매우 적다는
가정 하에서 제공하는 방법으로서, 실제 이와 같은 장애가 발생하면
데이터베이스가 깨지는 경우가 일반 디스크 기반 DBMS에서도 발생할 수
있는 현상이므로 실질적으로 사용하는데 큰 무리가 없을 것이다. 장애
발생 시 백업본을 활용하여 데이터베이스를 복구하는 것은 모든 DBMS의
일반적인 방법이다.
<그림 3> 일반적 장애에 대한 데이터베이스 일관성 보장
이상으로 메인 메모리 DBMS가 데이터베이스의 지속성을 유지하기 위한
다양한 방법들을 살펴 보았다. 위의 방법들은 데이터베이스의 지속성
수준과 성능 간의 상반된 관계로 인하여 다양하게 제공하는 것이지만,
어느 방법을 사용하여도 디스크 기반 DBMS 보다 좋은 성능을 나타내고
있다는 점을 강조한다. 따라서 사용자는 각자의 응용 환경에 적합한
지속성 레벨을 선택하여 사용함으로써 보다 고성능 발휘하는 응용
시스템을 개발할 수 있을 것이다.
데이터베이스 이중화
실시간 데이터베이스 응용 시스템 분야나 Mission-Critical 응용
시스템을 다루는 산업 분야에서는 데이터의 성능이나 일관성보다
시스템의 가용성에 보다 무게를 두는 경우가 많다. 시스템의 예기치
못한 오류로 인하여 데이터베이스 서비스가 중단되는 경우 치명적인
경제적 손실이나 시스템 내부 데이터의 불일치성을 유발할 수 있기
때문이다. 따라서 이러한 응용의 경우 시스템의 고가용성(high
availability)과 안정성이 필수적인 기능이라 할 수 있겠다.
고가용성을 보장하기 위해 기존의 디스크 기반 DBMS는 데이터베이스를
공유하는 클러스터 구조(database clustering)를 지원하며, 메인 메모리
DBMS는 데이터베이스 이중화(database replication) 기법을 제공한다.
클러스터 구조의 데이터베이스는 디스크를 공유할 수 있기에 가능한
구조로, 메인 메모리는 일반적으로 서버 노드 간에 공유가 불가능하기
때문에 메인 메모리 DBMS는 데이터베이스를 동일하게 복제하여 유지하는
이중화 방법을 채택하는 것이다. 데이터베이스 이중화는
오류-극복(fail-over) 구조에서 가용성을 증가시키는 기본적인 방법으로
사용되어 왔으며, 또한 원격지 서버의 접속 필요성을 줄임으로 인해
성능을 향상시킬 수 있는 방법으로도 제공되어 왔다.
전형적인 분산 데이터베이스 환경에서 데이터베이스 이중화 기법은
데이터 변경 내용의 전달 방법에 따라 “lazy”와 “eager” 기법으로
구분되며, 변경 주체 즉, 데이터의 소유자에 따라 그룹 또는 마스터
방식으로 구분된다. “eager” 기법은 한 객체에 대한 변경 내용이 그
트랜잭션의 일부로 인식되어 수행된다. 즉, 트랜잭션 수행 중 발생한
변경은, 발생 즉시 모든 이중화 서버로 전달되어 연쇄적으로 변경내용이
반영되는 기법이다. 반면 “lazy” 기법은 트랜잭션의 수행이 완전히
완료된 후에, 그 변경 사실에 대한 새로운 트랜잭션을 작성하여 각
노드에게 전달하는 기법으로, 각각의 노드 별로 또 다른 새로운
트랜잭션이 수행되어 지는 것으로 간주된다. <표 1>은 변경
내용의 전달방식에 따른 두 기법을 비교한 것이다.
<표 1> 변경 내용 전달 기법에 따른 비교
또한, 객체의 소유권 및 변경의 주체에 따라서 그룹 기법과 마스터
기법으로 구분할 수 있다. 즉, 객체를 변경을 할 수 있는 노드가
결정되어 있어서, 그 노드에서만 객체를 변경할 수 있고, 그 변경
내용을 다른 모든 노드에게 전달하는 마스터 기법 방식과 임의의 노드가
임의의 객체를 변경할 수 있으며, 그 변경사실을 모든 노드에게
전달하는 그룹 기법 방식이 있다. 따라서, 그룹 기법에서는 아무 노드나
객체를 변경하고, 변경 사실에 대한 갱신 트랜잭션을 발생할 수 있으나,
마스터 기법에서는 주 사본(primary copy)을 소유한 노드에서만 그
사본에 대한 변경이 가능하고, 그 변경 내용을 전달할 수 있다. 주
사본이 아닌 복사본을 소유하고 있는 모든 원격 서버들은 그 사본
객체에 대해서 판독연산만 가능하다. 이러한 객체 변경 소유권에 따른
기법의 비교는 <표 2>와 같다.
<표 2> 객체 변경 소유권에 따른 기법 비교
변경 내용 전달 방식과 객체 변경 소유권의 기준에 따라 상용
시스템들의 데이터베이스 이중화 기법들을 <표 3>과 같이 분류할
수 있다.
<표 3> 이중화 기법들의 분류
데이터베이스 이중화 구성 방법
데이터베이스 이중화 기법으로는 주-대기(Active-Standby) 위상과
활동-활동(Active-Active) 위상이 있는데, 최근에는 활동-활동 위상에
대한 요구가 크게 증가하고 있다. 이에 따라 동시성 제어 및 트랜잭션
관리 기술이 빠르게 발전하고 있다.
서버 구성에 따라 데이터베이스 이중화를 위한 통신 모델은 다음의 네
가지로 구분된다. 주-대기 서버 이중화 모델은 데이터베이스 이중화뿐만
아니라 분산 시스템의 전형적인 이중화 모델로서, 정상적인 운영
모드에서 주 서버는 일반적인 데이터베이스 서비스를 제공하는 것처럼
보이지만, 실제로 자신의 변경 내용을 대기 서버로 전달하고 있으며,
대기 서버는 데이터베이스 서비스는 하지 않은 채, 전달 받은 내용을
자신의 데이터베이스에 반영하게 된다. 주 서버에 오류가 발생하면, 주
서버의 서비스를 받던 응용들을 대기 서버로 옮겨 대기 서버에서 새로운
서비스를 시작하게 된다. 주 서버의 오류가 복구 되면 그 동안의 대기
서버의 변경 트랜잭션을 주 서버에 보내 이중화 작업을 계속 수행한다.
그 후, 양 서버의 역할을 바꾸어 계속 수행하거나, 주 서버와 대기
서버의 역할을 바꾸어 수행하기도 한다.
활동-활동 서버 이중화 모델은 응용 업무를 분리하여 처리하거나 부하
분산을 위해 주로 사용된다. 변경된 데이터 갱신 내용을 서로 상대편
서버에 이중화하는 작업을 수행하고, 응용에서 발생하는 트랜잭션을 두
그룹으로 분리하여 각각의 서버에서 수행하게 한다. 이후 변경
트랜잭션을 교환, 양 서버의 데이터 변경 내용을 일치시켜 상호
이중화하는 방식이다.
주-다중(Active-Multistandby) 대기 이중화 모델은 성능에 민감하고
높은 가용성을 요구하는 응용에 적합한 모델로서, 하나의 주 서버와 두
개 이상의 대기 서버로 구성된다. 주-대기 서버와 기본적으로 동일한
구성을 갖지만, 대기 서버 수가 많다는 점에서 시스템의 가용성을 더욱
높일 수 있다. 이 구조는 높은 고가용성을 얻을 수 있어, 크리티컬한
응용 시스템에 적합한 모델이지만 비용이 많이 든다는 단점이
있다.
다중 대기 서버에 변경 트랜잭션을 전달하기 위해 소요되는 주 서버의
오버헤드를 절감시키기 위해, <그림 5>의 (라)와 같은 전용 변경
전달 서버(propagator)를 운영하여 주-다중 대기 서버 모델을 운영할 수
있다.
<그림 5> 메모리 DB 이중화 구성 모델
이중화 데이터의 싱크 방법
앞에서도 살펴본 바와 같이 분산 데이터베이스 시스템에서 사용하는
2단계 완료 기법이나 3단계 완료 기법을 통하여 이중화 데이터를 완전
동기화(synchronous) 하는 방식은 성능 향상을 주목적으로 하는 메인
메모리 DBMS에서는 부적합하다. 따라서 메인 메모리 DBMS는
비동기(Asynchronous)로 데이터베이스를 이중화함으로써 이중화 중에도
데이터베이스의 성능 저하를 최소화 하고 있다. 그러나 비동기로
데이터베이스를 이중화하여 운영할 때 장애가 발생하면 장애 서버가
복구될 때까지 최종의 상태에서 데이터베이스를 운영하는 것이 어렵게
된다. 이러한 문제를 해결하기 위해 메인 메모리 DBMS는 여러 레벨의
지속성을 지원하는 것처럼 이중화 데이터의 동기화 레벨도 다양하게
지원함으로써, 사용자가 응용 특성에 맞게 선택적으로 사용할 수 있도록
하는 것이 바람직하다. 로그를 기반으로 이중화하는 방법에 있어서 이들
동기화 방법들에 관하여 살펴보도록 한다.
<그림 6> 이중화 싱크 방법
첫째, 완전 비동기 방식으로 로컬 서버(DBMS)는 원격 서버의 반영
여부와 상관없이 로그 내용을 원격 서버에 전송하는 방식이다<그림
6의 (가) 참조>. 비동기 이중화 방법 중 가장 성능이 좋은
방법이지만, 로컬 서버의 장애 발생 시 로컬 서버에서 처리된 모든
트랜잭션의 결과가 원격 서버에 전달되지 않을 수도 있다는 단점이
있다. 그러나 로컬 서버가 복구되면 전송하지 못한 변경 내용을 원격
서버에 보낼 수 있으므로 장애 복구 후에는 이중화 데이터베이스가
일치하게 된다. 이것은 원격 서버가 자신의 데이터베이스에 전송 받은
변경 내용을 어디까지 반영하였는지를 로컬 서버가 알고 있기 때문이다.
이는 원격 서버의 DB 반영후 act를 받기 때문에 가능하다.
둘째, 이중화할 로그 내용을 원격 서버에 전송되었음을 확인하고 지역
서버의 트랜잭션을 종료(commit)하는 방식이다<그림 6의 (나)
참조>. (가) 방법의 단점을 보완하기 위한 방법으로서, 트랜잭션을
커밋하기 전에 데이터 변경 정보를 원격 서버에 전달하였음을 확인하고
커밋하는 방식이다. 이 방식은 로컬 서버에 장애가 발생하였을 때
적어도 로컬 서버에서 처리된 모든 트랜잭션의 결과를 원격 서버에
전송하였음을 보장함으로써, 원격 서버는 로컬 서버의 최종
데이터베이스 상태를 유지하면서 서비스할 수 있다는 장점이 있다. 단,
원격 서버가 로컬 서버로부터 전송 받은 데이터 변경 내용을 자신의
데이터베이스에 반영하지 못하고 장애가 발생한 경우에는 원격 서버의
복구 후에나 이중화 데이터베이스가 일치함을 보장한다.
셋째, 로컬 서버에서 전송한 로그가 원격 서버에 반영되었음을 확인하고
로컬 트랜잭션을 종료하는 방식이다<그림 6의 (다) 참조>. 이
방식은 어떤 형태의 장애가 발생하더라도 장애 발생 시점에서 이중화
데이터베이스가 일치함을 보장한다. 다만, 이중화 성능이 좋지 않다는
단점이 있다.
이중화 데이터의 충돌 해결
데이터베이스 이중화는 물리적으로 서로 다른 두 데이터가 서로 같은
값을 유지하여야 하지만, 이러한 이중화 데이터의 동기화 작업 동안에
트랜잭션 수행 오류가 발생하거나, 의미적으로 불일치 데이터를
유발하는 트랜잭션이 수행되는 경우, 이중화 데이터에 대한 데이터
충돌(data conflict)이 발생하게 된다. 특히, 이중화 구성 모델 중에서
활동-활동 구조인 경우에는, 두 서버가 동등한 데이터베이스 서비스를
제공하므로, 서로 다른 두 응용에서 동일한 객체에 대해 동시에 갱신
작업을 시도하는 경우 데이터 충돌이 더욱 빈번하게 발생하게 된다.
일반적으로 분산 데이터베이스 시스템에서 사용하는 2단계 완료
기법이나 3단계 완료 기법을 통하여 데이터 충돌에 대한 데이터
일치성을 보장할 수 있으나, 지연된 변경 처리를 사용하는 데이터베이스
이중화 기법에서는 이러한 데이터 충돌을 해결하기 어렵다. <그림
7>은 두 개의 활동 서버로 구성되는 이중화 모델에서 데이터 충돌이
발생하여 불일치한 데이터베이스 상태가 유발되는 예를 보이고
있다.
<그림 7> 데이터베이스 이중화의 데이터 충돌
<그림 7>에서 "balance"의 현재 값은 100이며, 응용 1은 이 값에
100을 추가하는 트랜잭션, 응용 2는 이 값에 200을 추가하는 트랜잭션을
각각의 두 서버에서 동시에 수행하게 된다. 이 때, 두 객체에 대한 분산
병행수행 제어 방법을 적용하지 않고서는 데이터 충돌 즉, 전역적인
데이터 불일치 상태를 피하기 어렵다. 그러나 2단계 완료와 같은 기존
분산 병행 수행 제어 방법은 실시간 트랜잭션 처리를 보장할 수
없으므로, 메인 메모리 DBMS에 적용할 수 없다. 즉, 데이터의 분산
처리보다는 데이터의 이중화가 주된 목적이고 또한 예측가능하고 빠른
트랜잭션의 처리가 가능해야 하므로, 완벽한 일치성을 보장하는 분산
데이터베이스 처리 방법을 적용하기보다는 효율적인 트랜잭션 처리를
지원하면서 동시에 올바른 데이터를 유지할 수 있는 이중화 객체 충돌
해결 방법이 필요하다.
메인 메모리 DBMS는 이중화 객체의 데이터 충돌을 방지하기 위해서 추적
감사(audit) 기능을 제공한다. 이중화 객체를 다루는 서버간의 데이터를
테이블 단위로 비교, 검사하여 불일치 정보를 조사하고, 제공되는
사용자 일치 정책에 따라 두 데이터의 내용을 일치시키는 기능을
제공한다. 데이터 충돌을 해결하는 방법은 타임스탬프(timestamp)
방법과 값 기반(value based) 방법이 있다. 타임스탬프 방법은 데이터
충돌이 발생했을 때 최종에 변경된 값으로 유지하는 방법이다. 이
방법은 각 레코드 마다 시간을 기록할 수 있는 필드가 필요하며 이중화
서버 시스템 간에 시간을 동기화 하는 것이 어렵다는 문제점이 있다.
한편 값기반 방식은 마스터-종속(master-slave) 서버로 구분하여 데이터
충돌이 발생하면 마스터 서버의 값으로 데이터를 유지하는
방식이다.
값 기반 데이터 충돌 해결 방법은 한 서버를 마스터 서버로 선정하고,
나머지 서버들을 종속 서버로 설정한다. 이 때 다음 <표 5>와
같은 불일치 레코드가 발생한다.
<표 5> 이중화 서버간의 데이터 불일치 상황
위와 같은 불일치 상황에 따라, 추적 감사 기능을 사용하여 마스터
데이터베이스를 기준으로 종속 데이터베이스를 일치시키는 방법을
사용한다. 따라서, 위와 같은 불일치 상황에서 다음 <표 6>과
같은 일치 정책(synchronization policy)을 사용한다.
<표 6>의 기본 정책에 따라 추적 감사 기능이 수행되어, 이중화
객체에 대한 데이터 불일치 현상을 방지할 수 있다. 즉, 이중화 객체에
대하여 변경 트랜잭션이 작업되는 동안 항상 추적 감사 프로그램이 전역
데이터베이스의 상태를 감시하여 일관된 전역 데이터베이스 상태가
유지되도록 한다. 또한 추적 감사 스크립트는 사용자가 설정 가능하도록
되어 있어, 응용 시스템의 상황에 맞게 일치 정책을 변경할 수
있다.
<표 6> 이중화 객체 불일치 해결을 위한 일치 정책
이중화 데이터의 충돌 해결 방법으로 타임스탬프 방식 또는 값 기반
방식 중 어느 것이 더바람직하다고 단정지어 말하기는 곤란하다. 응용
환경에 따라 타임스탬프 방식 또는 값 기반 방식이 더 적합할 수도 있기
때문이다. 따라서 이들 두 가지 방식을 모두 지원하여 사용자가 필요에
따라 선택하여 사용할 수 있다면 가장 이상적이라 할 수 있겠다.
지금까지 메인 메모리 DBMS의 안정성과 데이터베이스 이중화 방법에
관한 방법들을 살펴 보았다. 메모리에 데이터베이스를 전체를
상주시켜야 하고 성능을 저하시키는 디스크 I/O를 극복해야 한다는
명제를 안고 있는 메인 메모리 DBMS는 이러한 문제를 모두 해결하고
있다. 데이터베이스의 일관성 유지와 가용성을 위한 이중화를
지원함으로써, 고성능과 중요 업무 영역에 이미 메인 메모리 DBMS가
다양하게 적용되고 있음을 주시해야 할 것이다.
|