InnoDB가 데이터·인덱스 페이지를 메모리에 캐싱하는 영역. MySQL 성능 튜닝의 첫 번째 손잡이다.
왜 크기가 곧 성능인가
-
요청한 페이지가 버퍼 풀에 있다 — → 메모리 접근 (수십 나노초)
-
없다 — → 디스크 접근 (SSD 도 수십 마이크로초)
-
1,000배 차이다
작업 데이터셋(자주 쓰는 데이터)이 버퍼 풀에 다 들어가느냐가 성능을 가른다.
-- 전용 DB 서버라면 물리 메모리의 50~75%
SHOW VARIABLES LIKE 'innodb_buffer_pool_size';
SET GLOBAL innodb_buffer_pool_size = 8 * 1024 * 1024 * 1024; -- 8GB (온라인 변경 가능)
적중률 확인하기
SHOW ENGINE INNODB STATUS\G
-- BUFFER POOL AND MEMORY 섹션
-- Buffer pool hit rate 1000 / 1000 ← 1000/1000 이면 100% 적중 (좋음)
-- 또는 지표로
SELECT (1 - (SELECT variable_value FROM performance_schema.global_status
WHERE variable_name='Innodb_buffer_pool_reads')
/ (SELECT variable_value FROM performance_schema.global_status
WHERE variable_name='Innodb_buffer_pool_read_requests')) * 100 AS hit_pct;
적중률이 99% 아래로 떨어지면 버퍼 풀이 작거나 쿼리가 불필요하게 많은 페이지를 읽고 있다는 신호다.
PostgreSQL은 구조가 다르다
-
InnoDB — buffer_pool 하나가 캐시를 전담한다 (메모리의 50~75%)
- 크게 잡는 게 정석
-
PostgreSQL — shared_buffers + OS 페이지 캐시의 2단 구조
- shared_buffers 는 25% 정도로 두고 나머지는 OS 에 맡긴다
- 무작정 키우면 이중 캐싱으로 오히려 손해
-- PostgreSQL
SHOW shared_buffers; -- 물리 메모리의 25% 가 일반적 권장
SHOW effective_cache_size; -- OS 캐시까지 포함한 '가용 캐시' 힌트 (옵티마이저용)
같은 "캐시를 키워라"가 두 엔진에서 다른 숫자로 나오는 이유다.
재시작하면 비어 있다
-- InnoDB: 종료 시 버퍼 풀 내용을 덤프해 두고 시작 시 복원한다
SHOW VARIABLES LIKE 'innodb_buffer_pool_dump_at_shutdown'; -- ON
SHOW VARIABLES LIKE 'innodb_buffer_pool_load_at_startup'; -- ON
이 설정이 없으면 재시작 직후 모든 쿼리가 디스크를 때려 한동안 서비스가 느리다(cold cache). 배포 후 지연 스파이크의 흔한 원인이다.
면접 함정
- ❌ "버퍼 풀은 크면 클수록 좋다" → OS와 다른 프로세스가 쓸 메모리를 남겨야 한다. 스왑이 시작되면 훨씬 느려진다.
- ❌ "PostgreSQL도 shared_buffers를 75%로" → OS 캐시와 이중으로 잡아 손해다.