
InnoDB 스토리지 엔진은 버퍼 풀이라는 거대한 메모리 공간을 페이지 크기(innodb_page_size 시스템 변수에 설정된)의 조각으로 쪼개어 InnoDB 스토리지 엔진이 데이터를 필요로 할 때 해당 데이터 페이지를 읽어서 각 조각에 저장합니다.
버퍼 풀의 페이지 크기 조각을 관리하기 위해 크게 LRU(Least Recently Used) 리스트와 플러시(Flush) 리스트, 프리(Free) 리스트라는 3개의 자료 구조를 관리합니다.
프리(Free) 리스트
프리 리스트는 버퍼 풀에서 실제 사용자 데이터로 채워지지 않은 비어 있는 페이지들의 목록입니다.
사용자의 쿼리가 새롭게 디스크의 데이터 페이지를 읽어와야 하는 경우 사용됩니다.
LRU(Least Recently Used) 리스트

엄밀하게 LRU와 MRU(Most Recently Used) 리스트가 결합된 형태라고 보면 됩니다.
Old 서브리스트 영역은 LRU에 해당하며, New 서브리스트 영역은 MRU로 이해하면 됩니다.
LRU 리스트를 관리하는 목적은 디스크로부터 한 번에 읽어온 페이지를 최대한 오랫동안 버퍼 풀의 메모리에 유지해서 디스크 읽기를 최소화하는 것입니다.
InnoDB 스토리지 엔진에서 데이터를 찾는 과정을 대략 다음과 같습니다.
1. 필요한 레코드가 저장된 데이터 페이지가 버퍼 풀에 있는지 검사
1-1. InnoDB 어댑티브 해시 인덱스를 이용해 페이지 검색
1-2. 해당 테이블의 인덱스(B-Tree)를 이용해 버퍼 풀에서 페이지를 검색
1-3. 버퍼 풀에 이미 데이터 페이지가 있었다면 해당 페이지의 포인터를 MRU 방향으로 승급
2. 디스크에서 필요한 데이터 페이지를 버퍼 풀에 적재하고, 적재된 페이지에 대한 포인터를 LRU 헤더 부분에 추가
3. 버퍼 풀의 LRU 헤더 부분에 적재된 데이터 페이지가 실제로 읽히면 MRU 헤더 부분으로 이동
(Read Ahead와 같은 대량 읽기의 경우 디스크의 데이터 페이지가 버퍼 풀로 적재는 되지만
실제 쿼리에서 사용되지는 않을 수도 있으며, 이런 경우에는 MRU로 이동되지 않음)
4. 버퍼 풀에 상주하는 데이터 페이지는 사용자 쿼리가 얼마나 최근에 접근했었는지에 따라 나이(Age)가 부여되며, 버퍼 풀에 상주하는 동안 쿼리에서 오랫동안 사용되지 않으면 데이터 페이지에 부여된 나이가 오래되고('Aging'이라고 함) 결국 해당 페이지는 버퍼 풀에서 제거된다. 버퍼 풀의 데이터 페이지가 쿼리에 의해 사용되면 나이가 초기화 되어 다시 젊어지고 MRU의 헤더 부분으로 옮겨진다.
5. 필요한 데이터가 자주 접근됐다면 해당 페이지의 인덱스 키를 어댑티브 해시 인덱스에 추가
플러시(Flush) 리스트
플러시(Flush) : 버퍼 풀 데이터 페이지의 변경 사항을 디스크에 기록하는 행위
플러시 리스트는 디스크로 동기화되지 않은 데이터를 가진 데이터 페이지(더티 페이지)의 변경 시점 기준의 페이지 목록을 관리합니다. 디스크에서 읽은 상태 그대로 전혀 변경이 없다면(이때의 페이지를 '클린 페이지'라고 합니다) 플러시 리스트에서 관리되지 않지만, 일단 한 번 데이터 변경이 가해진 데이터 페이지는 플러시 리스트에 관리되고 특정 시점이 되면 디스크로 기록돼야 합니다. 데이터가 변경되면 InnoDB는 변경 내용을 리두 로그에 기록하고 버퍼 풀의 데이터 페이지에도 변경 내용을 반영합니다. 그래서 리두 로그의 각 엔트리는 특정 데이터 페이지와 연결됩니다.
하지만 리두 로그가 디스크로 기록됐다고 해서 데이터 페이지가 디스크로 기록됐다는 것을 항상 보장하지는 않습니다. 때로는 그 반대의 경우도 발생할 수 있는데, InnoDB 스토리지 엔진은 체크포인트를 발생시켜 디스크의 리두 로그와 데이터 페이지의 상태를 동기화하게 됩니다.
체크포인트는 MySQL 서버가 시작될 때 InnoDB 스토리지 엔진이 리두 로그의 어느 부분부터 복구를 실행해야 할지 판단하는 기준점을 만드는 역할을 합니다.
참고.
- (도서) Real MySQL 8.0
'📁 Database > MySQL & MariaDB' 카테고리의 다른 글
| [MariaDB] MHA 구성(Part 3. MHA 설정) (0) | 2024.07.29 |
|---|---|
| [MariaDB] MHA 구성(Part 1. MariaDB 10.11.8 설치) (0) | 2024.07.26 |
| [MySQL] InnoDB 스토리지 엔진 아키텍처 (0) | 2024.07.10 |
| [MySQL] MySQL 아키텍처 : Replication(복제) (0) | 2024.07.10 |
| [MySQL] [MY-011825] [InnoDB] Cannot add field ... which is greater than maximum allowed size (8126) 해결법 (0) | 2024.05.31 |