Database/Mysql

[Real MySQL] 4-2. 아키텍쳐: InnoDB 스토리지 엔진 아키텍쳐 (2)

noahkim_ 2025. 6. 8. 18:52

백은빈, 이성욱 님의 "Real MySQL" 책을 정리한 포스팅 입니다.

 

 

 

6. InnoDB Buffer Pool

  • 디스크의 데이터 파일이나 인덱스 정보를 메모리에 캐시해두는 공간

 

버퍼링

  • 쓰기 작업을 메모리에 먼저 저장 후, 일괄 처리로 디스크에 기록

 

시스템 변수
변수명 설명
innodb_buffer_pool_size
버퍼 풀 전체 사이즈를 설정함. (동적으로 조정 가능)
innodb_buffer_pool_instances
버퍼 풀을 여러 인스턴스로 나누어 병렬 처리
- 기본 8개 (버퍼 크기가 1GB 이하면 1개만 사용)

 

 

구성 요소

페이지
  • InnoDB가 디스크에서 데이터를 읽거나 메모리에 저장할 때 사용하는 기본 단위(블록)
  • 하나의 페이지 안에는 여러 개의 레코드(행) 또는 인덱스 정보가 들어갈 수 있음
  • 기본값은 16KB (MySQL 설정에 따라 4KB~64KB까지 조정 가능)
페이지 유형 설명
클린 페이지
디스크에서 읽은 후 변경되지 않은 상태의 페이지
더티 페이지
변경되었지만 디스크에 아직 반영되지 않은 페이지

 

페이지 리스트
  • 버퍼 풀 내의 페이지들을 현재 상태에 따라 나눈 분류 목록 (비었는지, 자주 쓰이는지, 변경됐는지 등)
  • 성능 최적화를 위해서 사용함 (메모리 공간을 효율적으로 쓰고, 디스크 접근을 줄이기 위함)
리스트 이름 설명
프리 리스트
비어 있는 페이지들의 목록.
디스크에서 새 데이터를 읽어올 때 이 리스트에서 페이지를 꺼냄
LRU 리스트
사용 빈도에 따라 페이지를 유지하거나 제거함.
- 자주 쓰는 페이지는 MRU 쪽에 있음 (데이터 페이지가 실제로 읽히면 MRU 헤더 부분으로 이동)
- 오래된 것은 LRU 끝에 있음 (오랫동안 사용되지 않으면 제거됨)
플러시 리스트
변경되었지만 디스크에 기록되지 않은 더티 페이지 목록.
백그라운드 플러시 작업 대상임

 

레코드 버퍼
  • 각 클라이언트 세션이 테이블의 레코드를 읽고 쓸 때 사용하는 임시 메모리 공간
항목 설명
개수
전체 커넥션 수 × 각 커넥션이 접근하는 테이블 수에 비례하여 생성됨
크기
정확한 크기 측정 불가 (동적으로 할당 및 해제)
- 128MB 청크 단위로 분할 (내부 잠금 경합 최소화 목적)

 

검색 과정

  1. 필요한 레코드의 데이터 페이지가 버퍼 풀에 존재하는지 확인
    • InnoDB Adaptive Hash Index를 이용해 페이지를 검색
    • 인덱스를 이용해 페이지 검색
  2. 디스크에서 필요한 데이터 페이지를 버퍼 풀에 적재 (LRU 리스트에 추가)
  3. 필요한 데이터가 자주 접근됬다면 해당 페이지의 인덱스 키를 Adaptive Hash Index에 추가

 

Adaptive Hash Index

  • 자주 조회되는 키 값에 대해 자동으로 생성되는 해시 인덱스 (B-Tree 인덱스 기반)
항목 설명
도입 목적
B-Tree 탐색 시 발생하는 트리 깊이 탐색 비용을 줄이고, 반복 조회 성능 향상
동작 방식
자주 사용된 B-Tree 인덱스 페이지를 해시 테이블 형태로 저장하여 빠르게 조회 가능

 

 

해시 인덱스
  • 인덱스 키 + 데이터 페이지 주소 쌍 으로 관리됩니다.
  • 인덱스 키: B-Tree 인덱스의 고유번호 + 실제 키 값 조합

 

시스템 변수
  • innodb_adaptive_hash_index: 어댑티브 해시 인덱스 자동 생성의 활성화 여부

 

워밍업

  • 자주 사용되는 데이터를 버퍼 풀에 적재해두는 과정
  • 디스크 i/o가 줄고 성능이 향상됩니다.

 

