SELECT
: reads tuple from pagesINSERT
/ DELETE
/ UPDATE
: write records in pagesHIT
이라 하며, 디스크에서 페이지를 읽어오지 않고 DRAM에 저장된 페이지를 반환하는 DRAM operation이다.MISS
라 하며, Disk I/O가 발생한다. 디스크에서 페이지를 읽어와 DRAM에 저장한 후 반환해야 한다.메모리의 단위는 프레임(frame)이고, 한 프레임이 한 page를 가지고 있다는 맥락으로 이해할 수 있다. 그래서 디스크의 page가 메모리에 올라오면 free frame에 할당해야 한다. 만약 모든 프레임이 사용중이라면 빈 프레임을 확보해야 할 것이고, 이 작업을
victim frame selection
이라고 한다.
그래서 프레임에 있는 페이지가 dirty 상태라면 디스크에 변경된 내역을 저장하는 것이고, dirty 상태가 아니라면 프레임 clear()하면 되는 것이다.
Free List
: 바로 사용이 가능한 페이지 프레임, 즉 free(empty) buffer frames를 모아 둔 리스트.
LRU List
: 버퍼 풀에 존재하는 모든 페이지를 저장하는 리스트. 가장 오랫동안 사용되지 않은(least recently used
) 페이지를 tail에 유지한다.
Flush List
: 버퍼 풀에 존재하는 모든 dirty page를 가지고 있는 리스트. LSN 순서에 맞게 가장 오랫동안 수정되지 않은(least recently modified
) 페이지를 head에 유지한다.
DBMS에서 어떠한 데이터를 읽거나, 변경하거나, 삭제 혹은 추가하기 위해서는 해당 정보가 반드시 메모리, 즉 MySQL InnoDB 기준으로 'buffer pool'이라는 장소에 올라와 있어야 한다. 하지만 버퍼 풀은 유한하다. 물리적 메모리의 frame이기 때문에 DBMS가 컨트롤하고자 하는 모든 데이터베이스의 데이터를 버퍼 풀에 올릴 수 없는 것. 그러므로 위와 같은 세 개의 List를 두고, 메모리의 frame을 관리하는 방식을 사용한다.
// buf0buf.h
struct buf_pool_t {
...
UT_LIST_BASE_NODE_T(buf_page_t) flush_list;
UT_LIST_BASE_NODE_T(buf_page_t) free;
UT_LIST_BASE_NODE_T(buf_page_t) LRU;
...
위 헤더 파일을 보면 자세한 구조는 확인할 수 없지만, 버퍼 풀이 앞서 설명한 세 가지 리스트로 구성되어 있음을 알 수 있다. 그리고 NODE라는 표현으로 미루어 볼 때, 실제로 Linked_List
형태로 각자 프레임의 정보를 가지고 있다는 사실을 알 수 있을 것이다.
mysql-5.7.33/storage/innobase/buf에서 innoDB의 buffer manager 관련 코드를 확인할 수 있다.