과정을 즐기자

MySQL 엔진 아키텍처 본문

Database

MySQL 엔진 아키텍처

320Hwany 2023. 7. 11. 15:50

MySQL 서버는 사람의 머리 역할을 담당하는 MySQL 엔진 과 손발 역할을 담당하는 스토리지 엔진 으로 구분할 수 있습니다.

이번 글에서는 MySQL 서버의 전체적인 구조와 MySQL 엔진에 대해서 작성해보겠습니다.  

MySQL의 전체 구조

MySQL의 전체 구조는 위 그림과 같습니다. MySQL은 일반 상용 RDBMS와 같이 대부분의 프로그래밍 언어로부터  

접근 방법을 모두 지원합니다. MySQL 고유의 C API 부터 시작해 JDBC, ODBC 등을 제공합니다.   

이러한 라이브러리를 이용해 모든 언어로 MySQL 서버에서 쿼리를 사용할 수 있게 지원합니다.  

 

여기서 MySQL 엔진은 커넥션 핸들러, SQL 파서, 전처리기, 옵티마이저, 쿼리 실행기로 이루어지는데  

각각의 요소에 대해 알아보겠습니다.

MySQL 엔진

커넥션 핸들러

커넥션 핸들러는 클라이언트로부터의 접속 및 쿼리 요청을 처리합니다.

SQL 파서

SQL 파서는 사용자 요청으로 들어온 쿼리 문장을 MySQL이 인식할 수 있는 최소 단위의 어휘나 기호인 토큰으로 분리해   

트리 형태의 구조(파서 트리)로 만들어냅니다. 쿼리 문장의 기본 문법 오류는 이 과정에서 발견되고 사용자에게 오류 메세지를

전달하게 됩니다.

전처리기

파서 과정을 통해 만들어진 파서 트리를 기반으로 쿼리 문장에 구조적인 문제점이 있는지 확인합니다.

각 토큰을 테이블 이름이나 컬럼 이름 또는 내장 함수와 같은 개체를 매핑해 해당 객체의 존재 여부와 객체의 접근 권한 등을  

확인하는 과정을 이 단계에서 수행합니다.  

옵티마이저

옵티마이저는 사용자의 요청으로 들어온 쿼리 문장을 저렴한 비용으로 가장 빠르게 처리할지를 결정하는 역할을 담당하며

DBMS의 두뇌에 해당한다고 볼 수 있습니다. 

실행 엔진

옵티마이저가 두뇌라면 실행 엔진은 중간 관리자 핸들러(스토리지 엔진)는 각 업무의 실무자로 비유할 수 있습니다.

실행 엔진은 만들어진 계획대로 각 핸들러에게 요청해서 받은 결과를 또 다른 핸들러 요청의 입력으로 연결하는   

역할을 수행합니다.

스토리지 엔진(핸들러)

MySQL의 실행엔진의 요청에 따라 테이터를 디스크로 저장하고 디스크로부터 읽어 오는 역할을 합니다. 

MySQL의 대표적인 스토리지 엔진은 InnoDB이며 스토리지 엔진에 대한 더 자세한 내용은 다음 글에 작성하겠습니다.

MySQL 스레딩 구조

MySQL 서버는 프로세스 기반이 아니라 스레드 기반으로 작동하며 크게 포그라운드 스레드백그라운드 스레드로   

구분할 수 있습니다.

 

포그라운드 스레드는 최소한 MySQL 서버에 접속된 클라이언트의 수만큼 존재하며 주로 각 클라이언트 사용자가 

요청하는 쿼리 문장을 처리합니다. InnoDB 테이블은 데이터 버퍼나 캐시까지만 포그라운드 스레드가 처리하고 

나머지 버퍼로부터 디스크까지 기록하는 작업은 백그라운드 스레드가 담당합니다.

 

백그라운드 스레드에서 가장 중요한 스레드들은 로그 스레드쓰기 스레드입니다.

InnoDB에서 데이터를 읽는 작업은 주로 클라이언트 스레드에서 처리되기 때문에 읽기 스레드는 많이 설정할 필요가 없지만

쓰기 스레드는 아주 많은 작업을 백그라운드로 처리하기 때문에 더 많은 스레드가 필요합니다.

일반적인 사용 DBMS에는 대부분 쓰기 작업을 버퍼링해서 일괄 처리하는 기능이 탑재되어 있고 InnoDB 또한 이러한 방식으로 

처리합니다. 

 

스레드 풀

MySQL 서버 엔터프라이즈 에디션은 스레드 풀 기능을 제공하지만 MySQL 커뮤니티 에디션은 스레드 풀 기능을 지원하지 않습니다.

따라서 Percona Server에서 제공하는 스레드 풀 기능에 대해 알아보겠습니다.

스레드 풀은 내부적으로 사용자의 요청을 처리하는 스레드 개수를 줄여서 동시 처리되는 요청이 많다 하더라도

MySQL 서버의 CPU가 제한된 개수의 스레드 처리에만 집중할 수 있게 해서 서버의 자원 소모를 줄이는 것이 목적입니다.

일반적으로는 CPU 코어의 개수와 스레드 그룹의 개수를 맞추는 것이 CPU 프로세서 친화도를 높이는 데 좋습니다.  

 

만약 스레드 풀을 사용하지 않은 전통적인 스레드 모델을 사용한다면 커넥션별로 포그라운드 스레드가 하나씩 생성되고 할당됩니다.

스레드 풀을 사용하면 하나의 스레드가 여러 개의 커넥션 요청을 전담합니다.

메모리 할당 및 사용 구조

MySQL에서 사용되는 메모리 공간은 크게 글로벌 메모리 영역로컬 메모리 영역으로 구분할 수 있습니다.

글로벌 메모리 영역은 일반적으로 클라이언트 스레드의 수와 무관하게 하나의 메모리 공간만 할당하여 여러 스레드가 

공유하여 사용합니다. (물론 2개이상의 메모리 공간을 할당할 수도 있지만 클라이언트 스레드 수와는 무관)

대표적인 글로벌 메모리 영역에는 테이블 캐시,  InnoDB 버퍼풀, InnoDB 어댑티브 해시 인덱스, InnoDB 리두 로그 버퍼가 있습니다.

 

로컬 메모리 영역은 세션 메모리 영역이라고도 표현하며 MySQL 서버상에 존재하는 클라이언트 스레드가 쿼리를 처리하는 데  

사용하는 메모리 영역입니다. 각 클라이언트 스레드별로 독립적으로 할당되며 절대 공유되어 사용되지 않습니다.

대표적인 로컬 메모리 영역에는 정렬 버퍼, 조인 버퍼, 바이너리 로그 캐시, 네트워크 버퍼가 있습니다.

 

출처 : Real MySQL 8.0 1권