[MySQL] 버퍼풀과 innodb 버퍼풀 인스턴스 설정

2026. 2. 12. 18:09·DB

 

 

버퍼 풀(Buffer Pool)

버퍼 풀은 주 메모리(RAM) 안에 있는 영역으로, InnoDB가 접근되는 테이블 데이터와 인덱스 데이터를 캐시(저장)하는 곳이다. 버퍼 풀 덕분에 자주 쓰는 데이터는 메모리에서 바로 접근할 수 있어 처리 속도가 빨라진다. 전용 서버에서는 보통 물리 메모리의 최대 80%까지 버퍼 풀에 할당하는 경우도 많다.

대량 읽기(read)를 효율적으로 처리하기 위해, 버퍼 풀은 페이지(page) 단위로 나뉘며, 한 페이지에는 여러 행(row)이 들어갈 수 있다. 캐시 관리를 효율적으로 하기 위해 버퍼 풀은 페이지들의 연결 리스트(linked list)로 구현되어 있고, 거의 사용되지 않는 데이터는 LRU(Least Recently Used) 알고리즘의 변형으로 캐시에서 밀려나게 된다.

버퍼 풀을 잘 활용해 자주 접근하는 데이터를 메모리에 유지하는 방법을 아는 것은 MySQL 튜닝에서 중요한 요소다.

버퍼 풀 LRU 알고리즘

버퍼 풀은 LRU 알고리즘의 변형을 사용한 리스트로 관리된다. 새 페이지를 넣기 위해 공간이 필요하면 가장 오랫동안 사용되지 않은 페이지가 제거되고(evict), 새 페이지는 리스트의 중간(midpoint)에 추가된다. 이 “중간 삽입”전략은 리스트를 두 개의 서브리스트로 나눠서 취급한다.

  • 머리(head): 최근 접근된 새로운(young) 페이지들의 서브리스트
  • 꼬리(tail): 덜 최근에 접근된 오래된(old) 페이지들의 서브리스트

이 알고리즘은 자주 쓰는 페이지를 new(young) 서브리스트에 유지한다. old 서브리스트는 덜 쓰는 페이지들이며, 이 페이지들이 제거 후보가 된다.

  • 버퍼 풀의 3/8이 old 서브리스트에 할당된다.
  • 리스트의 중간지점(midpoint) 이 경계로서, new 서브리스트의 꼬리와 old 서브리스트의 머리가 만나는 곳이다.
  • InnoDB가 페이지를 버퍼 풀로 읽어올 때, 처음에는 midpoint에 삽입한다.
  • old 서브페이지에 있는 페이지를 접근하면 그 페이지는 young 이 되어 new 서브페이지 머리로 이동한다.
  • 결국 계속 안 쓰인 페이지는 old 서브리스트의 꼬리에 도달해 제거된다.

버퍼 풀 설정

버퍼 풀의 여러 요소를 설정해서 성능을 개선할 수 있다.

  • 이상적으로는, 다른 프로세스가 동작할 메모리를 남겨두되 가능한 한 크게 설정한다. 버퍼 풀이 클수록 InnoDB는 “디스크에서 한 번 읽고 이후에는 메모리에서 반복 접근” 하는 형태가 되어 메모리 DB처럼 동작한다.
  • 갑작스런 대량 스캔 때문에 자주 쓰는 데이터들이 밀려나버리는 것을 방지할 수 있다.
  • 메모리가 충분하면 버퍼 풀을 여러 인스턴스로 나눠 동시 처리 시 경합을 줄일 수도 있다. → 버퍼 풀 인스턴스 여러 개 설정.

버퍼 풀은 기본 설정에서는 보통 1개(하나의 큰 버퍼 풀)처럼 보이지만, 성능/동시성 때문에 여러 인스턴스로 나눠서 여러 개처럼 운영될 수 있다.

 

 

버퍼풀을 여러 인스턴스로 나누는 경우는 꽤 흔하다.

조건이 맞으면 기본 튜닝 항목 중 하나다.

  • 나누는 편이 많은 경우
    • 서버 RAM이 큰 편(8~16GB) 이고
    • 동시 접속/쿼리 수가 많아 버푸풀 내부 락/경합이 생길 수 있는 환경
    • 특히 OLTP(짧은 트랜잭션이 많이 도는 서비스)

