백은빈, 이성욱 님의 "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 청크 단위로 분할 (내부 잠금 경합 최소화 목적) |
검색 과정
- 필요한 레코드의 데이터 페이지가 버퍼 풀에 존재하는지 확인
- InnoDB Adaptive Hash Index를 이용해 페이지를 검색
- 인덱스를 이용해 페이지 검색
- 디스크에서 필요한 데이터 페이지를 버퍼 풀에 적재 (LRU 리스트에 추가)
- 필요한 데이터가 자주 접근됬다면 해당 페이지의 인덱스 키를 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 영역의 기록이 남아있을 경우 다시 씀 → 첫 번째 기록이 깨졌을 경우에도 정상 복구 가능 |
기록 과정
- 더티 페이지를 64개씩 묶어 Double-Write Buffer에 기록
- 1차 기록 (Double-Write Buffer → 디스크의 Double-Write 영역에 일괄 기록)
- 2차 기록 (Double-Write → 각 테이블의 데이터 파일에 개별적으로 기록)
- 완료 후 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 |
퍼지 작업을 얼마나 자주 수행할지 결정하는 빈도 설정 변수
|
출처
'Database > Mysql' 카테고리의 다른 글
[업무에 바로 쓰는 SQL 튜닝] 5. 악성 SQL 튜닝으로 전문가 되기 (0) | 2025.03.19 |
---|---|
[업무에 바로 쓰는 SQL 튜닝] 4. 악성 SQL 튜닝으로 초보자 탈출하기 (0) | 2025.03.18 |
[업무에 바로 쓰는 SQL 튜닝] 2. SQL 튜닝 용어를 직관적으로 이해하기 (3) | 2025.03.18 |
[업무에 바로 쓰는 SQL 튜닝] 1. MySQL과 MariaDB 개요 (0) | 2025.03.18 |
[Real MySQL] 16-2. 복제: 타입 (0) | 2025.03.14 |