8.9.1 InnoDB 버퍼 풀
InnoDB
는 데이터 및 인덱스를 메모리에 캐시하는 버퍼 풀 라는 저장 공간을 유지하고 있습니다. InnoDB
버퍼 풀의 구조를 알고 자주 액세스되는 데이터를 메모리에 유지하기 위해 그것을 이용하는 것은 MySQL 튜닝의 중요한 측면이다.
지침
이상적으로는 버퍼 풀의 크기를 최대한 크게 설정하여 서버에서 다른 프로세스가 과도한 페이징없이 실행하도록 충분한 메모리를 떠난다. 버퍼 풀이 클수록 InnoDB
는 또한 인 메모리 데이터베이스처럼 작동하여 디스크에서 한번 데이터를 읽기 후속 읽기시 메모리에서 데이터에 액세스합니다. 성능 향상을 위해 디스크 쓰기를 그룹화 할 수 있도록 버퍼 풀은 삽입 및 업데이트 작업에 의해 변경된 데이터를 캐시합니다.
시스템의 일반적인 워크로드에 따라 버퍼 풀의 각 부분의 비율을 조정하는 것이 좋은 경우가 있습니다. 버퍼 풀이 가득 될 때 캐시 블록을 선택하는 방법을 조정하고 백업 및 보고서 등의 작업 활동이 급증하고 자주 사용되는 데이터를 메모리에 저장할 수 있습니다.
큰 메모리 크기를 갖춘 64 비트 시스템에서 버퍼 풀을 여러 부분으로 분할하여 동시 작업중인 메모리 구조의 충돌을 최소화 할 수 있습니다. 자세한 내용은 섹션 14.13.1.4 "다중 버퍼 풀 인스턴스 사용" 을 참조하십시오.
내부 정보
InnoDB
는 LRU (Least Recently Used) 알고리즘의 변형을 사용하여 풀을 목록으로 관리합니다. 수영장에 새로운 블록을 추가하기 위해 여유가 필요한 경우, InnoDB
는 최근 가장 사용되지 않은 블록을 제거하고 새로운 블록을 목록 중간에 추가합니다. 이 "미드 포인트 삽입 전략 '은 목록 2 개의 하위 목록으로 처리합니다.
선두는 최근에 액세스 된 "새로운"(또는 "젊은") 블록의 하위 목록입니다.
끝은 최근 많이 사용되지 않는 "이전"블록의 하위 목록입니다.
이 알고리즘은 쿼리에서 자주 사용되는 블록을 새 하위 목록에 유지합니다. 이전 하위 목록은별로 사용되지 않는 블록을 포함하고이 블록은 새우 조치 의 대상이됩니다.
LRU 알고리즘은 기본적으로 다음과 같이 작동합니다.
버퍼 풀의 3/8가 이전 하위 목록에 할당됩니다.
목록의 미드 포인트는 새 하위 목록의 끝에와 이전 하위리스트의 선두가 접하는 경계입니다.
InnoDB
가 블록을 버퍼 풀에 가져 오면 먼저 그것을 미드 포인트 (이전 하위 목록의 맨)에 삽입합니다. 블록을 읽을 수있는 것은, SQL 쿼리 등의 사용자 지정 작업과InnoDB
에 의해 자동으로 실행되는 예측 작업의 일환으로 필요하기 때문입니다.이전 하위 목록의 블록에 액세스하면 그것이 "젊은"입니다 버퍼 풀의 선두 (새 하위 목록의 맨)으로 이동됩니다. 블록이 필요하기 때문에 읽은 경우 첫 번째 접근은 즉시 이루어 블록이 젊고됩니다. 예측을 위해 블록을 읽은 경우 첫 번째 접근은 즉시되지 않습니다 (블록이 제거 될 때까지 전혀되지 않는 경우도 있습니다).
데이터베이스가 작동하면 액세스되지 않은 버퍼 풀의 블록이 목록의 끝으로 이동됨에 따라 "오래된"입니다. 새 하위 목록 및 이전 하위 목록의 두 블록은 다른 블록이 새로 설정할 때 오래입니다. 이전 하위 목록의 블록은 블록이 미드 포인트에 삽입 된 경우도 오래입니다. 마지막으로, 오랫동안 사용되지 않은 채 블록은 이전 하위 목록의 끝에 도달 삭제됩니다.
기본적으로 쿼리에서 읽은 블록은 즉시 새 하위 목록으로 이동되어 그들이 장시간 버퍼 풀에 체재하는 것을 의미합니다. 테이블 스캔 (mysqldump 조작 또는 WHERE
절이없는 SELECT
문에서 실행되는 것과 같은)에 의해 대량의 데이터가 버퍼 풀에 흡수되어 새로운 데이터가 다시 사용될 수없는 경우에도 동일한 양의 오래된 데이터가 삭제 될 수 있습니다. 마찬가지로, 예측 백그라운드 스레드에 의해로드 된 후 한 번만 액세스 된 블록은 새로운 목록의 맨 위로 이동됩니다. 이런 상황에서 자주 사용되는 블록이 이전 하위 목록에 밀려 거기서 그들이 새우 션 대상이 될 수 있습니다.
구성 옵션
일부 InnoDB
시스템 변수에서 버퍼 풀의 크기를 제어하고 LRU 알고리즘을 조정할 수 있습니다.
innodb_buffer_pool_size
버퍼 풀의 크기를 지정합니다. 버퍼 풀이 작고, 충분한 메모리가있는 경우, 풀을 크게하면 쿼리가
InnoDB
테이블에 액세스 할 때 필요한 디스크 I / O의 양이 감소하여 성능을 향상시킬 수 있습니다.innodb_buffer_pool_instances
버퍼 풀을 자체 LRU리스트 및 관련 데이터 구조를 가지는 사용자 지정 수의 개별 영역으로 분할하여 동시 메모리 읽기 및 쓰기 작업 중에 충돌을 줄일 수 있습니다. 이 옵션은
innodb_buffer_pool_size
를 1G 바이트 이상의 크기로 설정 한 경우에만 사용할 수 있습니다. 지정한 총 크기는 모든 버퍼 풀 사이에 분할됩니다. 최고의 효율을 얻기 위해서는innodb_buffer_pool_instances
과innodb_buffer_pool_size
의 조합을 각 버퍼 풀 인스턴스가 적어도 1G 바이트가되도록 지정합니다.innodb_old_blocks_pct
InnoDB
가 오래된 블록 하위 목록에 사용하는 버퍼 풀의 대략적인 비율을 지정합니다. 값의 범위는 5 ~ 95입니다. 기본값은 37 (즉, 수영장 3/8)입니다.innodb_old_blocks_time
이전 하위 목록에 삽입 된 블록이 첫 방문 후 새 하위 목록으로 이동하기까지, 거기 체재해야하는 시간을 밀리 초 (ms) 단위로 지정합니다. 기본값은 0입니다. 삽입 후 얼마나 액세스가 발생하는지에 관계없이 이전 하위 목록에 삽입 된 블록은 Innodb 버퍼 풀에서 삽입 된 블록의 페이지 1/4을 제거 할 때 새 하위 목록 로 이동됩니다. 이 값이 0보다 크면 블록은 첫 번째 액세스 후 적어도 그 밀리 세컨드로 액세스가 발생할 때까지 이전 하위 목록에 남아 있습니다. 예를 들어, 1000 값은 블록을 첫 번째 액세스 후 그들이 새 하위 목록으로 이동되는 자격을 얻을 때까지 1 초 이전 하위 목록에 남아 있습니다.
innodb_old_blocks_time
을 0보다 크게 설정하면 1 번 테이블 스캔으로 스캔 만 사용 된 블록에서 새 하위 목록이 가득 찰 것을 방지합니다. 스캔에서 읽을 블록의 행은 빠르게 연속해서 여러 번 사용되지만 다음 블록은 사용되지 않습니다. innodb_old_blocks_time
이 블록을 처리하는 것보다 긴 시간의 값으로 설정되어 있으면, 블록은 "이전"하위 목록에 남아 목록의 끝에까지 빨라지므로 즉시 삭제됩니다. 이렇게하면 한 번의 스캔으로 만 사용되는 블록이 새 하위 목록에서 자주 사용되는 블록의 손실을 촉진하지 않습니다.
innodb_old_blocks_time
는 실행시에 설정할 수 있기 때문에 테이블 스캔이나 덤프 등의 작업을 수행하는 동안 그것을 일시적으로 변경할 수 있습니다.
SET GLOBAL innodb_old_blocks_time = 1000;
... perform queries that scan tables ...
SET GLOBAL innodb_old_blocks_time = 0;
목적이 테이블의 내용을 버퍼 풀에 들어가서 버퍼 풀을 "준비"하는 것입니다 경우,이 전략은 적용되지 않습니다. 예를 들어, 정상적인 사용 기간 후 데이터는 일반적으로 버퍼 풀에 있기 때문에 벤치 마크 테스트에서는 종종 서버를 시작할 때 테이블 또는 인덱스 스캔을 실행합니다. 이 경우 적어도 워밍업 단계가 완료 될 때까지 innodb_old_blocks_time
을 0으로 설정된 상태로 있습니다.
버퍼 풀의 모니터링
InnoDB 표준 모니터의 출력은 BUFFER POOL AND MEMORY
섹션에 버퍼 풀 LRU 알고리즘의 조작에 속하는 몇 가지 필드가 포함되어 있습니다.
Old database pages
: 버퍼 풀의 이전 하위 목록의 페이지 수입니다.Pages made young, not young
: 버퍼 풀의 선두 (새 하위 목록)로 이동 된 오래된 페이지 수와 새로워지는 않고 이전 하위 목록에 남아있는 페이지 수입니다.youngs/s non-youngs/s
: 젊고 된하거나되지 않은 이전 페이지 액세스 수. 이 메트릭은 두 점에서 이전 항목의 그것과는 다릅니다. 첫째, 이것은 이전 페이지에만 관련이 있습니다. 두 번째, 그것은 페이지 액세스 수에 따라 페이지 수에 따라 없습니다. (특정 페이지에 여러 액세스가있을 수 있으며, 그 모든 것이 계산됩니다.)young-making rate
: 블록이 버퍼 풀의 시작 부분으로 이동되는 히트.not
: 블록이 버퍼 풀의 시작 부분으로 이동되지 히트 (채워지지 않는 지연 때문에).
young-making
속도와 not
비율은 보통 버퍼 풀 전체의 적중률까지 도달하지 않습니다. 이전 하위 목록에서 블록의 히트 의해 그들이 새 하위 목록으로 이동되지만 새 하위 목록의 블록에 히트는 그들이 처음부터 특정 거리에있는 경우에만 목록의 맨 위로 이동 됩니다.
모니터에서 앞서 정보가 LRU의 조정 결정에 도움이 될 수 있습니다.
큰 스캔이 실행되고 있지 않은 경우,
youngs/s
값이 매우 낮은 것으로 확인 된 경우 지연 시간을 줄이거 나 이전 하위 목록에 사용되는 버퍼 풀의 비율을 늘릴 필요가있을 수 있음 을 보여줍니다. 비율을 늘리면 이전 하위 목록이 커지기 때문에 하위 목록의 블록이 끝으로 이동되어 삭제 될 때까지 오래 걸릴 수 있습니다. 그러면 다시 접근 젊고 될 가능성이 높아집니다.큰 테이블 스캔의 실행 (및 대량의
youngs/s
)에 대량의non-youngs/s
가 확인되지 않을 경우 지연 값을 크게하도록 조정합니다.
InnoDB
모니터의 출력으로 표시되는 초당 평균은 현재의 시간과 InnoDB
모니터의 출력이 마지막으로 출력 된 시간 사이의 경과 시간에 따라 있습니다.
InnoDB 모니터에 대한 자세한 내용은 섹션 14.15 "InnoDB 모니터" 를 참조하십시오.
INNODB_BUFFER_POOL_STATS
테이블과 InnoDB
버퍼 풀의 서버 상태 변수 는 SHOW ENGINE INNODB STATUS
출력에서 제공하는 많은 동일한 버퍼 풀 정보를 제공합니다.