→ 이런 환경에서는 innodb_buffer_pool_instances를 여러 개로 두는게 흔하다.

  • 장점
    • 버퍼 풀 내부에서 동시에 많은 스레드가 부딪히는 경합을 줄여서, 처리량과 지연시간을 개선한다.
    • 동시 쿼리가 많으면 여러 스레드가 여기 접근하면서 락을 잡고 기다리는 시간이 커진다. 버퍼 풀을 인스턴스로 쪼개면 이런 구조들이 분리되서 대기 시간이 감소되고 처리량이 증가한다.

한 도로의 차선을 늘려서 정체를 줄이는 것에 비유할 수 있다.

핵심은, 버퍼 풀에는 메모리 덩어리만 있는 것이 아니라 LRU 관리, free list, flush list 등과 같은 “캐시 관리 작업”이 계속 일어나고, 백그라운드 스레드가 같은 지점에 몰리면서 락 대기 오버헤드가 커진다.

그래서 버퍼 풀을 여러 인스턴스로 쪼개면 각 인스턴스가 자기만의 락을 따로 갖게 되어 경합이 분산되고, 처리량이 올라가면서 지연시간은 줄어드는 효과가 나온다.

정리하자면, 캐시 관리의 병목을 줄이려고 쪼개는 튜닝

'DB' 카테고리의 다른 글

[MySQL 쿼리 최적화] 실행 계획을 분석해보자  (0) 2026.04.02
MySQL의 Using filesort와 Using temporary  (0) 2025.11.23
[이음] 프로젝트에 쿼리의 실행계획을 분석하며 최적화 해보기  (1) 2025.11.22
[DB] B+Tree 란? 그리고 자바 구현  (0) 2025.04.12
[DB] VACUUM vs GC ?! 데이터베이스 최적화의 첫 걸음  (0) 2025.04.05
'DB' 카테고리의 다른 글
  • [MySQL 쿼리 최적화] 실행 계획을 분석해보자
  • MySQL의 Using filesort와 Using temporary
  • [이음] 프로젝트에 쿼리의 실행계획을 분석하며 최적화 해보기
  • [DB] B+Tree 란? 그리고 자바 구현
dev_noonoo
dev_noonoo
인생의 스노우볼을 굴리는 개발자 누누(이재혁)의 블로그입니다.
이전 글
MySQL의 Using filesort와 Using temporary
2025.11.23
다음 글
[MySQL 쿼리 최적화] 실행 계획을 분석해보자
2026.04.02
  • dev_noonoo
    개발자 누누님의 블로그
    dev_noonoo
  • 전체
    1,600
    오늘
    3
    어제
    2
    • 분류 전체보기 (35) N
      • 운영체제 (0)
      • 네트워크 (5)
      • DB (6) N
      • 코딩테스트 (0)
      • 아키텍처 (7)
      • 회고 (1)
      • 언어(java, kotlin, python ..... (5)
      • 우아한 테크코스 프리코스 (4)
  • 블로그 메뉴

    • 홈
    • 태그
    • 방명록
  • 링크

    • 깃허브
  • 공지사항

  • 인기 글

    • [우아한 테크코스 8기 백엔드]프리코스 1주차 회고 -문자⋯
      2025.10.21
    • 고성능 JPA & Hibernate / SQL 강의 추천
      2025.04.20
    • JSCODE 네트워크 스터디를 진행하며 느낀점들(feat.⋯
      2025.12.22
    • [클린 아키텍처] 웹 어댑터 구현하기 & 영속성 어댑터 구⋯
      2025.03.28
  • 태그

    분산락
    정렬방식
    redis
    좋아요api
    filesort
    MySQL
    Using temporary
  • 최근 댓글

    • 방문도장 찍어봅니다~
      new비비
      ·08.30
    • 들렸다 갑니다~
      문자life
      ·08.28
    • 들렸다 갑니다~
      문자life
      ·08.28
    • 왔다 갑니다.
      인포info
      ·08.26
    • 잘 보고갑니다~
      한달동안
      ·08.18
  • 최근 글

    • [MySQL 쿼리 최적화] 실행 계획을 분석해보자
      2026.04.02
    • [MySQL] 버퍼풀과 innodb 버퍼풀 인스턴스 설정
      2026.02.12
    • JSCODE 네트워크 스터디를 진행하며 느낀점들(feat.⋯
      2025.12.22
    • [컴퓨터 네트워크] 네트워크 레이어
      2025.12.15
    • [컴퓨터 네트워크] TCP & UDP
      2025.12.09
  • hELLO· Designed By정상우.v4.10.5
dev_noonoo
[MySQL] 버퍼풀과 innodb 버퍼풀 인스턴스 설정
상단으로

티스토리툴바