플러시

  • 디스크와 메모리 간의 데이터 동기화 작업
  • 백그라운드에서 더티 페이지들의 디스크 플러시 기능을 수행
플러시 유형 설명
플러시 리스트 플러시 더티 페이지를 디스크에 기록
LRU 리스트 플러시
오래된/사용 빈도가 낮은 페이지를 버퍼 풀에서 제거
→ 새로운 페이지 적재를 위한 공간 확보

 

시스템 변수
시스템 변수 설명
innodb_page_cleaners
더티 페이지를 디스크에 쓰는 클리너 스레드 수 (보통 버퍼 풀 인스턴스 수만큼 설정)
innodb_max_dirty_pages_pct
버퍼 풀에서 허용되는 최대 더티 페이지 비율. (이 비율을 넘기면 플러시가 더 적극적으로 수행됨)
innodb_max_dirty_pages_pct_lwm
더티 페이지 비율이 이 수준을 넘으면 백그라운드에서 점진적으로 플러시를 시작함
innodb_io_capacity
시스템이 일반적인 상황에서 처리할 수 있는 I/O 처리량 (더티 페이지 플러시 속도 조절 기준)
innodb_io_capacity_max
시스템이 최대 부하에서 처리할 수 있는 I/O 한계 (긴급 상황 시 한계까지 플러시 가능)
innodb_adaptive_flushing
활성화 시, 리두 로그 증가 속도 등을 고려해 플러시 타이밍을 자동 조절
innodb_adaptive_flushing_lwm
어댑티브 플러시를 시작할 리두 로그 공간 사용 비율 기준 (예: 30% 이상 사용 시 작동)
innodb_flush_neighbors
더티 페이지를 플러시할 때 인접한 페이지도 함께 플러시하여 디스크 접근 효율 개선
innodb_lru_scan_depth
LRU 리스트 끝에서 시작해 얼마나 많은 페이지를 검사할지 설정 (스캔량 조절)

 

Double-Write Buffer

  • 디스크에 같은 데이터를 두번 기록
항목 설명
데이터 무결성 보장
시스템이 데이터를 디스크에 기록 중 장애가 발생했을 때 데이터 손상을 방지
- 리두 로그는 페이지 변경 내용만 기록하므로, 페이지 자체가 부분적으로만 기록될 위험이 있음
해결 방법 (Double-Write)
같은 페이지를 두 번 기록
- 1차: Double-Write Buffer  디스크의 Double-Write 영역에 일괄 기록
- 2차: Double-Write  각 테이블의 데이터 파일에 개별적으로 기록

 Double-Write 영역의 기록이 남아있을 경우 다시 씀
 첫 번째 기록이 깨졌을 경우에도 정상 복구 가능

 

기록 과정
  1. 더티 페이지를 64개씩 묶어 Double-Write Buffer에 기록
  2. 1차 기록 (Double-Write Buffer  디스크의 Double-Write 영역에 일괄 기록)
  3. 2차 기록 (Double-Write  각 테이블의 데이터 파일에 개별적으로 기록)
  4. 완료 후 Double-Write Buffer에서 해당 페이지 제거

 

시스템 변수
변수명 설명
innodb_doublewrite
Double-Write 기능 사용 여부 설정 (ON 추천)
innodb_flush_log_at_trx_commit
트랜잭션 커밋 시 리두 로그를 디스크에 언제 동기화할지 결정하는 변수

 

Write Buffering

  • 변경 내용을 즉시 디스크에 쓰지 않고, 먼저 Redo Log에 기록 (성능 최적화)
항목 설명
고정 크기 순환 방식
여러 개의 고정 크기 로그 파일을 순환 구조로 재사용
로그 포지션이 끝에 도달하면 다시 앞에서부터 덮어쓰기
LSN (Log Sequence Number)
리두 로그에 기록될 때마다 증가하는 일련번호
변경 순서를 추적하고 체크포인트 관리에 사용됨

 

활성 리두 공간
  • 아직 디스크에 반영되지 않은 더티 페이지와 연관된 로그 영역
  • 재사용 불가능한 공간

 

체크 포인트
  • 더티 페이지를 디스크에 기록하는 시점
  • 체크포인트 이전의 로그는 재사용 가능 상태가 됨
항목 설명
체크포인트 발생 조건
리두 로그가 가득 차거나, 시스템이 적절하다고 판단한 경우 발생
체크포인트 에이지
가장 최근 체크포인트 LSN과 마지막 LSN 간의 차이
→ 즉, 활성 리두 로그 공간의 크기를 의미함

 

백업 및 복구

  • 버퍼 풀의 데이터를 복원하거나 백업하는 기능
  • 시스템 재시작 후에도 이전의 성능 상태를 복구하는 데 유용함

 

