MySQL은 Process가 아닌 Thread 기반으로 동작합니다. Thread는 역할에 따라 2가지로 분류할 수 있는데, User Session에 해당하는 Foreground Thread와 내부적인 처리를 목적으로 하는 Background Thread가 여기에 해당합니다.
Background Thread의 수는 MySQL Server 버전과 설정에 따라 다를 수 있으며, 병렬 작업을 수행하는 경우 동일한 이름의 Thread가 2개 이상 표시될 수 있습니다.
mysql> select thread_id, name, type from performance_schema.threads;
+-----------+----------------------------------------+------------+
| thread_id | name | type |
+-----------+----------------------------------------+------------+
| 1 | thread/sql/main | BACKGROUND |
| 2 | thread/sql/thread_timer_notifier | BACKGROUND |
| 3 | thread/innodb/io_ibuf_thread | BACKGROUND |
| 4 | thread/innodb/io_log_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_read_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/io_write_thread | BACKGROUND |
| 13 | thread/innodb/page_cleaner_thread | BACKGROUND |
| 16 | thread/innodb/srv_lock_timeout_thread | BACKGROUND |
| 17 | thread/innodb/srv_error_monitor_thread | BACKGROUND |
| 18 | thread/innodb/srv_monitor_thread | BACKGROUND |
| 19 | thread/innodb/srv_master_thread | BACKGROUND |
| 20 | thread/innodb/srv_purge_thread | BACKGROUND |
| 21 | thread/innodb/srv_worker_thread | BACKGROUND |
| 22 | thread/innodb/srv_worker_thread | BACKGROUND |
| 23 | thread/innodb/buf_dump_thread | BACKGROUND |
| 24 | thread/innodb/dict_stats_thread | BACKGROUND |
| 25 | thread/innodb/srv_worker_thread | BACKGROUND |
| 26 | thread/sql/signal_handler | BACKGROUND |
| 27 | thread/sql/compress_gtid_table | FOREGROUND |
| 29 | thread/sql/one_connection | FOREGROUND |
+-----------+----------------------------------------+------------+
📢 MySQL에서는 전통적인 Thread 모델을 사용하지만 MySQL Enterprise Edition과 Percona Server for MySQL에서는 Thread Pool 플러그인이 포함되어 있습니다. 커뮤니티 버전에서의 **Thread 모델**은 Client Connection 당 하나의 Thread를 사용하여 명령문을 실행합니다. 그렇기 때문에, 더 많은 Client가 Server에 연결하고 명령문을 실행할수록 전반적인 성능이 저하됩니다. 반면, **Thread Pool 플러그인**은 오버헤드를 줄이고 성능을 향상하도록 설계된 대체 Thread 처리 모델을 제공합니다. 특히 최신 다중 CPU/Core 시스템에서 많은 수의 Client 연결에 대한 명령문 실행 Thread를 효율적으로 관리하여 Server 성능을 향상합니다.
Foreground Thread(Client Thread)
Foreground Thread의 수는 최소 MySQL Server에 접속한 Client 수만큼 존재하며, 각 Client 사용자가 요청한 Query를 처리합니다.
사용자가 작업을 마치고 Session이 종료되면 해당 Thread는 Thread Cache로 반환됩니다. 이때 Thread Cache에 일정 개수 이상의 대기 중인 Thread가 있다면 해당 Thread를 종료시켜 일정 개수의 Thread만 Thread Cache에 유지합니다.
📢 Thread Cache에 유지할 수 있는 최대 Thread 개수는 thread_cache_size라는 System Variable로 설정합니다
일반적인 Foreground Thread는 사용자 요청(Query)을 받아 필요한 Data를 가져오는 역할을 수행하는데, 사용 중인 스토리지 엔진에 따라 역할 및 수행 범위가 달라질 수 있습니다.
예를 들어, MyISAM 테이블의 경우 디스크 I/O관련 작업은 모두 Foreground Thread가 담당하지만, InnoDB 테이블은 메모리에 대한 Read/Write 작업만을 Foreground Thread가 담당합니다.
(이외의 작업은 Background Thread가 담당합니다.)
Background Thread
다양한 MySQL의 스토리지 엔진 중 InnoDB의 경우 많은 작업을 Background Thread가 수행합니다.
Data 읽기 작업의 경우, 주로 Foreground Thread가 처리하기 때문에 Read Thread를 많이 설정할 필요는 없습니다. 하지만 쓰기 작업의 경우 대부분의 작업을 Background Thread가 담당하므로 충분한 수의 Write Thread를 설정하는 것이 좋습니다.
📢 과거 버전에서는 Master Thread가 여러 가지 역할을 수행했기 때문에 동시성이 떨어질 수밖에 없었지만, 지금은 각각의 작업들이 역할별로 분리되어 각기 다른 Thread들이 담당하고 있습니다. 예를 들어, Buffer Pool에 있는 Dirty Page를 Flush 하는 일은 Page Cleaner Thread가 수행하며 있으며, Delete Query에 의해서 삭제 처리된 Row를 물리적으로 삭제하는 일은 Purge Thread가 수행합니다.
InnoDB 엔진의 주요 Background Thread
Thread 종류 | Name | Description |
Master Thread | thread/innodb/srv_master_trhead | • Background Thread의 관리 및 다양한 작업들의 스케줄링을 담당합니다. • Data 일관성을 보장하기 위해 Buffer Pool의 Data를 디스크로 비동기식으로 Flush합니다. |
Insert Buffer Thread | thread/innodb/io_ibuf_thread | Insert Buffer(Change Buffer)를 Merge합니다. |
Log Thread | thread/innodb/io_log_thread | 트랜잭션 로그(Redo Log)를 작성합니다. |
Read Thread | thread/innodb/io_read_thread | 다양한 유형의 Read 요청 처리합니다. |
Write Thread | thread/innodb/io_write_thread | 다양한 유형의 Write 요청 처리합니다. |
Page Cleaner Thread | thread/innodb/page_cleaner_thread | Buffer Pool의 Dirty Page를 디스크로 Flush합니다. |
Purge Thread | thread/innodb/srv_purge_thread | Rollback에 더이상 필요하지 않은 Row를 제거하는 작업을 담당합니다. |
InnoDB Thread 상태 확인 방법
mysql> show engine innodb status;
=====================================
2022-04-27 06:59:36 140181498717952 INNODB MONITOR OUTPUT
=====================================
Per second averages calculated from the last 15 seconds
-----------------
BACKGROUND THREAD
-----------------
srv_master_thread loops: 92 srv_active, 0 srv_shutdown, 1030078 srv_idle
srv_master_thread log flush and writes: 0
----------
SEMAPHORES
----------
... 중략 ...
------------
TRANSACTIONS
------------
...
--------
FILE I/O
--------
I/O thread 0 state: waiting for completed aio requests (insert buffer thread)
I/O thread 1 state: waiting for completed aio requests (log thread)
I/O thread 2 state: waiting for completed aio requests (read thread)
I/O thread 3 state: waiting for completed aio requests (read thread)
I/O thread 4 state: waiting for completed aio requests (read thread)
I/O thread 5 state: waiting for completed aio requests (read thread)
I/O thread 6 state: waiting for completed aio requests (write thread)
I/O thread 7 state: waiting for completed aio requests (write thread)
I/O thread 8 state: waiting for completed aio requests (write thread)
I/O thread 9 state: waiting for completed aio requests (write thread)
Pending normal aio reads: [0, 0, 0, 0] , aio writes: [0, 0, 0, 0] ,
ibuf aio reads:, log i/o's:, sync i/o's:
Pending flushes (fsync) log: 0; buffer pool: 0
1097 OS file reads, 545 OS file writes, 84 OS fsyncs
0.00 reads/s, 0 avg bytes/read, 0.00 writes/s, 0.00 fsyncs/s
-------------------------------------
INSERT BUFFER AND ADAPTIVE HASH INDEX
-------------------------------------
... 중략 ...
InnoDB 엔진의 주요 System Variable (Background Thread)
System Variable | Default Value | Range | Description |
innodb_read_io_threads | 4 | 1 ~ 64 | 읽기 작업에 대한 I/O Thread 수 입니다. |
innodb_write_io_threads | 4 | 1 ~ 64 | 쓰기 작업에 대한 I/O Thread 수 입니다. |
innodb_page_cleaners | 4 | 1 ~ 64 | Buffer Pool에서 Dirty Page를 Flush하는 Page Clearner Thread의 수 입니다. |
innodb_purge_threads | 4 | 1 ~ 32 | Purge 작업에 할당된 Purge Thread의 수 입니다. |
기획 및 글 | 기술기획팀
이미지 제작 | 디자인그룹 이민석
'엑셈 경쟁력 > DB 인사이드' 카테고리의 다른 글
DB 인사이드 | MySQL Architecture - 5. SQL 처리과정 (4) | 2022.06.30 |
---|---|
DB 인사이드 | MySQL Architecture - 4. Memory (0) | 2022.06.30 |
DB 인사이드 | MySQL Architecture - 2. 스토리지 엔진 (0) | 2022.06.30 |
DB 인사이드 | MySQL Architecture - 1. MySQL 엔진 (0) | 2022.06.30 |
DB 인사이드 | PostgreSQL Vacuum - 6. Autovacuum (4) | 2022.04.29 |
댓글