Real MySQL 8.0 1권 <= 해당 책 내용을 바탕으로 스터디를 진행하였습니다.
이번 스터디는 MySQL의 아키텍처에 대해 알아보겠습니다.
MySQL 서버는 사람의 머리 역할을 담당하는 MySQL 엔진 과 손발 역할을 담당하는 스토리지 엔진으로 구별 할 수 있습니다.
먼저 MySQL 엔진 아키텍처에 대해 알아보겠습니다.
MySQL 엔진 아키텍처
MySQL의 전체 구조를 살펴보면 아래와 같습니다.

- MySQL은 일반 상용 RDBMS와 같이 대부분 프로그래밍 언어로부터 접근 방법을 모두 지원
- MySQL 서버는 크게 MySQL 엔진과 스토리지 엔진으로 구분
1-1. MySQL 엔진
MySQL 엔진의 역할은 다음과 같습니다.
- 클라이언트로부터 접속 및 쿼리 요청 처리하는 커넥션 핸들러와 SQL 파서 및 전처리기
- 쿼리의 최적화된 실행을 위한 옵티마이저
여기서 옵티마이저란?
DB가 SQL 쿼리를 가장 빠르고 적은 자원으로 실행하기 위해 실행 계획을 짜는 프로그램 입니다.
1-2. 스토리지 엔진
스토리지 엔진의 역할은 다음과 같습니다.
- 실제 데이터를 디스크 스토리지에 저장하거나 디스크 스토리지로부터 데이터를 읽어오는 역할
그리고 MySQL 서버에서 MySQL 엔진은 1개지만, 스토리지 엔진은 여러 개 동시에 사용할 수 있습니다.
아래 예시 처럼 테이블이 사용할 스토리지 엔진을 지정하면 이후 해당 테이블의 모든 읽기 작업이나 변경 작업은 정의된 스토리지 엔진이 처리 합니다.
ex)
mysql> CREATE TABLE test_table (fd1 INT, fd2 INT) ENGINE=INNODB;1-3. 핸들러 API
MySQL 엔진의 쿼리 실행기에서 데이터를 쓰거나 읽어야 할 때, 각 스토리지 엔진에 쓰기, 읽기를 요청하는데, 이러한 요청을 핸들러 API를 사용해 MySQL 엔진과 데이터를 주고 받습니다.
mysql> show global status like 'Handler%';
---
Variable_name |Value|
--------------------------+-----+
Handler_commit |10667|
Handler_delete |8 |
Handler_discover |0 |
Handler_external_lock |28513|
Handler_mrr_init |0 |
Handler_prepare |82 |
Handler_read_first |10040|
Handler_read_key |17138|
Handler_read_last |0 |
Handler_read_next |11555|
Handler_read_prev |0 |
Handler_read_rnd |329 |
Handler_read_rnd_next |54819|
Handler_rollback |9847 |
Handler_savepoint |0 |
Handler_savepoint_rollback|0 |
Handler_update |352 |
Handler_write |8007 |2-1. MySQL 스레딩 구조