ib_buffer_pool 파일
  • 버퍼 풀의 메타 정보만 저장하는 파일 
  • LRU 리스트에서 적재된 데이터 페이지의 메타 정보를 포함
  • 이 파일을 통해 백업 및 복구 작업을 수행함

 

테이블
테이블명 설명
information_schema.innodb_buffer_page
버퍼 풀에 적재된 페이지 목록 확인 가능
information_schema.innodb_cached_indexes
인덱스 기준으로 캐시된 페이지 정보 확인 가능

 

시스템 변수
변수명 설명
innodb_buffer_pool_dump_now 현재 버퍼 풀 상태를 즉시 백업
innodb_buffer_pool_load_now 백업된 상태를 즉시 복원
innodb_buffer_pool_load_abort
백업 상태 로딩 중 중단 요청 시 활성화
innodb_buffer_pool_load_at_startup MySQL 시작 시 자동으로 복원
innodb_buffer_pool_dump_at_shutdown MySQL 종료 시 자동으로 백업
innodb_buffer_pool_dump_status
백업/복원 작업의 진행 상태 확인 변수

 

 

Redo Log

  • 커밋된 변경 사항을 기록하는 로그 파일
  • 서버가 예기치 않게 종료되었을 때, 아직 디스크에 쓰이지 않은 커밋된 데이터 복구
  • 리두 로그에 기록된 내용을 기반으로 데이터 파일에 반영되지 않은 변경사항을 복원함

 

로그 버퍼
  • 리두 로그를 일시적으로 저장하는 메모리 공간
항목 설명
동작
일정 크기(기본 16MB) 이상이 되거나, 트랜잭션이 커밋되면 로그 파일로 기록됨
장점
디스크 I/O 빈도를 줄이고 성능 향상에 기여

 

 

명령어
더보기

리두 로그 아카이빙

DO innodb_redo_log_archive_start('backup', '20200722');
DO innodb_redo_log_archive_stop();

 

리두 로그 활성화/비활성화

ALTER INSTANCE ENABLE INNODB REDO_LOG;
ALTER INSTANCE DISABLE INNODB REDO_LOG;

 

시스템 변수
변수명 설명
innodb_flush_log_at_trx_commit
리두 로그를 트랜잭션 커밋 시 디스크에 얼마나 자주 쓰는지 설정
innodb_log_file_size
개별 리두 로그 파일의 크기 설정
innodb_log_files_in_group
리두 로그 파일의 개수 설정 (기본 2개)
innodb_redo_log_archive_dirs
리두 로그 아카이브 대상 디렉터리 경로 지정
innodb_redo_log_enabled
리두 로그 활성화 여부 제어 변수

 

Undo Log

  • DML 실행 시, 변경되기 이전 데이터의 버전을 저장하는 공간
항목 설명
ROLLBACK
트랜잭션이 롤백되면 Undo Log를 사용해 데이터를 변경 전 상태로 복원
보존 기간
트랜잭션이 끝날 때까지 Undo Log는 삭제되지 않음
성능 영향
Undo Log가 많아지면 메모리 사용 증가 → 성능 저하 가능

 

트랜잭션의 격리 수준 보장
항목 설명
MVCC
Undo Log를 활용해 트랜잭션 간 충돌 없이 격리 수준(Repeatable Read 등)을 보장
레코드 모니터링
Undo 관련 상태를 확인 가능

 

Undo Table Space
  • Undo Log가 저장되는 공간
항목 설명
롤백 세그먼트
하나의 Undo 테이블 스페이스는 최대 128개의 롤백 세그먼트를 가짐
언두 슬롯
하나의 세그먼트는 (페이지 크기 / 16바이트) 개의 언두 슬롯 보유

 

 

언두 퍼지
  • 커밋 완료된 트랜잭션의 불필요한 Undo Log를 백그라운드 스레드가 주기적으로 삭제

 

명령어
더보기

레코드 모니터링

SHOW ENGINE INNODB STATUS

 

언두 테이블 스페이스 확인

SELECT TABLESPACE_NAME, FILE_NAME FROM INFORMATION_SCHEMA.FILES WHERE FILE_TYPE LIKE 'UNDO LOG';

 

시스템 변수
항목 설명
innodb_undo_log_truncate
Undo 로그 자동 삭제(퍼지) 기능 활성화 여부 설정 변수
innodb_purge_resg_truncate_frequency
퍼지 작업을 얼마나 자주 수행할지 결정하는 빈도 설정 변수

 

 

출처