1) InnoDB 버퍼 풀
- InnoDB 스토리지 엔진에서 가장 핵심적인 부분으로,
디스크의 데이터 파일이나 인덱스 정보를 메모리에 캐시해 두는 공간이다.
쓰기 작업을 지연시켜 일괄 작업으로 처리할 수 있게 해주는 버퍼 역할도 같이 한다.
- 일반적인 애플리케이션에서는 INSERT, UPDATE ,DELETE처럼 데이터를 변경하는 쿼리는
데이터 파일의 이곳저곳에 위치한 레코드를 변경하기 때문에 랜덤한 디스크 작업을 발생시킨다.
하지만 버퍼 풀이 이러한 변경된 데이터를 모아서 처리하면 랜덤한 디스크 작업의 횟수를 줄일 수 있다.
2) 버퍼 풀의 크기 설정
- 일반적으로 전체 물리 메모리의 80% 정도를 InnoDB의 버퍼 풀로 설정하라는 내용의 게시물도 있는데,
그렇게 단순하게 설정해서 되는 값은 아니며,
운영체제와 각 클라이언트 스레드가 사용할 메모리도 충분히 고려해서 설정해야 한다.
- MySQL 서버 내에서 메모리를 필요로 하는 부분은 크게 없지만
아주 독특한 경우 레코드 버퍼가 상당한 메모리를 사용하기도 한다.
레코드 버퍼는 각 클라이언트 세션에서 테이블의 레코드를 읽고 쓸 때 버퍼로 사용하는 공간을 말하는데,
커넥션이 많고 사용하는 테이블도 많다면
레코드 버퍼 용도로 사용되는 메모리 공간이 꽤 많이 필요해질 수도 있다.
- MySQL 서버가 사용하는 레코드 버퍼 공간은 별도로 설정할 수 없ㅇ며,
전체 커넥션 개수와 각 커넥션에서 읽고 쓰는 테이블의 개수에 따라서 결정된다.
또한 이 버퍼 공간을 동적으로 해제되기도 하므로 정확히 필요한 메모리 공간의 크기를 계산할 수가 없다.
(2-1) innodb_buffer_pool_size 시스템 변수
- InnoDB 버퍼 풀은 innodb_buffer_pool_size 시스템 변수로 크기를 설정할 수 있으며,
동적으로 버퍼 풀의 크기를 확장할 수 있다.
하지만 버퍼 풀의 크기 변경은 크리티컬한 변경이므로
가능하면 MySQL 서버가 한가한 시점을 골라서 진행하는 것이 좋다.
- 또한 InnoDB 버퍼 풀을 더 크게 변경하는 작업은 시스템 영향도가 크지 않지만,
버퍼 풀의 크기를 줄이는 작업은 하지 않도록 주의하자.
- InnoDB 버퍼 풀은 내부적으로 128MB 청크 단위로 쪼개어 관리되는데,
이는 버퍼 풀의 크기를 줄이거나 늘리기 위한 단위 크기로 사용된다.
그래서 버퍼 풀의 크기를 줄이거나 늘릴 때는 128MB 단위로 처리된다.
(2-2) innodb 버퍼 풀과 세마포어
- InnoDB 버퍼 풀은 전통적으로 버퍼 풀 전체를 관리하는 잠금(세마포어)으로 인해
내부 잠금 경합을 많이 유발해왔는데,
이런 경합을 줄이기 위해 버퍼 풀을 여러 개로 쪼개어 관리할 수 있게 개선됐다.
- 버퍼 풀이 여러 개의 작은 버퍼 풀로 쪼개지면서 개별 버퍼 풀 전체를 관리하는 잠금(세마포어) 자체도
경합이 분산되는 효과를 내게 되는 것이다.
innodb_buffer_pool_instances 시스템 변수를 이용해 버퍼 풀을 여러 개로 분리해서 관리할 수 있는데,
각 버퍼 풀을 버퍼 풀 인스턴스라고 표현한다.
- 기본적으로 버퍼 풀 인스턴스의 개수는 8개로 초기화되지만,
전체 버퍼 풀을 위한 메모리 크기가 1GB미만이면 버퍼 풀 인스턴스는 1개만 생성된다.
버퍼 풀로 할당할 수 있는 메모리 공간이 40GB 이하 수준이라면 기본값인 8을 유지하고,
메모리가 크다면 버퍼 풀 인스턴스당 5GB 정도가 되게 인스턴스 개수를 설정하는 것이 좋다.
3) 버퍼 풀의 구조
-
InnoDB 스토리지 엔진은 버퍼 풀이라는 거대한 메모리 공간을
페이지 크기(innodb_page_size 시스템 변수에 설정된)의 조각으로 쪼개어
InnoDB 스토리지 엔진이 데이터를 필요로 할 때 해당 데이터 페이지를 읽어서 각 조각에 저장한다.
- 버퍼 풀의 페이지 크기 조각을 관리하기 위해 InnoDB 스토리지 엔진은
크게 LRU 리스트와 플러시 리스트, 그리고 프리 리스트라는 3개의 자료 구조를 관리한다.
- 프리 리스트는 InnoDB 버퍼 풀에서 실제 사용자 데이터로 채워지지 않은 비어 있는 페이지들의 목록이며,
사용자의 쿼리가 새롭게 디스크의 데이터 페이지를 읽어와야 하는 경우 사용된다.
- LRU 리스트는 엄밀하게 LRU와 MRU 리스트가 결합된 형태라고 보면된다.
LRU 리스트를 관리하는 목적은 디스크로부터 한 번 읽어온 페이지를
최대한 오랫동안 InnoDB 버퍼 풀의 메모리에 유지해서 디스크 읽기를 최소화하는 것이다.
'Real MySQL 1권' 카테고리의 다른 글
[Real MySQL 1권] REPETABLE READ & SERIALIZABLE (0) | 2024.12.19 |
---|---|
[Real MySQL 1권] MySQL의 격리 수준 - READ UNCOMMITTED, READ COMMITTED (0) | 2024.12.18 |
[Real MySQL 1권] MVCC (0) | 2024.12.12 |
[Real MySQL 1권] 클러스터링 인덱스 (0) | 2024.08.25 |
[Real MySQL 1권] 인덱스와 잠금 (0) | 2024.06.28 |