MySQL 서버는 프로세스 기반이 아니라 스레드 기반을 작동, 크게 포그라운드/백그라운드 스레드로 구분
아래 명령어를 통해 현재 MySQL 서버에서 실행 중인 스레드의 목록을 확인 할 수 있습니다.
mysql> select thread_id, name, type, processlist_user, processlist_host from performance_schema.threads ORDER BY type, thread_id;
---
thread_id|name |type |processlist_user|processlist_host|
---------+-------------------------------------------+----------+----------------+----------------+
1|thread/sql/main |BACKGROUND| | |
3|thread/innodb/io_ibuf_thread |BACKGROUND| | |
4|thread/innodb/io_read_thread |BACKGROUND| | |
5|thread/innodb/io_read_thread |BACKGROUND| | |
6|thread/innodb/io_read_thread |BACKGROUND| | |
7|thread/innodb/io_read_thread |BACKGROUND| | |
8|thread/innodb/io_write_thread |BACKGROUND| | |
9|thread/innodb/io_write_thread |BACKGROUND| | |
10|thread/innodb/io_write_thread |BACKGROUND| | |
11|thread/innodb/io_write_thread |BACKGROUND| | |
12|thread/innodb/page_flush_coordinator_thread|BACKGROUND| | |
13|thread/innodb/log_checkpointer_thread |BACKGROUND| | |
14|thread/innodb/log_flush_notifier_thread |BACKGROUND| | |
15|thread/innodb/log_flusher_thread |BACKGROUND| | |
16|thread/innodb/log_write_notifier_thread |BACKGROUND| | |
17|thread/innodb/log_writer_thread |BACKGROUND| | |
18|thread/innodb/log_files_governor_thread |BACKGROUND| | |
21|thread/innodb/srv_lock_timeout_thread |BACKGROUND| | |
22|thread/innodb/srv_error_monitor_thread |BACKGROUND| | |
23|thread/innodb/srv_monitor_thread |BACKGROUND| | |
24|thread/innodb/buf_resize_thread |BACKGROUND| | |
25|thread/innodb/srv_master_thread |BACKGROUND| | |
26|thread/innodb/dict_stats_thread |BACKGROUND| | |
27|thread/innodb/fts_optimize_thread |BACKGROUND| | |
28|thread/mysqlx/worker |BACKGROUND| | |
29|thread/mysqlx/worker |BACKGROUND| | |
34|thread/innodb/buf_dump_thread |BACKGROUND| | |
35|thread/innodb/clone_gtid_thread |BACKGROUND| | |
36|thread/innodb/srv_purge_thread |BACKGROUND| | |
37|thread/innodb/srv_worker_thread |BACKGROUND| | |
38|thread/innodb/srv_worker_thread |BACKGROUND| | |
39|thread/innodb/srv_worker_thread |BACKGROUND| | |
41|thread/sql/signal_handler |BACKGROUND| | |
42|thread/mysqlx/acceptor_network |BACKGROUND| | |
43|thread/mysqlx/acceptor_network |BACKGROUND| | |
40|thread/sql/event_scheduler |FOREGROUND|event_scheduler |localhost |
44|thread/sql/compress_gtid_table |FOREGROUND| | |
11119|thread/sql/one_connection |FOREGROUND|admin |121.133.22.9 |
11120|thread/sql/one_connection |FOREGROUND|admin |121.133.22.9 |
11121|thread/sql/one_connection |FOREGROUND|admin |121.133.22.9 |2-2. 포그라운드 스레드(클라이언트 스레드)
포그라운드 스레드의 특징
- 포그라운드 스레드는 최소한 MySQL 서버에 접속된 클라이언트의 수만큼 존재합니다.
- 주로 각 클라이언트 사용자가 요청하는 쿼리 문장을 처리 합니다.
- 데이터를 MySQL의 데이터 버퍼나 캐시로부터 가져오며, 버퍼나 캐시에 없는 경우 직접 디스크의 데이터나 인덱스 파일로 부터 데이터를 읽어와서 작업을 처리
- 정리하면, MySQL에서 사용자 스레드와 포그라운드 스레드는 똑같은 의미로 사용됨
2-3. 백그라운드 스레드
백그라운드 스레드(Background Threads)란, 클라이언트가 실행하는 SQL 쿼리와 별개로 MySQL 서버 내부에서 동작하는 다양한 작업을 수행하기 위해 자동으로 실행되는 스레드를 말합니다.
InnoDB는 MySQL에서 가장 널리 쓰이는 스토리지 엔진(Storage Engine) 중 하나로, 다음과 같이 여러가지 작업을 수행 합니다.
- Insert 버퍼를 병합하는 스레드
- 로그를 디스크로 기록하는 스레드
- InnoDB 버퍼 풀의 데이터를 디스크에 기록하는 스레드
- 데이터를 버퍼로 읽어 오는 스레드
- 잠금이나 데드락을 모니터링하는 스레드
여기서 가장 중요한 스레드는 로그 스레드 와 버퍼의 데이터를 디스크로 내려쓰는 작업을 처리하는 쓰기 스레드 입니다.
3-1. 메모리 할당 및 사용 구조

