한 줄 요약: MySQL 의 1 차 분리는 server layer ↔ pluggable storage engine 두 계층임. 둘 사이는 handler API 가 경계이며, 공식 매뉴얼도 “rows examined by the server layer (not counting any processing internal to storage engines)” 처럼 이 둘만 일관되게 구분해서 다룸. 공식 그림 Figure 18.3 은 그 위에 클라이언트 드라이버(Connectors) 와 디스크(File System) 를 한 번 더 그려 Connectors / MySQL Server / File System 의 3 블록으로 풀어 보임.

이미지 출처: MySQL 9.7 Reference Manual, Figure 18.3 MySQL Architecture with Pluggable Storage Engines.
아키텍처 구성
공식 그림 Figure 18.3 이 그리는 블록과, 매뉴얼 본문이 실제로 쓰는 표준 어휘는 다음과 같음.
| 블록 (Figure 18.3) | 공식 매뉴얼 어휘 | 역할 |
|---|---|---|
| Connectors | ”Connector APIs and service layers” | 언어별 드라이버(C/JDBC/ODBC/Python 등). mysqld 외부에서 연결을 만듦 |
| MySQL Server | server layer · The Common Database Server Layer (Section 18.11.2) | connection pool · SQL interface · parser · optimizer · caches & buffers |
| Pluggable Storage Engines | ”storage engines” — server layer 안쪽의 교체 가능한 컴포넌트 | InnoDB 등이 handler API 뒤에서 실제 데이터·인덱스·트랜잭션을 처리 |
| File System | ”physical server level” — 파일 / 로그 | 테이블스페이스·redo·undo·binlog 가 실제로 떨어지는 디스크 영역 |
server layer ↔ storage engine 사이 경계가 handler API 임. Figure 18.3 의 박스 포함관계가 가리는 이 경계를 단순화하면 다음과 같음.
graph TD Client[/"Client / Connectors"/] subgraph ServerLayer["MySQL Server (server layer)"] direction TB Parser[Parser] Optimizer[Optimizer] Executor[Executor] Parser --> Optimizer Optimizer --> Executor end HandlerAPI{{"handler API ── 공식 경계"}} subgraph Engine["Pluggable Storage Engines"] InnoDB[(InnoDB)] end FS[/"File System: *.ibd · redo · undo · binlog"/] Client --> Parser Executor --> HandlerAPI HandlerAPI --> InnoDB InnoDB --> FS
매뉴얼이 두 영역을 가리킬 때 일관되게 쓰는 어휘쌍이 이 경계를 그대로 반영함.
“the higher MySQL layer above the
InnoDBlayer that sets these locks” —innodb_table_locks설명“There are no intermediate commits at the SQL layer during the DDL operation.” — Atomic DDL
결론
왜 이런 분리가 중요한가
| 질문 | 답변 |
|---|---|
| 왜 server layer 와 storage engine 을 나눴나 | 같은 SQL 인터페이스 아래에서 스토리지 전략(트랜잭션·압축·메모리·로그)만 바꿀 수 있게 하기 위함. handler API 가 두 계층의 공식 경계임. |
| 왜 InnoDB 가 사실상 표준인가 | 트랜잭션·crash recovery·MVCC·외래 키·clustered index 를 모두 포함하고, 8.0 부터는 데이터 딕셔너리·시스템 테이블까지 InnoDB 위에 얹혀 있음. |
| 왜 옵티마이저 튜닝이 비중이 큰가 | 같은 결과를 내는 실행 계획이 여러 개 있고, 통계·인덱스·힌트에 따라 비용 차이가 크게 벌어지기 때문임. |
| 왜 buffer pool 이 핵심 지표인가 | 디스크 I/O 가 메모리 접근보다 훨씬 비싸므로, hot 데이터·인덱스가 메모리에 머무는지가 처리량을 결정함. |
운영 시 기억할 것
- 병목 분석은 server layer → storage engine → file system 순으로 짚음. server layer 안에서는 connection management(
Threads_running·max_connections) → SQL processing(EXPLAIN ANALYZE) 순으로 한 단계 더 나누면 진단이 빨라짐. - MySQL 5.7 까지 존재하던 query cache 는 8.0 에서 제거됨 (5.7.20 부터 deprecated). “쿼리 캐시 hit 율” 같은 옛 가이드를 그대로 적용하면 안 됨. 결과 캐싱이 필요하면 애플리케이션 레이어(Redis 등) 로 올림.
- 8.0 부터 메타데이터가 트랜잭셔널 데이터 딕셔너리로 옮겨가면서 DDL 이 atomic 해짐 —
ALTER도중 크래시가 나도 파일과 메타가 어긋난 상태로 남지 않음. - 스토리지 엔진을 바꿀 수 있다는 설계는 보존됐지만, 운영 환경에서 InnoDB 외 엔진은 특수 목적 에만 씀 (
MEMORY임시 테이블,BLACKHOLE로그 라우팅 등).
상세
1. Connectors (그림 윗단)
mysqld 외부의 언어별 클라이언트 드라이버 — C/JDBC/ODBC/Python/.NET 등이 같은 wire protocol 을 구현함. 운영 튜닝 대상은 아니지만 클라이언트 측 커넥션 풀 동작이 server layer 의 connection management 부하에 직접 영향을 줌.
2. Server Layer (그림의 “MySQL Server” 박스)
handler API 위쪽 전부 — connection pool · SQL interface · parser · optimizer · caches & buffers. 공식 챕터명은 The Common Database Server Layer (Section 18.11.2).
2-1. 연결 관리 (Connection Pool 박스)
mysqld 는 커넥션마다 OS 스레드 하나를 붙임 — one-thread-per-connection 모델임. 매번 스레드를 새로 만들지 않도록 thread cache 가 있어, disconnect 된 스레드를 보관했다가 다음 connect 에서 재사용함. 캐시가 너무 작으면 Threads_created 가 빠르게 증가하므로 운영 시 이 지표를 모니터링함.
2-2. Parser → Optimizer → Executor (SQL Interface · Parser · Optimizer 박스)
쿼리 한 줄이 결과로 돌아오기까지의 흐름은 다음과 같음.
- Parser — SQL 문법을 검증해 파스 트리(AST) 를 만들고, 식별자(테이블·컬럼) 해석과 권한 검사를 함께 처리함.
- Optimizer — 통계 정보(테이블 row 수·인덱스 cardinality 등) 를 참조해 비용 모델로 가장 싼 실행 계획을 선택함. 같은 결과를 내는 plan 후보가 여럿이라 이 선택의 정확도가 곧 응답 시간이 됨.
- Executor — 옵티마이저가 고른 plan 을 따라 handler API 를 호출해 행을 한 줄씩 가져옴. handler API 가 server layer 와 storage engine 의 공식 경계임.
메타데이터(데이터 딕셔너리) 도 8.0 부터 InnoDB 위 트랜잭셔널 테이블로 옮겨졌고, 그 결과 DDL 이 atomic 해졌음. 같은 8.0 에서 query cache 는 제거됐음.
3. Storage Engine — InnoDB (Pluggable Storage Engines 박스)
handler API 뒤에 붙는 실제 데이터 관리자임. 8.0+ 에서 시스템 테이블까지 InnoDB 위에 올라갔으므로 사실상 InnoDB 가 표준 이며, 다른 엔진은 특수 목적에만 씀.
Buffer Pool (Caches & Buffers 박스)
데이터·인덱스 페이지를 메모리에 캐싱하는 영역. 매뉴얼 권장은 “On dedicated servers, up to 80% of physical memory is often assigned to the buffer pool” — 물리 메모리 중 buffer pool 에 할당하는 비율 기준임. LRU 변형 알고리즘으로 hot 페이지를 우선 유지함.
Clustered Index — PK 가 곧 데이터 배치
InnoDB 테이블은 B+ Tree clustered index 로 저장됨 — PK 순서가 곧 디스크 물리 배치이며, 보조 인덱스 leaf 에는 PK 값이 들어감. PK 설계가 인덱스 크기·lookup 비용·페이지 분할 빈도를 함께 결정함.
Redo Log · Undo Log · MVCC
InnoDB 는 두 로그로 동시성·내구성을 떠받침.
- Redo log — 내구성. 커밋 시 redo 만 디스크에 있으면 크래시 후 복구가 됨.
- Undo log — 원자성 + MVCC. 롤백용 이전 이미지를 보관하면서, 다른 트랜잭션이 시점에 맞는 행 버전을 재구성하는 재료가 됨.
덕분에 InnoDB 는 잠금 없이 일관된 스냅샷 읽기 를 제공함 — SELECT 가 UPDATE 를 막지 않고 UPDATE 도 SELECT 를 막지 않음.
4. File System (Files & Logs 박스)
그림이 가장 아래 박스로 그리는 영역임. 매뉴얼은 physical server level 로 부름. 그림이 명시하는 파일·로그 종류는 다음과 같음.
| 파일·디렉터리 | 역할 |
|---|---|
*.ibd | 테이블별 데이터·인덱스(테이블스페이스) |
mysql.ibd | 데이터 딕셔너리 + 시스템 테이블 |
ibdata1 | 시스템 테이블스페이스(undo·doublewrite 등) |
#innodb_redo/ (8.0.30+) | redo log 그룹 |
binlog.NNNNNN | 변경 이벤트 스트림(복제·CDC 소스) |
블록별 성능 튜닝 포인트
각 블록에서 “어디를 보고 무엇을 만지는가” 를 한 표로 압축함. server layer 는 connection management 와 SQL processing 으로 한 번 더 나눔.
| 블록 | 주요 지표 · 진단 도구 | 실무 튜닝 포인트 |
|---|---|---|
| Server Layer — connection management | Threads_connected, Threads_created, Connections | thread_cache_size 조정, 커넥션 풀 도입, max_connections 산정, wait_timeout |
| Server Layer — SQL processing | EXPLAIN ANALYZE, performance_schema.events_statements_* | 인덱스 설계, 옵티마이저 힌트(STRAIGHT_JOIN 등), 통계 갱신, 쿼리 리팩토링 |
| Storage Engine (InnoDB) | Buffer pool hit ratio, Innodb_buffer_pool_pages_free | innodb_buffer_pool_size, innodb_buffer_pool_instances, innodb_redo_log_capacity |
| File System | I/O wait, IOPS, fsync latency (pidstat -d, iostat -x) | PK 설계(clustered index 친화), binlog_expire_logs_seconds, redo log 크기, 스토리지 SSD/NVMe 화 |
위에서 아래로 내려가며 짚는 이유는 상위 블록의 문제가 하위 블록의 부하로 전파되기 때문임. 옵티마이저가 잘못된 인덱스를 골라 풀스캔이 일어나면 buffer pool 이 흔들리고, buffer pool miss 가 늘어나면 디스크 IOPS 가 증가함. 거꾸로 짚으면 진짜 원인 대신 하위 증상에만 손대는 결과로 이어짐.
참고
- MySQL 9.7 — Pluggable Storage Engine Architecture — Figure 18.3 MySQL Architecture with Pluggable Storage Engines 출처
- MySQL 9.7 — Connection Interfaces — 커넥션 → 스레드 매핑·thread cache 동작
- MySQL 9.7 —
thread_cache_size— 기본값 공식(8 + max_connections/100, 100 cap),Threads_created/Connections로 캐시 효율 산정 - MySQL 9.7 — The InnoDB Buffer Pool — buffer pool 구조 · “물리 메모리의 80% 까지” 권장
- MySQL 9.7 — Clustered and Secondary Indexes — InnoDB clustered index 의 PK 의존성·보조 인덱스 leaf 구조
- MySQL 9.7 — Atomic Data Definition Statement Support — 데이터 딕셔너리·스토리지 엔진·binlog 의 원자 결합
- MySQL 9.7 — MySQL Data Dictionary — 5.7 이전 파일 기반 메타데이터(
.frm·.par) 폐기 배경 - MySQL 5.7 — The MySQL Query Cache — “The query cache is deprecated as of MySQL 5.7.20, and is removed in MySQL 8.0” — query cache 제거 이력