들어가며
데이터베이스의 데이터는 디스크로부터 메모리에 할당되어서 읽힌 다음 수정을 하기도 하고, 새로이 생성되어 메모리에 할당되는 데이터가 있다. 이러한 데이터는 결과적으로는 디스크에 저장되어야 영구적으로 저장됨을 보장할 수 있다. 이 글에서는 큐브리드에서 데이터를 디스크에 저장하는 방법 중 하나를 소개하여서 큐브리드 제품에 대한 이해를 돕고자 한다.
현재 글을 쓰는 시점의 버전은 11.2이다.
Double Write Buffer
Double Write Buffer의 정의, 목적, 매커니즘을 거쳐 모듈에 대해 전반적인 설명을 하고자 한다.
Double Write Buffer 란?
큐브리드는 기본적으로 Double Write Buffer를 통해서 디스크에 데이터를 저장한다. Double Write Buffer는 메모리와 디스크 양쪽에 구성되어 있는 버퍼영역이다. 기본적으로 2M의 크기로 설정되어 있으며, cubrid.conf 파일 내에서 그 크기를 32M까지 조절 할 수 있다.
Note
큐브리드에서는 Double Write Buffer를 사용해서 DB페이지를 디스크에 저장하는 방법과 DB 페이지를 바로 디스크에 저장하는 방법이 있다. 이번 글에서는 Double Write Buffer를 사용해서 저장하는 방법만 언급하도록 하겠다.
Double Write Buffer 의 목적
이렇게 생성된 Double Write Buffer는 디스크에 데이터를 저장할때, DB페이지가 깨져서 저장되는 경우를 막을 수 있다. DB페이지가 깨지는 것은 다음의 이유 때문이다.
이 문서에서 메모리에 존재하는 한 개의 DB페이지는 리눅스 혹은 윈도우의 OS페이지 4개로 이루어져있다고 가정해서 설명한다. 이러한 DB페이지는 디스크에 저장될 때, flush라는 매커니즘을 거쳐서 저장된다.
Flush 매커니즘을 통해서 디스크에 저장될 때 DB페이지는 OS페이지 단위로 나뉘어져 저장되는데, 위 그림과 같이 디스크에 DB페이지의 저장이 완료되지 않았을 때 시스템의 갑작스러운 종료가 일어나면 해당 DB페이지는 깨진 상태가 된다.
Note 이러한 디스크 쓰기를 Partial Write라고 부른다.
Double Write Buffer에 데이터가 저장되는 과정
큐브리드의 DB페이지는 Double Write Buffer를 거쳐 다음과 같이 디스크에 저장된다.
위와 같이, 4개의 OS페이지로 구성된 1개의 DB페이지가 메모리 내 Double Write Buffer에 저장된다. 그 이후, DB 내부 Double Write Buffer에 한 번 그리고 DB파일에 두 번 이렇게 저장된다.
메모리 내 Double Write Buffer에서 저장되는 과정은 다음과 같이 자세하게 설명 할 수 있다.
- DB 페이지는 메모리의 Double Write Buffer안에 있는 하나의 slot에 저장되고, 이러한 slot이 모여 Block이 된다.(아래 그림의 초록색 네모가 하나의 Block)
- 이러한 연속된 Block들을 메모리 내 Double Write Buffer이라고 부른다.
- 하나의 Block이 slot으로 가득차게 되면 flush라는 매커니즘을 통해 디스크에 저장이되고, 이러한 flush는 Block 단위로 진행된다.
DB페이지가 메모리 내 Double Write Buffer로부터 디스크에 있는 DB로의 저장되는 과정은 다음과 같이 두 과정을 순서대로 실행한다.
- slot으로 가득찬 단일 Block을 DB 내부 Double Write Buffer에 저장
- 단일 Block내 저장된 page와 동일한 위치에 있는 디스크에 page저장
DB 내부 Double Write Buffer에 저장이 실패했을 때
이 경우에는 깨진 데이터를 Disk에 저장하는 것을 막기 위해 서버를 재구동하거나 Double Write Buffer를 새로 만드는 과정에서 큐브리드 서버가 중지 되어서 아직 디스크에 쓰이지 않는 데이터들이 쓰여진다.
디스크 내부 DB에 데이터 저장이 실패했을 때
DB 내부에 저장된 Double Write Buffer를 메모리에 할당 시킨뒤, Block 내부에 있는 page와 DB 내부에 저장된 page를 비교한다. DB영역에서 깨진 DB페이지에 대해서만 다시 flush를 진행시켜서 DB페이지가 깨진 상태로 디스크에 저장되는 것을 방지한다.
DB에 DB페이지가 성공적으로 저장되었을 때
DB 내부에 있는 Double Write Buffer는 그대로 유지되고, 다음 Block이 flush를 통해서 디스크에 DB페이지가 저장될 때 덮어씌워진다. 즉, Double Write Buffer는 계속 유지된다.
마치며
위와 같은 과정을 거쳐서 Double Write Buffer를 사용한 DB페이지가 성공적으로 저장되고, 깨진 DB페이지가 저장되는 것을 막을 수 있다.
참고자료
- CUBRID Manual - https://www.cubrid.org/manual/en/11.0/
- CUBRID Source Code - https://github.com/CUBRID/cubrid