한 줄 요약: 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 Architecture with Pluggable Storage Engines

이미지 출처: 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 Serverserver 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 InnoDB layer 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 박스)

쿼리 한 줄이 결과로 돌아오기까지의 흐름은 다음과 같음.

  1. Parser — SQL 문법을 검증해 파스 트리(AST) 를 만들고, 식별자(테이블·컬럼) 해석과 권한 검사를 함께 처리함.
  2. Optimizer — 통계 정보(테이블 row 수·인덱스 cardinality 등) 를 참조해 비용 모델로 가장 싼 실행 계획을 선택함. 같은 결과를 내는 plan 후보가 여럿이라 이 선택의 정확도가 곧 응답 시간이 됨.
  3. 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 managementThreads_connected, Threads_created, Connectionsthread_cache_size 조정, 커넥션 풀 도입, max_connections 산정, wait_timeout
Server Layer — SQL processingEXPLAIN ANALYZE, performance_schema.events_statements_*인덱스 설계, 옵티마이저 힌트(STRAIGHT_JOIN 등), 통계 갱신, 쿼리 리팩토링
Storage Engine (InnoDB)Buffer pool hit ratio, Innodb_buffer_pool_pages_freeinnodb_buffer_pool_size, innodb_buffer_pool_instances, innodb_redo_log_capacity
File SystemI/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 가 증가함. 거꾸로 짚으면 진짜 원인 대신 하위 증상에만 손대는 결과로 이어짐.


참고