DB & AWS Knowledge
MySQL / MariaDB 기본 아키텍처 (Engine) 본문
해당 페이지에서는 MySQL / MariaDB 기본 아키텍처 중 엔진영역에 대하여 다룬다.
(참고 사이트)
https://mysqldba.tistory.com/2
https://dev.mysql.com/doc/refman/8.0/en/pluggable-storage-overview.html
https://dansjkim.github.io/posts/database-execution-plan
https://lannstark.tistory.com/21
https://developpaper.com/mysql-innodb-storage-engine-exploration/
mysqlserverteam.com/mysql-connection-handling-and-scaling/
severalnines.com/database-blog/what-check-if-mysql-memory-utilisation-high
www.mysqlkorea.com/sub.html?mcode=manual&scode=01_1&m_no=22554&cat1=827&cat2=966&cat3=1010&lang=k
타 RDBMS 의 기본구조인 Engine + Data 영역과 유사하게 Mysql , MariaDB 도 Engine 영역, Data 영역으로 나뉜다.
단, MySQL 은 타 RDBMS 와 다르게 Data 영역에서 사용할 스토리지 엔진 또한 여러 개가 있어서 이 중에서 필요한 엔진을 선택하여 사용이 가능하며 그에 따른 아키텍처 요소도 차이가 있다.
자주 사용하는 스토리지 엔진은 MyISAM, InnoDB 이며, 단일 DB 서버에서 테이블 등의 특정 오브젝트 단위로 여러 개의 스토리지 엔진을 사용 할 수 있다.
여러 필수 백그라운드 및 세션 프로세스들로 운영되는 RDBMS 와는 다르게 MySQL (MariaDB) 은 단일 프로세스 (mysqld) 로 DB 가 운영 된다.
(실제 기동시에는 해당 프로세스의 비정상 종료 시, 재기동 시켜주는 mysqld_safe 프로세스와 같이 기동 된다.)
RDBMS 에서 구성 하는 백그라운드 및 프로세스들은 MySQL / MariaDB 에서는 스레드로 단위로 운영되기에 이에 따라 외부 에서 DB 접근시에는 프로세스가 아닌 스레드로 연결이 맺어 진다.
스토리지 엔진 이외에 기본적으로 사용하는 MySQL 엔진 요소들은 아래와 같다.
Connection Pool
클라이언트에 스레드를 배정해주는 공간, 스레드를 배정하여 세션을 구성 해 줄 시, 각 세션별로 쿼리 연산처리를 할 수 있는 스레드 캐시도 각각 부여 해 준다.
Connection Pool 을 통한 세션 및 스레드 배정 과정은 아래와 같다.
먼저, DB 내에서 command line 혹은 기타 라이브러리를 통하여 DB 를 사용할 클라이언트 (Client) 들이 있다.
이 클라이언트들의 TCP-IP 포트 통신 신호를 (MySQL, MariaDB 포트번호는 특별한 설정이 없다면 3306 을 사용한다) 통하여 DB에 접속 요청 신호를 보낸다.
이러한 접속요청들은 적재가 되며, 그후 DB 에서 이를 담당하는 Receiver 스레드가 각 요청마다 하나의 User 스레드를 배정해준다. 그 후 실질적인 DB 작업은 User 스레드가 처리하게 된다.
Receiver 스레드 위의 Thread Cache 가 있다. 이는 DB 접속 유저에 따른 스레드 배정 속도를 빠르게 처리하기 위해서 구성하는 공간이다. 이 공간에서 OS 스레드를 세로 만들거나 기존 미사용 OS 스레드를 가져와서 예비용으로 보관하게 된다. thread_cache_size 라는 파라미터를 통하여 예비용으로 보관할 수 있는 스레드 개수를 조절 할 수 있다.
클라이언트들이 User 스레드들을 받게 되면 User 스레드가 실질적인 DB 입출력 처리를 담당하게 된다.
입출력에 따른 자체 프로토콜이 적용되는 부분이기도 하다.
이를 통하여 구현되는 스레드 객체를 THD 라 표기한다. (뒤의 s 는 객체가 클라이언트 수에 따라 복수개이기 때문)
THD 는 유저 스레드와 마찬가지로 1 클라이언트 1 객체 배정을 따른다. 최대 1만개까지 동시 사용이 가능하며 각 객체들 마다 배정된 메모리 사용률은 각 객체가 수행하는 SQL 쿼리의 메모리 사용에 따라 상이하다. 각 세션당 평균 메모리 사용에 따른 메모리 샤용량도 조절이 가능하다.
세션이 종료하게 되면 위의 과정을 거치게 된다. 먼저 클라이언트가 종료신호인 COM_QUIT 을 유저 스레드에 보낸다.
이에 따라 유저 스레드는 보관한 DB 작업과 관련된 내용을 모두 비운 뒤, THD 객체를 회수하고, 배정된 유저 스레드 또한 회수되어 Thread Cache 에 보관된다.
해당 종료 명령어 이외에 클라이언트와 서버중 한곳에서 접속을 차단하거나 종료시켰을 경우에도 위의 과정을 거친다.
스레드가 회수되어 thread cache 에 보관 될 때, 해당 공간에 스레드를 보관할 수 있는 여유 공간이 없으면 스레드 자체도 종료되어 없어지게 된다.
SQL Interface
DB 에서 사용하는 SQL 구문 및 프로시저 등의 명령문들을 보관하는 모듈 공간이다.
Parser
SQL Interface 에 근거하여 수행하려는 SQL 구문을 DB 내부적으로 처리 할 수 있도록 DB 언어로 가공하는
역할을 담당한다.
Optimizer
Parser 를 거친 구문에 대하여 최적의 실행 계획을 세우는 공간. 타 DB 와 마찬가지로 Executer 가 실행
계획까지 세운 구문을 실행 함.
Cache & Buffers
참조 및 변경할 데이터, 오브젝트 구조들 및 필요 시 스토리지 엔진이 사용 할 내용 까지 디스크에서 가져와서 보관하는 메모리 공간이다. MySQL 은 타 RDBMS 와 같이 모든 세션들이 공유하는 메모리 공간과 각 세션들이 사용하는 메모리 공간이 있다.
주로 언급 되면서 조절해야 하는 글로벌 메모리 영역과 세션 메모리 구성 요소들은 다음과 같다.
글로벌 메모리 영역
키 캐시
MyISAM 스토리지 엔진이 사용하는 캐시 영역으로서 MyISAM 스토리지 엔진에서 인덱스 블록 정보들을
보관하는 영역이다. 이를 보관함으로써 DISK I/O 부하를 줄일 수 있는 이점이 있다. 단, 이 공간은 MyISAM 전용 이므로 InnoDB 를 메인 스토리지로 사용하는 서버에서는 많이 줄 필요가 없다. 해당 항목은 key_buffer_size 파라미터로 조절 가능하다.
버퍼 풀
흔히 데이터베이스 시스템에서 작업 대상 혹은 기타 목적으로 사용되는 데이터를 디스크에서 가져와서 보관하는 공간이다. 디스크를 통한 데이터 접근은 매우 느리기 때문에 디스크 대비 속도가 메우빠르고, 잠깐이나마 데이터를 보관 할 수도 있는 메모리를 이에 대한 방안으로 사용 하는 것이다. MySQL / MariaDB 에서 이 공간을 메인으로 사용하는 스토리지 엔진은 InnoDB 엔진 이며 조절하는 파라미터 또한 innodb_buffer_pool_size 다. 보통 메모리 관련 파라미터를 사용 시, 메인으로 사용하는 영역인 만큼 크게 설정하여 사용한다.
쿼리 캐시
특정 쿼리들에 대한 실행결과를 저장 한 후, 다음에 유입되는 쿼리들에 대한 결과를 저장하고 있을 시, 바로 반환 시켜주는 영역이다. 결과를 저장한다는 점에서 결과가 아닌 쿼리 수행 계획을 저장하는 Oracle 의 Shared Pool 과 큰 차이를 보인다. 결과를 바로 반환한다는 점은 장점이나, 보통 이를 OFF 하고 메모리 cache hit 율을 높여서 성능을 개선하는 방향으로 가는 경우가 많고, 이를 사용하면 이에 대한 단점이 있다. (참조 : rrhh234cm.tistory.com/141)
해당 영역을 조절 할 수 있는 파라미터는 query_cache_type, query_cache_size, query_cache_limit 가 있으며
OFF 를 할 시에는 위의 3개 파라미터를 0 으로 설정 하면 된다.
테이블 캐시
모든 RDBMS 들은 DB 내에 저장하고 있는 인덱스, 테이블 등의 객체(object)들에 대한 명칭, 크기, 사용 빈도등의 데이터들을 보관하면서 관리한다. 이러한 데이터들을 메타 데이터라고 한다. 메타 데이터 또한 데이터이기 때문에 관리 및 기타 객체 변경등을 할 시에 이 메타 데이터들 또한 조회할 필요가 있다. 당연히 디스크를 지속조회를 하면 성능 저하가 발생하고 이를 막기 위하여 메모리공간에 이러한 메타 데이터들을 보관하는 공간을 마련했는데 그게 바로 테이블 캐시다. 5.1.2 이전 버전에서는 table_cache 파라미터로 조절했으나 그 이후 버전에서는 table_open_cache 로 바뀌었다. 이 또한 쿼리 캐쉬와 마찬가지로 성능과 관련 된 파라미터인데 아래의 링크들을 참조하면 좋다.(small-dbtalk.blogspot.com/2013/09/mysql-table-cache.html, www.mysqlkorea.com/sub.html?mcode=manual&scode=01_1&m_no=22536&cat1=827&cat2=965&cat3=1002&lang=k)
로그 버퍼
리두 로그 파일에 쓰여질 내용들을 보관하는 공간이다. 마찬가지로 메모리 활용 없이 지속적인 디스크 쓰기는 성능 저하를 유발하기에 리두 로그 파일들에 쓰여질 내용들에 대해서 어느정도 보관을 하고 있다가 디스크에 써내리는 특정 조건이 되면 메모리에서 디스크로 해당 내용들을 써내리는 flush 동작을 하게함으로써 리두 로그 파일에 작성된다.
관련된 파라미터는 innodb_log_buffer_size 로 크기를 조절하며, 디스크 영역에서는 innodb_log_file_size, innodb_log_files_in_group 으로 리두 로그파일 크기 및 파일 그룹 및 개수를 조절한다.
기타 성능과 관련된 추가 파라미터 내용들은 아래의 링크를 참조한다.
(ssup2.github.io/theory_analysis/MySQL_Buffer_Pool_Redo_Log_Log_Buffer/)
로컬 메모리 영역
커넥션 버퍼, Result 버퍼
외부 클라이언트들이 DB서버를 사용시, 이에 대한 DB 데이터 사용 공간을 DB서버 메모리내에서 사용 해 줄 수 있도록 배정해 주는 공간이다. 기본적으로 net_buffer_length 파라미터 값에 근거하여 배정이 되나 각 세션들이 배정된 공간이외의 더 큰 공간을 원하면 max_allowed_packet 파라미터에 근거한 최대값까지 증가 할 수 있다. 5.1 버전 이전까지는 기본 16kb 에서 1kb~1mb 범위로 조절이 가능했으나, 그 이후 버전은 허용하지 않는다.
Read 버퍼
데이터를 순차적으로 읽어 들일 때, 사용하는 공간이다. 관련 파라미터는 read_buffer_size 다.
랜덤 Read 버퍼
정렬이 되어 있지 않은 데이터를 정렬 후 읽어 들이는 등의 임의의 순서대로 데이터를 읽어 들일 때 사용하는 공간이다. 관련 파라미터는 read_rnd_buffer_size 다.
조인(join) 버퍼
말 그대로 Join 에서 사용 할 때, 사용하는 버퍼 공간이다. 이 공간은 단순 Join 이 아닌 특정쿼리를 옵티마이저가 실행 계획을 세울 시, 실행 계획 type 이 ALL 이나 index 같이 여러 테이블들에 한번에 묶을 수 있는 공용 key 가 없는 Join 문에 사용 한다. Join_buffer_size 로 크기를 조절 할 수 있다.
정렬(sort) 버퍼
정렬 작업 대상 테이블에 정렬을 위해 사용 할 인덱스가 없을 시, 사용하는 공간이다. MySQL / MariaDB 는 이 공간을 통하여 인덱스가 없는 테이블에 using filesort 라는 추가 실행 계획을 세워 데이터를 정렬한다. Sort_buffer_size 파라미터로 조절이 가능하며, 이 값이 너무 적으면 디스크 I/O 유발로 성능이 저하 되므로, 성능 테스트를 통한 적절한 값을 부여 하는 것이 좋다.
'MySQL > 아키텍처 및 내부 구조' 카테고리의 다른 글
MySQL / MariaDB 기본 아키텍처 (Data - InnoDB) (0) | 2021.03.30 |
---|---|
MySQL / MariaDB 기본 아키텍처 (쿼리 실행 과정) (0) | 2021.03.16 |
MySQL / MariaDB (InnoDB 기준) index 종류 (0) | 2021.03.10 |
MySQL / MariaDB Lock 종류 (InnoDB 기준) (0) | 2021.03.05 |
MySQL / MariaDB 트랜잭션 Isolation Level (0) | 2021.03.03 |