MySQL 아키텍처
MySQL 커넥터
다양한 방식으로 다양한 언어에서 SQL을 사용할 수 있도록 도와준다. MySQL C API, JDBC, ODBC, .NET 표준 드라이버 등이 있다.
MySQL 엔진
MySQL의 두뇌 역할은 한다. SQL 문장을 분석하거나 최적화한다. 커넥션 핸들러, SQL 파서 및 전처리기, 옵티마이저가 중심을 이룬다.
MySQL 스토리지 엔진
MySQL의 손발 역할을 한다. MySQL 엔진이 SQL을 분석하고 실행계획을 작성하면 MySQL 스토리지 엔진은 그것에 맞게 실제 데이터를 디스크 스토리지에 저장하거나 가져온다. 대표적으로 InnoDB와 MyISAM이 있다.
핸들러 API
MySQL이 스토리지 엔진에게 읽기 또는 쓰기 요청을 보내는 것을 핸들러 요청이라 한다. 이때 사용되는 API를 핸들러 API라 한다. 핸들러 API만 구현되어 있다면 스토리지 엔진의 역할을 수행할 수 있다.
MySQL 스레딩 구조
MySQL 서버는 스레드 기반으로 동작한다. 크게 포그라운드 스레드와 백그라운드 스레드로 구분할 수 있다.
포그라운드 스레드(클라이언트 스레드)
MySQL 서버에 접속된 클라이언트의 수만큼 존재한다. 주로 쿼리문장을 처리한다. 작업이 완료되면 해당 커넥션을 담당하던 스레드는 스레드 캐시로 되돌아간다. 이때 스레드 캐시에 일정 개수 이상의 대기중인 스레드가 있다면 스레드를 종료시킨다. 즉, 스레드 캐시의 스레드 개수를 유지한다.
MySQL 서버의 스레드 모델은 스레드 풀과 다르다. MySQL 서버는 커넥션과 1:1로 스레드를 생성하지만 스레드 풀은 스레드가 여러 개의 커넥션을 요청을 관리한다. 엔터프라이즈 버전에서는 스레드 풀 모델을 사용할 수 있다.
포그라운드 스레드는 데이터 버퍼, 캐시에서 데이터 읽기 작업을 직접 수행한다. 두 곳에 데이터가 없다면 디스크나 인덱스 파일로부터 데이터를 읽어온다. MyISAM 테이블은 데이터 쓰기 작업을 포그라운드 스레드가 처리하지만 InnoDB테이블은 데이터 쓰기 작업을 백그라운드 스레드가 처리한다.
백그라운드 스레드
InnoDB는 다음과 같은 작업을 여러 백그라운드 스레드로 처리한다.
- 인서트 버퍼를 병합하는 스레드
- 로그를 디스크에 기록하는 스레드
- InnoDB 버퍼 풀의 데이터를 디스크에 기록하는 스레드
- 데이터를 버퍼로 읽어 오는 스레드
- 잠금이나 데드락을 모니터링하는 스레드
중요한 스레드는 로그를 기록하는 스레드와 버퍼의 데이터를 디스크로 내려쓰는 작업을 하는 스레드이다. 데이터를 읽는 작업은 클라이언트 스레드에서 처리되기 때문에 많은 수의 스레드를 설정할 필요가 없다. 하지만 쓰기 스레드는 많은 작업을 수행하기 때문에 디스크 최적으로 사용할 수 있을 만큼의 충분한 개수로 설정해 주어야 한다.
사용자의 쓰기 작업은 지연될 수 있으나 읽기 작업은 지연될 수 없다. 그래서 대부분의 DBMS가 쓰기 버퍼링을 지원한다. InnoDB 또한 이러한 방식으로 처리한다. 따라서 DML로 데이터가 변경되는 경우 쓰기 작업이 완료될 때 까지 기다리지 않아도 된다. 하지만 MyISAM은 그렇지 않고 사용자 스레드가 쓰기 작업까지 처리한다. 따라서 MyISAM에서 일반적인 쿼리는 쓰기 버퍼링 기능을 사용할 수 없다.
메모리 할당 및 사용 구조
글로벌 메모리 영역
MySQL서버가 시작되면서 운영체제로부터 할당된다. 모든 스레드에 의해 공유된다. 대표적인 글로벌 영역은 다음과 같다.
- 테이블 캐시
- InnoDB 버퍼 풀
- InnoDB 어뎁티브 해시 인덱스
- InnoDB 리두 로그 버퍼
로컬 메모리 영역
세션 메모리 영역이라고도 표현한다. 클라이언트 스레드가 쿼리를 처리하는데 사용하는 메모리 영역이다. 스레드별로 독립적으로 할당되며 공유되어 사용되지 않는다. 각 쿼리의 용도별로 필요할 때만 공간이 할당되고 필요하지 않은 경우에는 할당되지 않을 수 있다. 쿼리를 실행하는 순간에만 할당했다 해제하는 공간(소트 버퍼, 조인 버퍼)과 커넥션이 열려있는 동안 계속 할당된 상태로 남아 있는 공간(커넥션 버퍼, 결과 버퍼)도 있다.
플러그인 스토리지 엔진 모델
MySQL은 플러그인 모델을 사용한다. 코어 기능에 플러그인들을 추가해 부가적인 기능을 제공한다. 스토리지 엔진도 플러그인이다.
SQL을 분석하고 어떻게 실행할지는 MySQL 엔진이 정하지만 디스크에서 데이터를 읽고 쓰는 작업은 스토리지 엔진이 처리한다. MySQL 엔진이 핸들러를 통해 스토리지 엔진으로 부터 데이터를 읽거나 저장하는 것이다. 하지만 GOUP BY나 ORDER BY 등 복잡한 쿼리는 MySQL 엔진에서 실행된다.
하나의 쿼리 작업은 여러 하위 작업으로 나뉜다. 각 하위 작업이 MySQL 엔진에서 처리되는지 스토리지 엔진에서 처리되는지 구분할줄 알아야 한다.
스토리지 엔진 외에도 다양한 기능이 플러그인으로 존재한다. 인증이나 전문 검색파서 또는 쿼리 재작성과 같은 플러그인이 있다.
컴포넌트
MySQL 8.0부터 플러그인 아키텍처의 단점을 보완하기 위해 컴포넌트 아키텍처가 지원된다. 플러그인 아키텍처는 다음과 같은 단점이 있다.
- 플러그인은 오직 MySQL 서버와 인터페이스할 수 있고, 플러그인끼리는 통신할 수 없다.
- 플러그인은 MySQL 서버의 변수나 함수를 직접 호출하여 안전하지 않다.(캡슐화 X)
- 플러그인은 상호 의존 관계를 설정할 수 없어서 초기화가 어렵다.
컴포넌트 아키텍처는 위와 같은 단점을 보완했다.
'Database' 카테고리의 다른 글
[MySQL] InnoDB 스토리지 엔진 아키텍처 - 3 (0) | 2023.02.08 |
---|---|
[MySQL] InnoDB 스토리지 엔진 아키텍처 - 2 (2) | 2023.02.01 |
[MySQL] InnoDB 스토리지 엔진 아키텍처 - 1 (0) | 2023.01.11 |
[MySQL] MySQL 쿼리 실행 구조 (0) | 2023.01.10 |
[DB] SQL JOIN (0) | 2023.01.06 |