본문 바로가기
DB/MySQL

Real MySQL 04 서버 아키텍처 (1)

by yeonn108 2022. 3. 7.

- MySQL 서버는 MySQL 엔진과 스토리지 엔진으로 이루어져 있음

MySQL 엔진

- 커넥션 핸들러 : 클라이언트의 접속과 쿼리 요청을 처리함

- SQL 파서, 전처리기

- 옵티마이저 : 쿼리 최적화 담당

스토리지 엔진

- 실제 디스크 스토리지에 데이터 저장

- 디스크 스토리지로부터 데이터 읽어오기

MySQL 엔진은 하나지만, 스토리지 엔진은 동시에 여러개 사용 가능

테이블 생성 시 다음과 같이 스토리지 엔진을 지정할 수 있다. 해당 테이블에 대한 읽기, 변경 작업은 지정된 스토리지 엔진으로 처리하게 된다.

 

CREATE TABLE test (id INT, name VARCHAR(30)) ENGINE=INNODB;

 

- MySQL 엔진이 스토리지 엔진에서 데이터를 읽어오거나 저장하기 위해 핸들러를 거친다.
- GROUP BY나 ORDER BY 와 같은 복잡한 처리는 스토리지 엔진이 아닌, MySQL 엔진의 쿼리 실행기에서 처리된다.

- 하나의 쿼리 작업은 여러 하위 작업으로 나뉜다. 각 하위 작업은 MySQL 엔진스토리지 엔진에 의해서 실행된다.

 

SHOW ENGINES;

 

- 위의 명령어로 설치된 MySQL 서버에서 지원되는 스토리지 엔진을 확인할 수 있다.

핸들러 API

- MySQL 엔진이 쿼리 실행기에서 데이터를 읽거나 쓸 때, 각 스토리지 엔진에 쓰기나 읽기를 요청한다.

즉, Handler API를 이용해서 MySQL 엔진과 스토리지 엔진이 데이터를 주고받는 것

MySQL 스레딩 구조

MySQL 서버는 프로세스가 아닌 스레드 기반으로 작동한다.

- Foreground thread

- Background thread

- performance_schema.threads 를 통해서 MySQL 서버에서 실행 중인 스레드 목록을 볼 수 있음

Foreground thread (클라이언트 스레드)

- 주로 각 클라이언트가 요청하는 쿼리를 처리한다.

- thread_cache_size 시스템 변수로 스레드 캐시에 유지할 수 있는 최대 스레드 개수 설정 가능

- 클라이언트가 작업을 다 마치고 커넥션을 종료하면 -> 해당 스레드는 thread cache로 돌아간다.

- Foreground 스레드는 MySQL의 데이터 버퍼나 캐시로부터 데이터를 갖고 오고, 데이터가 없다면 디스크의 데이터나 인덱스 파일로부터 읽어온다.

- InnoDB는 버퍼나 캐시까지만 Foreground thread가 처리하고, 버퍼로부터 디스크로 기록하는 작업은 백그라운드 스레드가 처리함

- Foreground thread = 사용자 스레드

- 즉, 클라이언트의 요청을 처리해주는 스레드, 클라이언트에 할당되는 스레드

Background thread

- 로그를 디스크에 기록하고, InnoDB 버퍼풀의 데이터를 디스크에 기록, 데이터를 버퍼로 읽어오기, 잠금이나 데드락 모니터링 등의 작업을 수행하는 스레드가 백그라운드 스레드이다.

- 대부분 쓰기작업은 백그라운드 스레드가 진행하고, 읽기 작업은 포그라운드 스레드가 작업한다.

- 쓰기작업은 지연되어 처리가 가능하나, 읽기작업은 지연처리가 불가능하다.

MySQL의 메모리 공간과 구조

- 글로벌 메모리 영역과 로컬 메모리 영역으로 나뉜다.

 

글로벌 메모리 영역

- MySQL 서버가 시작되면서 운영체제로부터 시스템 변수로 설정한 만큼 할당된다.

- 클아이언트 스레드 수와 관계 없이 하나의 메모리 공강만 할당된다.

- 여러개의 글로벌 메모리 영역기 생성되라고 모든 스레드에 의해 공유된다.

- 테이블 캐시, Inno버퍼 풀, InnoDB 리두 로그버퍼 등이 해당됨



로컬 메모리 영역

- 세션 메모리 영역, 클라이언트 메모리 영역이라고도 불림

- 클라이언트 스레드가 쿼리를 처리하는데 사용하는 메모리 영역이다

- 각 클라이언트 스레드멸로 독립적으로 할당된다. 공유되는 공간이 아님

- 정렬 버퍼, 조인 버퍼, 바이너리 로그 캐시, 네트워크 버퍼 등이 해당됨

쿼리 실행 구조

쿼리 파서

- 사용자로부터 요청된 쿼리 문장을 토큰으로 분리해서 트리 형태 구조로 만든다.

토큰이란, MySQL이 인식할 수 있는 최소 단위의 어휘나 기호임

- 쿼리문의 Syntax error는 이 과정에서 발견된다.

 

전처리기

- 파서 과정에서 만들어진 파서 트리를 기반으로 쿼리문의 구조적인 것을 검증한다.

- 각 토큰을 table 이름, column 이름, 내장 함수 등과 매핑해서 각 객체의 존재여부, 접근 권한 등을 확인

 

옵티마이저

- 쿼리문을 저렴한 비용으로 가장 빠르게 처리하는 것을 결정

 

실행엔진

- 옵티마이저에 의해 최적화된 계획대로 각 핸들러에게 요청하고, 받은 결과를 또 다른 핸들러 요청의 입력으로 연결하는 역할

 

핸들러 (스토리지 엔진)

- 핸들러는 MySQL 실행 엔진의 요청에 따라 데이터를 디스크에 저장, 읽기를 한다.

- 핸들러는 곧 스토리지 엔진이다.

- MyISAM 테이블을 조작하면 핸들러는 MyISAM 스토리지 엔진이고, InnoDB 테이블을 조작하면 핸들러가 InnoDB 스토리지 엔진임

 

쿼리 캐시
- SQL 실행 결과를 메모리에 캐시하고, 동일한 SQL에 대한 결과를 빠르게 반환
-> 캐시에 저장된 것 중 변경된 테이블과 관련된 데이터는 invalidate 해야한다. -> 동시 처리 성능 저하 발생
- 이와 같은 문제로 MySQL 8.0 부터는 쿼리 캐시 기능이 제거되고, 관련된 시스템 변수도 제거됨

 

 

학습한 것을 상기시키며 정리했습니다. 출처: Real MySQL 8.0