InnoDB 스토리지 엔진 아키텍처 (3)
7. 버퍼풀
MySQL 아키텍처를 공부하면서 InnoDB 스토리지 엔진 부분이 가장 방대한 것으로 알려져 있다. 그 InnoDB 스토리지 엔진 중 가장 핵심적인 부분이 바로 '버퍼 풀(Buffer Pool)'으로 불리는 디스크의 데이터 파일이나 인덱스 정보를 메모리에 저장해두는 공간이다.
아마 이번 글이 가장 길지 않을까 싶다. 괜히 처음 접하는 어려운 개념을 내 언어로 바꿔버리면 더욱 혼동이 올 것 같아서 되도록 읽는 책의 본문 내용을 그대로 쓰고자 했다. 반복적으로 읽어가면서 나만의 언어로 풀어가는 것이 맞다고 생각하기 때문이다.
InnoDB 엔진 전체 구조
버퍼 풀(Buffer Pool)이란 MySQL InnoDB 스토리지 엔진에서 가장 핵심적인 부분으로서 디스크의 데이터 파일이나 인덱스 정보를 메모리에 캐시해두는 공간이다. 쓰기 작업을 지연시켜 일괄 작업으로 처리할 수 있게 해주는 역할도 함께 한다. 일반적으로 INSERT, UPDATE, DELETE처럼 데이터를 변경하게 만드는 쿼리(Query)는 데이터 파일의 이곳 저곳에 위치한 레코드들을 변경시키기 때문에 디스크 작업이 랜덤하게 발생한다. 하지만, 버퍼풀은 이러한 변경된 데이터를 모아서 처리함으로써 랜덤한 디스크 작업 횟수를 줄이게 된다.
7.1 버퍼풀의 크기 설정
버퍼풀이란
버퍼풀은 운영체제와 각 클라이언트 스레드가 사용할 메모리를 고려하여 설정해야 된다. MySQL 서버 내에서 메모리를 필요로 하는 것은 흔치 않지만 특별한 경우에는 레코드 버퍼가 상당한 메모리를 사용하기도 한다. 레코드 버퍼란 각 클라이언트 세션에서 테이블의 레코드를 읽고 쓸 때 버퍼로 사용하는 공간을 말하는데, 커넥션이 많고 사용하는 테이블도 많다면 레코드 버퍼 용도로 사용되는 메모리 공간이 꽤 많아질 수 있다.
MySQL 서버가 사용하는 레코드 버퍼 공간은 별도로 설정할 수 없으며, 전체 커넥션 개수와 각 커넥션에서 읽고 쓰는 테이블의 개수에 따라서 결정된다. 또한, 버퍼 공간은 동적으로 해제되기도 하므로 정확히 필요한 메모리 공간의 크기를 계산할 수 없다. 하지만, MySQL 5.7부터 InnoDB 버퍼풀의 크기를 동적으로 조절할 수 있게 되었다.
버퍼풀 공간 설정
가능하면 InnoDB 버퍼풀의 크기를 적절히 작은 값으로 설정해서 조금씩 상황을 보면서 증가시키는 방법이 효율적이다. 운영체제의 전체 메모리 공간이 8GB 미만이라면 50% 정도만 InnoDB 버퍼풀을 설정하는 것이 좋다. 나머지 공간은 서버와 운영체제, 다른 프로그램이 사용할 수 있도록 공간을 확보해주는 것이 좋기 때문이다.
InnoDB 버퍼풀은 innodb_buffer_pool_size 시스템 변수를 통해 공간 크기를 설정할 수 있으며, 동적으로 버퍼풀의 크기를 확장할 수 있다. 하지만, 버퍼풀의 크기 변경은 중대한 변경이기 때문에 가능하면 MySQL 트래픽이 적은 시점에 진행하는 것이 좋다.
또한, InnoDB 버퍼풀 증가 작업은 시스템 영향도가 크지 않지만, 감소 작업은 서비스 영향도가 매우 크기 때문에 가능하면 버퍼풀의 크기를 감소시키는 작업은 하지 않길 권장한다. 가급적 공간크기 재설정 작업을 하기 전에 MySQL 공식 문서를 참고하는걸 권한다.
[참고. MySQL 매뉴얼 - 버퍼풀 https://dev.mysql.com/doc/refman/8.0/en/innodb-buffer-pool-resize.html]
버퍼풀 인스턴스 설정
InnoDB 버퍼풀은 본래 전체를 관리하는 잠금(세마포어)으로 인해 내부 잠금 경합 문제를 많이 유발했는데, 이런 경합을 줄이기 위해 버퍼풀을 여러 개로 쪼개어 관리할 수 있도록 개선됐다. 버퍼풀이 여러 개의 작은 버퍼풀로 쪼개지면서 개별 버퍼풀 전체를 관리하는 잠금(세마포어) 자체도 경합이 분산되게 되었다.
innodb_buffer_pool_instances 시스템 변수를 이용해 버퍼풀을 여러 개로 분리해서 관리할 수 있는데, 각 버퍼풀을 버퍼풀 인스턴스라고 표현한다. 기본적으로 버퍼풀 인스턴스 개수는 8개로 초기화되지만, 전체 버퍼풀을 위한 메모리 크기가 1GB 미만이라면 버퍼풀 인스턴스는 1개만 생성된다. 버퍼풀로 할당할 수 있는 메모리 공간이 40GB 이하 수준이라면 기본값인 8을 유지하고 메모리가 크다면 버퍼풀 인스턴스당 5GB 정도가 되게 인스턴스 개수를 설정하는 것이 좋다.
7.2 버퍼풀의 구조
InnoDB 스토리지 엔진은 버퍼풀이라는 거대한 메모리 공간을 페이지 크기(innodb_page_size 시스템 변수에서 설정)의 조각으로 쪼개어 InnoDB 스토리지 엔진이 데이터를 필요로 할 때 해당 데이터 페이지를 읽어서 각 조각에 저장한다. 버퍼풀의 페이지 크기 조각을 관리하기 위해 InnoDB 스토리지 엔진은 크게 LRU(Least Recently Used) 리스트, 플러시(Flush) 리스트, 프리(Free) 리스트라는 3개의 자료 구조를 관리한다.
프리리스트와 LRU 리스트
프리리스트는 InnoDB 버퍼풀에서 실제 사용자 데이터로 채워지지 않은 비어 있는 페이지들의 목록이며, 사용자의 쿼리가 새롭게 디스크의 데이터 페이즈를 읽어와야 하는 경우 사용된다. LRU 리스트는 아래 그림과 같은 구조를 갖고 있는데, 엄밀하게는 LRU와 MRU(Most Recently Used) 리스트가 결합된 형태로 보면 된다.
Old 서브리스트 영역은 LRU에 해당하며, New 서브리스트 영역은 MRU로 이해하면 된다. LRU 리스트 목적은 디스크로부터 한 번 읽어온 페이지를 최대한 오랫동안 InnoDB 버퍼풀의 메모리에 유지해서 디스크 읽기를 최소화하는 것이다.
InnoDB 스토리지 엔진에서 데이터를 찾는 과정
1. 필요한 레코드가 저장된 데이터 페이지가 버퍼풀에 있는지 검사
1) InnoDB 어댑티브 해시 인덱스를 이용해 페이지 검색
2) 해당 테이블의 인덱스(B-Tree)를 이용해 버퍼풀에서 페이지 검색
3) 버퍼풀에 이미 데이터 페이지가 있었다면 해당 페이지의 포인터를 MRU 방향으로 승급
2. 디스크에서 필요한 데이터 페이지를 버퍼풀에 적재하고, 적재된 페이지에 대한 포인터를 LRU head에 추가
3. 버퍼풀의 LRU head 부분에 적재된 데이터 페이지가 실제로 읽히면서 MRU head 부분으로 이동
4. 버퍼풀에 상주하는 데이터 페이지는 사용자 쿼리가 얼마나 최근에 접근했었는지에 따라 나이(age)가 부여되며, 버퍼풀에 상주하는 동안 쿼리에서 오랫동안 사용되지 않으면 데이터 페이지에 부여된 나이가 오래되고, 결국 해당 페이지는 버퍼풀에서 제거된다. 버퍼풀의 데이터 페이지가 쿼리에 의해 사용되면 나이가 초기화되어 다시 젊어지고 MRU head 부분으로 옮겨진다.
5. 필요한 데이터가 자주 접근됐다면 해당 페이지의 인덱스 킬를 어댑티브 해시 인덱스에 추가
위와 같은 과정 때문에 처음 한 번 읽힌 데이터 페이지가 이후에 자주 사용된다면, 그 데이터 페이지는 InnoDB 버퍼풀 MRU 영역에서 계속 살아남게 되고, 반대로 거의 사용되지 않으면 새롭게 디스크에서 읽히는 데이터 페이지들에 밀려 LRU 끝으로 밀려나 결국 제거된다.
플러시 리스트
플러시 리스트는 디스크로 동기화되지 않은 데이터를 가진 데이터 페이지(더티 페이지)의 변경 시점 기준의 페이지 목록을 관리한다. 디스크에서 읽은 상태 그대로 전혀 변경이 없다면 플러스 리스트에 관리되지 않지만, 일단 한 번 데이터 변경이 가해진 데이터 페이지는 플러스 리스트에 관리되고 특정 시점이 되면 디스크로 기록돼야 한다. 데이터가 변경되면 InnoDB는 변경 내용을 리두 로그에 기록하고 버퍼풀의 데이터 페이지에도 변경 내용을 반영한다.
그래서, 리두 로그의 각 엔트리는 특정 데이터 페이지와 연결된다. 하지만, 리두 로그가 디스크로 기록됐다고 해서 데이터 페이지가 디스크로 기록됐다는 것을 항상 보장하진 않는다. 때때로 그 반대의 경우가 발생할 수 있는데, InnoDB 스토리지 엔진은 체크포인트를 발생시켜 디스크의 리두 로그와 데이터 페이지의 상태를 동기화하게 된다. 체크포인트는 MySQL 서버가 시작될 때 InnoDB 스토리지 엔진이 리두 로그의 어느 부분부터 복구할지 판단하는 기준점을 만드는 역할을 한다.
7.3 버퍼풀과 리두 로그
버퍼풀과 리두 로그의 관계
InnoDB 버퍼풀은 서버 메모리가 허용하는 만큼 크게 설정할수록 쿼리 성능이 빨라진다. 하지만, InnoDB 버퍼풀은 데이터베이스 서버의 성능 향상을 위해 데이터 캐시와 쓰기 버퍼링이라는 두 가지 용도가 있는데, 버퍼풀의 메모리 공간만 단순히 늘리는 것은 데이터 캐시 기능만 향상시키는 것이다. InnoDB 버퍼풀의 쓰기 버퍼링 기능까지 향상시키기 위해서는 리두 로그와의 관계를 이해해야 한다.
버퍼풀은 디스크에서 읽은 상태로 전혀 변경되지 않은 클린 페이지(Clean Page)와 함께 INSERT, UPDATE, DELETE 명령으로 변경된 더티 페이지(Dirty Page)도 갖고 있다. 더티페이지는 디스크와 메모리(버퍼풀)의 데이터 상태가 다르기 때문에 언젠가는 디스크로 기록돼야 한다. 하지만, 더티페이지는 버퍼풀에 무한정 존재하지 않는다.
InnoDB 스토리지 엔진에서 리두 로그는 1개 이상의 고정 크기 파일을 연결해서 순환 고리처럼 사용한다. 즉, 데이터 변경이 계속 발생하면 리두 로그 파일에 기록됐던 로그 엔트리는 어느 순간 다시 새로운 로그 엔트리로 덮어 쓰인다. 그래서 InnoDB 스토리지 엔진은 전체 리두 로그 파일에서 재사용 가능한 공간과 당장 재사용 불가능한 공간을 구분해서 관리해야 하는데, 재사용 불가능한 공간을 활성 리두 로그(Active Redo Log)라고 한다. 위 그림에서 화살표를 갖고 있는 엔트리들이 활성 리두 공간이다.
LSN(Log Sequece Number)
리두 로그 파일의 공간은 계속 순환되어 재사용되지만 매번 기록될 때마다 로그 포지션은 계속 증가된 값을 갖게 되는데, 이것이 바로 LSN이다. Innodb 스토리지 엔진은 주기적으로 체크포인트 이벤트를 발생시켜 리두 로그와 버퍼풀의 더티페이지를 디스크로 동기화하는데, 이렇게 발생한 체크포인트 중 가장 최근 체크포인트 지점의 LSN이 활성 리두 로그 공간의 시작점이 된다. 하지만, 활성 리두 로그 공간의 마지막은 계속해서 증가하기 때문에 체크포인트와 무관하다. 그리고, 가장 최근 체크포인트의 LSN과 마지막 리두 로그 엔트리의 LSN의 차이를 체크포인트 에이지(Checkpoint Age)라고 한다. 즉, 체크포인트 에이지는 활성 리두 로그 공간의 크기를 말한다.
1. Innodb 버퍼풀은 100GB이고, 리두 로그 파일의 전체 크기는 100MB인 경우
2. Innodb 버퍼풀은 100MB이고, 리두 로그 파일의 전체 크기는 100GB인 경우
1번의 경우, 리두 로그 파일의 크기가 100MB(명박..?)밖에 안 되기 때문에 체크포인트 에이지도 최대 100MB만 허용된다. 예를 들어, 평균 리두 로그 엔트리가 4KB였다면 25,600개(=100MB/4KB) 정도의 더티 페이지만 버퍼풀에 보관할 수 있게 된다. 결국, 버퍼풀의 크기는 매우 크지만 실제 쓰기 버퍼링을 위한 효과는 거의 없는 것이다.
2번의 경우, 위와 동일한 방식으로 계산할 수 있는데, 대략 400GB 정도의 더티페이지를 가질 수 있다. 하지만, 버퍼풀의 크기가 100MB이기 때문에 최대 허용 가능한 더티 페이지는 100MB 크기가 된다.
이런 사례처럼 극단적일 필요는 없고, 버퍼풀 크기가 100GB 이하의 MySQL 서버에서는 리두 로그 파일의 전체 크기를 대략 5~10GB 수준으로 선택하고 필요할 때마다 조금씩 늘려가면서 최적값을 선택하는 것이 효율적이다.
7.4 버퍼풀 플러시(Buffer Pool Flush)
Innodb 스토리지 엔진은 버퍼풀에서 아직 디스크로 기록되지 않은 더티 페이지들을 성능상의 악영향 없이 디스크에 동기화하기 위해 다음과 같이 플러시 리스트(flush_list)와 LRU 리스트(LRU_list) 플러시(2개) 기능을 백그라운드로 실행한다.
7.4.1 플러스 리스트 플러시
Innodb 스토리지 엔진은 리두 로그 공간의 재활용을 위해 주기적으로 오래된 리두 로그 엔트리가 사용하는 공간을 비운다. 그런데, 이때 리두 로그 공간이 지워지려면 반드시 Innodb 버퍼풀의 더티페이지가 먼저 디스크로 동기화되어야 한다. 이를 위해 Innodb 스토리지 엔진은 주기적으로 플러시 리스트(flush_list) 플러시 함수를 호출해서 플러시 리스트에서 오래 전에 변경된 데이터 페이지 순서대로 디스크에 동기화하는 작업을 수행한다. 이때 언제부터 얼마나 많은 더티페이지를 한 번에 디스크로 기록하느냐에 따라 사용자의 쿼리 처리가 악영향을 받지 않으면서 부드럽게 처리될 수 있다.
Innodb 스토리지 엔진이 제공하는 시스템 변수
- innodb_page_cleaners
- innodb_max_dirty_pages_pct_lwm
- innodb_max_dirty_pages_pct
- innodb_io_capacity
- innodb_io_capacity_max
- innodb_flush_neighbors
- innodb_adaptive_flushing
- innodb_adaptive_flushing_lwm
Innodb 스토리지 엔진에서 더티 페이지를 디스크로 동기화하는 스레드를 클리너 스레드라고 하며, innodb_page_cleaners 시스템 변수에서 클리너 스레드의 개수를 조정할 수 있다. Innodb 스토리지 엔진은 여러 개의 Innodb 버퍼풀 인스턴스를 동시에 사용할 수 있는데, innodb_page_cleaners 설정값이 버퍼풀 인스터스 개수보다 많은 경우에 innodb_buffer_pool_instances 설정값으로 자동으로 변경한다. 즉, 하나의 클리너 스레드가 하나의 버퍼풀 인스턴스를 처리하도록 자동으로 맞춰준다.
하지만, innodb_page_cleaners 시스템 변수의 설정값이 버퍼풀 인스턴스 개수보다 적은 경우에는 하나의 클리너 스레드가 여러 개의 버퍼풀 인스턴스를 처리한다. 따라서, 가능하면 innodb_page_cleaners 설정값은 innodb_buffer_pool_instances 설정값과 동일한 값으로 설정하는 것을 권한다.
Innodb 버퍼풀은 클린 페이지뿐만 아니라 사용자 DML(INSERT, UPDATE, DELETE)에 의해 변경된 더티페이지도 함께 가지고 있는데, 버퍼풀의 한계가 있기 때문에 무한정 더티페이지를 유지할 수 없다. 기본적으로 전체 버퍼풀이 가진 페이지의 90%까지 더티페이지를 가질 수 있는데, 이 값도 높을 수 있다. innodb_max_dirty_pages_pct 시스템변수 설정을 통해 더티페이지 비율을 조정할 수 있다. 일반적으로 버퍼풀은 더티페이지를 많이 가질수록 디스크 쓰기 작업을 버퍼링함으로써 여러 번 디스크 쓰기를 한 번으로 줄이는 효과를 극대화할 수 있다. 그래서 innodb_max_dirty_pages_pct 시스템 설정은 가급적 기본값을 유지하는게 좋다.
Innodb 버퍼풀에 더티페이지가 많을수록 디스크 쓰기 폭팔(Disk IO Burst) 현상이 발생할 가능성이 높다. 스토리지 엔진은 innodb_io_capacity 시스템 변수에 설정된 값을 기준으로 더티페이지 쓰기를 실행한다. 하지만, 디스크로 기록되는 더티페이지 개수보다 더 많은 더티페이지가 발생하면 버퍼풀에 더티페이지가 계속 증가하게 되고, 어느 순간 90% 비율을 넘어가면서 스토리지 엔진은 갑자기 더티페이지를 디스크에 기록해야 된다고 판단하게 된다. 이때 디스크 쓰기가 폭증하는 현상이 발생하게 된다. 이를 위해 Innodb_max_dirty_pages_pct_lwm 시스템 변수를 통해 일정 수준 이상의 더티페이지가 말생하면 조금씩 더티 페이지를 디스크로 기록하게 하고 있다.
innodb_io_capacity와 innodb_io_capacity_max 시스템 변수는 각 데이터베이스 서버에서 어느 정도의 디스크를 읽고 쓰기가 가능한지를 설정하는 값이다. innodb_io_capacity는 일반적인 상황에서 디스크가 적절히 처리할 수 있는 수준의 값을 설정하며, innodb_io_capacity_max 시스템 변수는 디스크가 최대 성능을 발휘할 때 어느 정도 디스크 읽고 쓰기가 가능한지를 설정한다. 이때 디스크 읽고 쓰기란 스토리니 엔진의 백그라운드 스레드가 수행하는 디스크 작업을 의미하는데, 대부분 버퍼풀의 더티페이지 쓰기에 해당한다.
관리할 MySQL 서버가 많다면 서버 트래픽을 모니터링하면서 일일이 설정하기 번거롭다. 그래서 어댑디트 플러시 기능을 제공하는데, innodb_adaptive_flushing 시스템변수로 기능을 on/off할 수 있는데, 기본값은 on이다. 어댑티브 플러시 기능이 활성화(on)되면, 스토리지 엔진은 단순히 버퍼풀의 더티페이지 비율이나 시스템 설정값에 의존하지 않고 새로운 알고리즘을 사용한다.
innodb_flush_neighbors 시스템 변수는 더티페이지를 디스크에 기록할 때 디스크에 근접한 페이지 중에서 더티 페이지가 있다면 스토리지 엔진이 함께 묶어서 디스크로 기록하게 해주는 기능을 활성화할지 여부를 설정한다.
7.4.2 LRU 리스트 플러시
Innodb 스토리지 엔진은 LRU 리스트에서 사용 빈도가 낮은 데이터 페이지들을 제거해서 새로운 페이지들을 읽어올 공간을 만들어야 하는데, 이를 위해 LRU 리스트(LRU_list) 플러시 함수가 사용된다. 스토리지 엔진은 LRU 리스트의 끝부분부터 시작해서 최대 innodb_lru_scan_depth 시스템 변수에 설정된 개수만큼의 페이지들을 스캔한다.
Innodb 스토리지 엔진은 이때 스캔하면서 더티페이지는 디스크에 동기화하게 하며, 클린 페이지는 즉시 프리(free) 리스트로 페이지를 옮긴다. Innodb 스토리지 엔진은 innodb 버퍼풀 인스턴스별로 최대 innodb_lru_scan_depth 개수만큼 스캔하기 때문에 실질적인 LRU 리스트의 스캔은 'innodb_buffer_pool_instances * innodb_lru_scan_depth' 수만큼 수행하게 된다.
7.5 버퍼풀 상태 백업 및 복구
Innodb 서버의 버퍼풀은 쿼리 성능에 밀접한 영향을 미친다. 디스크 데이터가 버퍼풀에 미리 적재돼 있는 상태를 워밍업 상태라고 하는데, 이 경우 쿼리 처리 속도가 매우 빠른 것이 일반적이다. 그래서, MySQL 5.5 버전에서는 점검을 위해 서버를 셧다운 했다가 다시 시작하는 경우 서비스를 오픈하기 전에 강제 워밍업을 위해 주요 테이블과 인덱스에 대해 풀 스캔을 한 번씩 실행하고 서비스를 오픈했었다.
그러나, MySQL 5.6 버전부터는 버퍼 풀 덤프 및 적재 기능이 도입되었다. 서버 점검이나 기타 작업을 위해 MySQL 서버를 재시작해야 하는 경우 서버를 셧다운하기 전에 다음과 같이 innodb_buffer_pool_dump_now 시스템 변수를 이용해 현재 Innodb 버퍼풀의 상태를 백업할 수 있다. 그리고, 서버를 다시 시작하면 innodb_buffer_pool_load_now 시스템 변수를 이용해 백업된 버퍼풀의 상태를 다시 복구할 수 있다.
-- MySQL서버 셧다운 전, 버퍼풀 상태 백업
mysql> SET GLOBAL innodb_buffer_pool_dump_now=ON;
-- MySQL서버 재시작 후, 백업된 버퍼풀 상태 복구
mysql> SET GLOBAL innodb_buffer_pool_load_now=ON;
Innodb 버퍼풀의 백업은 데이터 디렉토리에 ib_buffer_pool이라는 이름의 파일로 생성되는데, 아무리 파일이 크더라도 몇 십 MB 이하인 것을 확인할 수 있다. 이는 스토리지 엔진이 버퍼풀의 LRU 리스트에서 적재된 데이터 페이지의 메타 정보만 가져와서 저장하기 때문이다.
mysql> SHOW STATUS LIKE 'Innodb_buffer_pool_dump_status'\G
버퍼풀 적재작업이 너무 오래 걸려서 중간에 멈추고 싶으면, Innodb_buffer_pool_load_abort 시스템 변수를 이용하면 된다.
mysql> SET GLOBAL innodb_buffer_pool_load_abort=ON;
만약, MySQL 서버가 시작되면 자동으로 백업된 버퍼풀의 상태를 복구하도록 하고 싶다면, innodb_buffer_pool_dump_at_shutdown과 innodb_buffer_pool_load_at_startup 설정을 MySQL 서버 설정 파일에 넣어두면 된다.
7.6 버퍼풀의 적재 내용 확인
MySQL 5.6 버전부터는 서버의 information_schema 데이터베이스의 innodb_buffer_page 테이블을 이용해 Innodb 버퍼풀 메모리에 어떤 테이블의 페이지들이 적재돼 있는지 확인할 수 있었다. 하지만, 버퍼풀이 큰 경우에는 이 테이블 조회가 상당히 큰 부하를 일으키면서 서비스 쿼리가 많이 느려지는 문제가 있었다. 그래서 실제 서비스용으로 사용되는 MySQL 서버에서는 버퍼풀의 상태를 확인하는 것이 거의 불가능했다.
MySQL 8.0 버전에서는 이런 문제점 해결을 위해 information_schema 데이터베이스에 innodb_cached_indexes 테이블이 새로 추가됐다. 이 테이블을 사용하면 테이블의 인덱스별로 데이터 페이지가 얼마나 Innodb 버퍼풀에 적재돼 있는지 확인할 수 있다.
아직 MySQL 서버는 개별 인덱스별로 전체 페이지 개수가 몇 개인지는 사용자에게 알려주지 않기 때문에 information_schema 테이블을 이용해도 테이블의 인덱스별로 페이지가 innodb 버퍼풀에 적재된 비율은 확인할 수 없다.
출처: ⌜Real MySQL 8.0 (개발자와 DBA를 위한 MySQL 실전 가이드)⌟, 백은빈, 이성욱 지음, 위키북스, 2021.09.08 출간
'Data Engineering > MySQL' 카테고리의 다른 글
[Query] JOIN 쿼리문의 이해 (국제표준 ANSI 조인 기준) (0) | 2022.11.12 |
---|---|
[ MySQL 아키텍처 ] 2. InnoDB 스토리지 엔진 아키텍처 (2) (0) | 2022.10.05 |
[ MySQL 아키텍처 ] 2. InnoDB 스토리지 엔진 아키텍처 (1) (0) | 2022.10.05 |
[ MySQL 아키텍처 ] 1. MySQL 엔진 아키텍처 (3) (0) | 2022.10.05 |
[ MySQL 아키텍처 ] 1. MySQL 엔진 아키텍처 (2) (2) | 2022.10.04 |