CUBRID도 OS나 다른 DBMS와 같이 성능상의 이유로 페이지(page) 단위 디스크 I/O를 수행한다.
가상 메모리를 사용하는 최소 크기 단위이다.
가상 메모리란?
프로세스는 독립된 메모리 공간(=partition)을 가지고 있고, 서로의 메모리 공간에 접근할 수 없다. 운영체제는 사용자가 많은 프로세스로 메모리를 한계 이상 쓰려고 할 때 디스크 공간을 메모리처럼 사용하여 비록 느리지만 돌아는가게 만들었다. 이렇게 운영체제가 디스크에서 메모리처럼 사용하고자 올린 파일을 paging(swap) file이라고 한다. 이 페이징 파일은 디스크에 올라가기 때문에 다른 프로세스들도 사용할 수 있는 특이한 가상메모리가 된다.
우리의 운영체제는 페이징 파일을 실제 물리 메모리에 올리고 내리면서 여러 프로세스를 운용한다. 고로 사용자 입장에서는 마치 사용할 수 있는 메모리의 크기가 증가한 것 처럼 보인다.
한정된 물리 메모리의 한계를 극복하고자 디스크와 같은 느린 저장장치를 활용해, 애플리케이션들이 더 많은 메모리를 활용할 수 있게 해 주는 것이 가상 메모리이다.
만약, 페이징 파일에서 물리 메모리로 데이터를 로드할 때, 아무 위치에나 필요한 크기 만큼(무작위) 로드한다고 가정을 해보자.
이런 경우, 로드하고 언로드하는 데이터의 크기가 모두 제각각이므로, 이를 반복하다 보면 메모리 공간에 fragmentation(프로세스가 필요한 양보다 더 큰 메모리가 할당되어서 메모리가 낭비되거나 중간중간에 생긴 사용하지 않는 메모리가 많이 존재해서 총 메모리 공간은 충분하지만 실제로 할당할 수 없는 상황)이 발생하게 된다.
이를 막기 위해, 운영체제가 만든 것이 page라는 최소 크기 단위인 것이다.
Demanding-page는 실제로 필요한 page만 물리 메모리로 가져오는 방식이다. 이 과정에서 필요 page에 접근하려 하면, 결국 가상 메모리 주소에 대응하는 물리 메모리 주소를 찾아내어, 물리 메모리 주소를 얻어와 하는데, 이 때 필요한 것이 페이지 테이블(page table)이다. 페이지 테이블에 valid bit 라는 것을 두고, 해당 page가 물리 메모리에 있으면 set, 그렇지 않으면 invalid로 설정한다.
CUBRID 페이지 크기는 최소 4KB ~ 최대 16KB 이며, 디폴트로 16KB 디스크 페이지 크기를 사용한다.
슬랏 페이지 구조란 이런 페이지에 데이터 저장을 구조화하는 하나의 방식을 말한다.
새로운 값이 삽입되면 레코드는 페이지의 앞 부분부터 차례대로 할당되고, 슬롯(slot)은 페이지의 끝부터 역방향으로 할당된다. 하나의 레코드는 레코드 헤더(header), 고정 길이 컬럼들(Fix Col), 가변 길이 컬럼들(Var Col)로 이루어져 있다.
레코드에 가변 길이 컬럼이 존재함으로 UPDATE시 레코드의 크기가 달라진다.
UPDATE할 레코드가 기존 크기보다 작으면 해당 위치에 데이터를 UPDATE하면 되지만, 기존 크기보다 크면 같은 페이지 내에서 UPDATE할 레코드를 할당하고, 기존 slot은 UPDATE할 레코드를 가리킨다.
하지만 같은 페이지 내에서 새로운 레코드에 대해 UPDATE할 공간이 없다면 아래 그림처럼 별도의 페이지를 할당하고 기존의 레코드는 새 레코드를 가리킨다.
UPDATE할 레코드의 크기가 한 페이지보다 크면 다음 그림처럼 데이터를 페이지 단위로 나누어 저장하고, 이전 데이터가 저장되었던 페이지는 갱신된 데이터를 저장한 페이지를 가리킨다.
이 경우 데이터를 쓸 때에는 데이터를 페이지 단위로 쪼개야 하고, 읽을 때에는 쪼개진 페이지들을 일련의 메모리 상에 로드해야 하며, 이는 성능을 저하시킬 수 있다.
LRU(Least-Recently Used)
한정된 크기의 버퍼를 효율적으로 사용하기 위해, 가장 최근에 사용한 데이터만 유지하고 오랫동안 사용하지 않은 데이터는 디스크에서 내린 후 그 공간을 해제(free)한다. STEAL 정책에서 사용하는 메모리 관리 방식이다.
STEAL 정책 : 수정된 페이지를 언제든지 디스크에 쓸 수 있는 정책, STEAL 정책은 수정된 페이지가 어떠한 시점에도 디스크에 써질 수 있기 때문에 필연적으로 UNDO 로깅과 복구를 수반하는데, 거의 모든 DBMS가 채택하는 버퍼 관리 정책이다.
본 시리즈의 글들은 CUBRID DB엔진 오픈 스터디를 진행하며 팀원들과 함께 공부한 내용을 정리한 것입니다.
Github 링크
Page 발표 내용