MySQL에서 사용되는 메모리 공간은 크게 글로벌 메모리 영역 과 로컬 메모리 영역 영역으로 구분합니다.
글로벌 메모리 영역
클라이언트 스레드의 수와 무관하게 하나의 메모리 공간만 할당이 됩니다. 다만 설정에 따라 더 할당을 받을 수 있긴 합니다.
주된 역할은 모든 연결(세션)이 공통적으로 쓰는 캐시나 버퍼를 담고, 디스크 I/O를 줄여 MySQL 서버의 전체 성능을 높이는 데 초점을 둡니다.
대표적인 글로벌 메모리 영역은 다음과 같습니다.
- 테이블 캐시
- InnoDB 버퍼 풀
- InnoDB 어댑티브 해시 인덱스
- InnoDB 리두 로그 버퍼
로컬 메모리 영역
MySQL 서버상에 존재하는 클라이언트 스레드가 쿼리를 처리하는 데 사용하는 메모리 영역 입니다.그리고, 클라이언트 스레드가 사용하는 메모리 공간이라고 해서 클라이언트 메모리 영역이라고도 합니다.
또한, 클라이언트와 MySQL 서버와의 커넥션을 세션이라고 하기 때문에 로컬 메모리 영역을 세션 메모리 영역이라고도 합니다.
이러한 특성 덕분에 로컬 메모리는 각 클라이언트 스레드별로 독립적으로 할당이 되며 절대 공유되어 사용하지 않습니다.
대표적인 로컬 메모리 영역은 다음과 같습니다.
- 정렬 버퍼
- 조인 버퍼
- 바이너리 로그 캐시
- 네트워크 버퍼
4-1. 플러그인 스토리지 모델
MySQL의 독특한 구조 중 대표적인 것이 바로 플러그인 모델 입니다.
특징으로는,
MySQL 서버를 수정하거나 재컴파일하지 않고도 다양한 기능(스토리지 엔진, 인증 방식, 정보 스키마 테이블, 성능 수집기 등)을 외부 모듈(플러그인) 형태로 쉽게 추가/제거할 수 있는 아키텍처입니다.
즉, MySQL 서버의 확장성과 유연성을 위해 동적으로 기능을 추가하거나 교체할 수 있는 구조를 위한 것 입니다.
아래와 같은 명령어로 설치된 플러그인들을 확인할 수 있습니다.
mysql> show plugins;
---
Name |Status |Type |Library |License|
-------------------------------+--------+------------------+--------------+-------+
binlog |ACTIVE |STORAGE ENGINE | |GPL |
mysql_native_password |ACTIVE |AUTHENTICATION | |GPL |
sha256_password |ACTIVE |AUTHENTICATION | |GPL |
caching_sha2_password |ACTIVE |AUTHENTICATION | |GPL |
sha2_cache_cleaner |ACTIVE |AUDIT | |GPL |
daemon_keyring_proxy_plugin |ACTIVE |DAEMON | |GPL |
CSV |ACTIVE |STORAGE ENGINE | |GPL |
MEMORY |ACTIVE |STORAGE ENGINE | |GPL |
InnoDB |ACTIVE |STORAGE ENGINE | |GPL |
INNODB_TRX |ACTIVE |INFORMATION SCHEMA| |GPL |
INNODB_CMP |ACTIVE |INFORMATION SCHEMA| |GPL |
INNODB_CMP_RESET |ACTIVE |INFORMATION SCHEMA| |GPL |
INNODB_CMPMEM |ACTIVE |INFORMATION SCHEMA| |GPL |
INNODB_CMPMEM_RESET |ACTIVE |INFORMATION SCHEMA| |GPL |
INNODB_CMP_PER_INDEX |ACTIVE |INFORMATION SCHEMA| |GPL |
INNODB_CMP_PER_INDEX_RESET |ACTIVE |INFORMATION SCHEMA| |GPL |
INNODB_BUFFER_PAGE |ACTIVE |INFORMATION SCHEMA| |GPL |
INNODB_BUFFER_PAGE_LRU |ACTIVE |INFORMATION SCHEMA| |GPL |
INNODB_BUFFER_POOL_STATS |ACTIVE |INFORMATION SCHEMA| |GPL |
INNODB_TEMP_TABLE_INFO |ACTIVE |INFORMATION SCHEMA| |GPL |
INNODB_METRICS |ACTIVE |INFORMATION SCHEMA| |GPL |
INNODB_FT_DEFAULT_STOPWORD |ACTIVE |INFORMATION SCHEMA| |GPL |
INNODB_FT_DELETED |ACTIVE |INFORMATION SCHEMA| |GPL |
INNODB_FT_BEING_DELETED |ACTIVE |INFORMATION SCHEMA| |GPL |
INNODB_FT_CONFIG |ACTIVE |INFORMATION SCHEMA| |GPL |
INNODB_FT_INDEX_CACHE |ACTIVE |INFORMATION SCHEMA| |GPL |
INNODB_FT_INDEX_TABLE |ACTIVE |INFORMATION SCHEMA| |GPL |
INNODB_TABLES |ACTIVE |INFORMATION SCHEMA| |GPL |
INNODB_TABLESTATS |ACTIVE |INFORMATION SCHEMA| |GPL |
INNODB_INDEXES |ACTIVE |INFORMATION SCHEMA| |GPL |
INNODB_TABLESPACES |ACTIVE |INFORMATION SCHEMA| |GPL |
INNODB_COLUMNS |ACTIVE |INFORMATION SCHEMA| |GPL |
INNODB_VIRTUAL |ACTIVE |INFORMATION SCHEMA| |GPL |
INNODB_CACHED_INDEXES |ACTIVE |INFORMATION SCHEMA| |GPL |
INNODB_SESSION_TEMP_TABLESPACES|ACTIVE |INFORMATION SCHEMA| |GPL |
MyISAM |ACTIVE |STORAGE ENGINE | |GPL |
MRG_MYISAM |ACTIVE |STORAGE ENGINE | |GPL |
PERFORMANCE_SCHEMA |ACTIVE |STORAGE ENGINE | |GPL |
TempTable |ACTIVE |STORAGE ENGINE | |GPL |
ARCHIVE |ACTIVE |STORAGE ENGINE | |GPL |
BLACKHOLE |ACTIVE |STORAGE ENGINE | |GPL |
FEDERATED |DISABLED|STORAGE ENGINE | |GPL |
ngram |ACTIVE |FTPARSER | |GPL |
mysqlx_cache_cleaner |ACTIVE |AUDIT | |GPL |
mysqlx |ACTIVE |DAEMON | |GPL |
auth_socket |ACTIVE |AUTHENTICATION |auth_socket.so|GPL |5-1. 컴포넌트
MySQL 8.0 부터는 기존의 플러그인 아키텍처를 대체하기 위해 컴포넌트 아키텍처가 지원 됩니다.
플러그인은 아래와 같은 단점이 있었습니다.
- 플러그인은 오직 MySQL 서버와 인터페이스할 수 있고, 플러그인끼리는 통신할 수 없음
- 플러그인은 MySQL 서버의 변수나 함수를 직접 호출하기 때문에 안전하지 않음(캡슐화 안 됨)
- 플러그인은 상호 의존 관계를 설정할 수 없어서 초기화가 어려움
비밀번호 검증 기능을 사용해보면서, 컴포넌트의 간단한 사용법을 알아보겠습니다.
# validate_password 컴포넌트 설치
mysql> INSTALL COMPONENT 'file://component_validate_password';
# 설치된 컴포넌트 확인
mysql> SELECT * FROM mysql.component;
---
component_id|component_group_id|component_urn |
------------+------------------+----------------------------------+
1| 1|file://component_validate_password|6-1. 쿼리 실행 구조

위 그림은 쿼리를 실행하는 관점에서 MySQL의 구조를 간략하게 그림으로 표현한 것 입니다.
- 쿼리 파서
사용자 요청으로 들어온 쿼리 문장을 토큰(MySQL이 인식할 수 있는 최소 단위의 어휘나 기호)으로 분리해 트리 형태의 구조로 만들어 내는 작업 - 전처리기
파서 과정에서 만들어진 파서 트리를 기반으로 쿼리 문장에 구조적인 문제점이 있는지 확인 - 옵티마이저
쿼리 변환, 실행 계획 수립, 비용 기반 최적화를 수행합니다. DBMS의 두뇌라고 생각하면 됨 - 쿼리 실행기
옵티마이저가 수립한 계획을 실제로 실행하여 데이터를 반환합니다. 즉 핸들러에게 요청을 하여 요청 값을 받고 사용자에게 전달 해줍니다. - 핸들러(스토리지 엔진)
MySQL 서버 가장 밑단에서 쿼리 실행기의 요청에 따라 데이터를 데스크로 저장하고 읽어오는 역할을 담당 합니다.
내부적으로는 MySQL 엔진과 스토리지 엔진을 이어주는 '연결고리' 이지만, 사실상 "핸들러 = 스토리지 엔진"이라고 봐도 무방합니다.
7-1. 스레드 풀
스레드 풀은 MySQL 커뮤니티 에디션에는 없는 기능이고 엔터프라이즈 에디션에만 존재하는 기능 입니다.
스레드 풀(Thread Pool) 은 여러 개의 스레드를 미리 생성해두고, 작업이 생기면 이 중 하나를 가져다 사용하는 방식의 리소스 관리 기법입니다.
다만, 미리 CPU 자원을 점유해서 사용하기 때문에 쿼리 처리가 더 느려지는 사례가 발생할 수도 있습니다.
동작 방식은 다음과 같습니다.
- 애플리케이션에서 작업 요청 발생
- 작업은 작업 큐(task queue)에 추가됨
- 미리 만들어진 스레드들(thread workers) 중 대기 중인 스레드가 작업을 가져가 실행
- 작업이 끝난 스레드는 다시 작업 큐에서 다음 작업을 기다림
8-1. 트랜잭션 지원 메타데이터
MySQL 메타데이터란?
데이터베이스, 테이블, 컬럼, 인덱스 등의 구조 정보를 설명하는 데이터MySQL 8.0 이전 버전들의 메타데이터 처리 방식
메타데이터는 파일 기반으로 관리를 했습니다.
.frm, .trn, .par 등 다양한 파일을 통해 객체 정의 관리를 하다보니, 파일 시스템 기반의 비일관성 문제가 생겼습니다.<br>예시를 들자면 아래와 같은 문제였습니다.
<br>예시: 테이블 생성 중 서버 다운 → .frm 파일은 생성되었지만 실제 테이블은 없음, 메타데이터와 실제 데이터 상태 불일치
MySQL 8.0의 주요 변화로는,
트랜잭션 지원 메타데이터 도입과InnoDB를 통한 메타데이터 관리입니다.
트랜잭션 지원 메타데이터 방식
MySQL 8.0에서는 모든 메타데이터를 InnoDB 스토리지 엔진 기반의 테이블에 저장함으로써 트랜잭션으로 관리합니다.
새로운 "데이터 딕셔너리(Data Dictionary)" 시스템 도입
메타데이터 정보는 InnoDB 내부 테이블에 저장 (mysql.tables, mysql.columns, mysql.indexes 등)
메타데이터 변경도 InnoDB의 트랜잭션 관리 하에 수행됨
이렇게 되면서 특징 및 장점은 아래와 같습니다.
항목 설명 원자성(Atomicity) 테이블 생성, 수정, 삭제 등 메타데이터 변경도 트랜잭션 내에서 처리되어 실패 시 롤백 가능 일관성(Consistency) 메타데이터와 실제 데이터 상태가 항상 일관됨 복구 용이성 InnoDB의 Crash Recovery 기능이 메타데이터까지 복구 가능하게 만듦 성능 향상 메타데이터 접근을 위한 시스템 락이 감소하고, 병렬성 향상
InnoDB 기반 메타데이터 관리 구조
MySQL 8.0은 Data Dictionary라는 InnoDB 기반 메타데이터 저장소를 통해 다음과 같은 객체 정보를 관리합니다.
mysql.tables : 테이블 메타정보
mysql.columns : 컬럼 정의 정보
mysql.indexes : 인덱스 정보
mysql.schemata : 데이터베이스(스키마) 정보
mysql.view : 뷰 정의
mysql.triggers 등
이 모든 테이블은 InnoDB 스토리지 엔진을 사용하므로, 트랜잭션, MVCC, Undo/Redo 로그, Crash Recovery가 적용됩니다.
InnoDB 메타데이터 관리의 이점으로는 아래와 같습니다.
기능 설명 트랜잭션 일관성 CREATE,ALTER,DROP등 DDL 수행 중 오류 발생 시 메타데이터 롤백장애 복구 서버 크래시 후에도 메타데이터 일관성 복원 락 경쟁 감소 이전 파일 기반 시스템보다 메타데이터 락 경합이 현저히 감소 성능 향상 스레드 간 동시 메타데이터 접근 최적화 atomic DDL DDL 명령도 일부는 트랜잭션처럼 동작 (단일 스테이트먼트 단위로 원자성 보장)
1부 내용은 여기 까지 입니다.
감사합니다.
'스터디 > MySQL' 카테고리의 다른 글
| MySQL 스터디 - 트랜잭션과 잠금 (2) | 2025.07.06 |
|---|---|
| MySQL 스터디 - 아키텍처 2부 (0) | 2025.06.28 |
| MySQL 스터디 - 사용자 및 권한 (0) | 2025.06.20 |
