RealMySQL 8.0 (4장 아키텍처)
4.1 MySQL 엔진 아키텍처
크게 MySQL 서버의 구조를 나누었을 때 3가지로 나눌 수 있다.
MySQL 엔진
- 클라이언트로부터의 접속 및 쿼리 요청을 처리하는 커넥션 핸들러
- SQL파서 및 전처리기, 옵티마이저 등으로 이루어짐
스토리지 엔진
- 실제 데이터를 디스크 스토리지에 저장하거나 디스크 스토리지로 부터 데이터를 읽어오는 역할
- InnoDB, MyISAM ...
- MySQL 서버에서 MySQL 엔진은 하나지만, 스토리지 엔진은 여러 개를 동시에 사용 가능
- 각 스토리지 엔진은 성능 향상을 위해 키 캐시나 InnoDB 버퍼 풀과 같은 기능을 내장
핸들러 API
- MySQL 엔진의 쿼리 실행기에서 데이터를 쓰거나 읽을 때 각 스토리지 엔진에 쓰기/읽기를 요청하는 것을 핸들러 요청이라 하고, 여기서 사용되는 API
4.1.2 MySQL 스레딩 구조
MySQL 서버는 프로세스 기반이 아닌 쓰레드 기반으로 작동
-Foreground, Background 스레드로 구성
Foreground 스레드(클라이언트 스레드)
- MySQL 서버에 접속한 클라이언트의 수만큼 존재
- 클라이언트 사용자가 요청하는 쿼리문장을 처리
- 커넥션이 종료되면 쓰레드 최대 쓰레드 개수(
thread_cache_size
option)에 따라 캐시로 돌아가거나 종료
Storage 엔진에 따른 스레드의 역할 차이
MyISAM 테이블 : 디스크 쓰기 작업까지 포그라운드 스레드가 처리
InnoDB 테이블 : 데이터 버퍼나 캐시까찌만 포그라운드 스레드가 처리, 버퍼<->디스크는 백그라운드 스레드가 처리
Background 스레드
MyISAM의 경우에는 별로 해당 사항이 없지만, InnoDB는 여러 작업을 백그라운드로 처리
- 인서트 버퍼(Insert Buffer)를 병합하는 스레드
- 로그를 디스크에 기록하는 스레드
- InnoDB 버퍼풀의 데이터를 디스크에 기록하는 스레드
- 데이터를 버퍼로 읽어들이는 스레드
- 기타 여러가지 잠금이나 모니터링 스레드
- 이러한 모든 스레드를 총괄하는 메인 스레드 등 존재
쓰기 스레드, 로그 스레드
- 읽기는 클라이언트 스레드에서 처리하기 때문에 많을 필요가 없으나, 쓰기 스레드는 많은 작업을 백그라운드로 처리하여 2~4개 정도 설정하는게 좋음
- 쓰기 작업은 지연(버퍼링)되어 처리될 수 있지만 읽기는 불가능
- InnoDB : 쓰기 작업을 버퍼링하여 일괄처리 하는 기능이 내장되어 디스크의 데이터파일로 저장될 때까지 기다리지 않아도 됨
- MyISAM : 클라이언트 스레드가 쓰기 작업까지 함꼐 처리해 일반적인 쿼리는 완전히 저장될 때 까지 기다려야함
4.1.3 메모리 할당 및 사용 구조
글로벌 메모리 영역
- 하나의 메모리 공간만 할당(운영체제로부터 할당받음)
- 모든 쓰레드에 의해 공유
- 테이블 캐시, InnoDB 버퍼 풀, InnoDB 어댑티브 해시 인덱스, InnoDB 리두 로그 버퍼
로컬(세션) 메모리 영역
- 클라이언트 쓰레드가 사용하는 메모리 공간
- 공유되어 사용되지 않는다
- 정렬 버퍼, 조인 버퍼, 바이너리 로그 캐시, 네트워크 버퍼
- 소트 버퍼나 조인 버퍼같은 공간은 필요할 때만 할당될 수 있기 때문에 필요하지 않은 경우 MySQL이 메모리 공간을 할당조차 하지 않을 수도 있다.
4.1.4 플로그인 스토리지 엔진 모델
쿼리가 실행되는 과정은 대부분 MySQL엔진에서 처리되고, 마지막 데이터 읽기/쓰기 작업만 스토리지 엔진에 의해 처리
핸들러
- 어떤 기능을 호출하기위해 사용하는 객체
- MySQL 엔진이 스토리지 엔진을 조정하기 위해 핸들러를 사용
- MySQL 엔진이 각 스토리지 엔진에게 데이터를 읽어오거나 저장하도록 명령하려면 반드시 핸들러를 통해야 함
MySQL 서버에서 지원하는 스토리지 엔진
플러그인 아키텍처 문제점
- 플러그인끼리 서로 통신 불가
- 캡슐화 되지 않는다.
- 플러그인 간의 상호 의존 관계를 설정할 수 없어서 초기화가 어려움
4.1.5 컴포넌트 아키텍처
MySQL 8.0부터 플러그인의 문제점을 보완하기 위해 도입된 아키텍처
- 사용자에게는 플러그인과 컴포넌트는 동일하게 보인다.
4.1.6 쿼리 실행 구조
- 쿼리 파서
- 쿼리 문장 -> 토큰(MySQL이 인식할 수 있는 최소 단위의 어휘나 기호)으로 분리 후, 트리 형태 구조로 만듦
- 쿼리 문장의 문법 오류는 이 과정에서 발견
- PreProcessor(전처리기)
- 쿼리 문장에 구조적인 문제점 확인 (각 토큰의 테이블, 칼럼에 대한 객체 매핑 및 접근 권한 확인)
- 실제 존재하지 않거나 권한상 사용할 수 없는 개체의 토큰은 이 단계에서 걸러집니다.
- 옵티마이저
- 어떻게 하면 옵티마이저가 더 나은 선택을 할 수 있게 유도하는 과정 : MySQL 성능 최적화
- 실행 엔진
- 실행 엔진과 핸들러는 손과 발에 비유
- 실행 엔진은 핸들러에게 임시 테이블을 만들라고 요청합니다.
- 다시 실행 엔진은 WHERE 절에 일치하는 레코드를 읽어오라고 핸들러에게 요청합니다.
- 읽어온 레코드들을 1번에서 준비한 임시 테이블로 저장하라고 다시 핸들러에 요청합니다.
- 데이터가 준비된 임시 테이블에서 필요한 방식으로 데이터를 읽어오라고 핸들러에게 다시 요청합니다.
- 최종적으로 실행 엔진은 결과를 사용자나 다른 모듈로 넘깁니다.
- 실행 엔진과 핸들러는 손과 발에 비유
- 핸들러(스토리지 엔진)
- 핸들러는 MySQL 서버의 가장 밑단에서 MySQL 실행 엔진의 요청에 따라 데이터를 디스크로 저장하고 디스크로부터 읽어오는 역할을 담당
4.1.8 쿼리 캐시
- 성능상의 문제 야기 : 삭제되었다.
4.1.9 스레드 풀
요청마다 스레드를 생성하는 경우 오버헤드가 많이 발생
- 스레드 생성, 제거 비용
- 컨텍스트 스위칭
- 스레드 스케줄링 비용
일반적으로 스레드 풀을 제공하지는 않는다.
Percona Server에서 제공하는 쓰레드 풀
Percona Server : Percona 에서 만든 오픈 소스 MySQL 배포판
- 플러그인 형태로 구현
- 보통, CPU 코어의 개수만큼 쓰레드 그룹을 생성한다
4.1.10 트랜잭션 지원 메타데이터
테이블의 구조 정보나 스토어드 프로그램의 코드 관련 정보를 InnoDB에 저장하도록 개선
~ 5.7) 테이블 구조를 FRM 파일에 저장하고 일부 스토어드 프로그램도 파일 기반으로 관리
파일 기반 관리 방법 : 트랜잭션이 지원 X
-> 테이블을 생성, 변경 도중 장애가 발생하면 테이블이 깨지는 현상
MyISAM not support tx
cf) 간단한 MyISAM
vs InnoDB
- InnoDB 엔진은 트랜잭션 처리가 필요하고 대용량의 데이터를 다루는 부분에서 효율적
- MyISAM 엔진은 트랜잭션 처리가 필요 없고, Read only 기능이 많은 서비스일수록 효율적
- InnoDB는 데이터의 변화가 많은 서비스 적합
- MyISAM은 SELECT가 많은 서비스에 적합
'책 > RealMySQL' 카테고리의 다른 글
RealMySQL 5.1 - 트랜잭션 (0) | 2023.04.04 |
---|---|
RealMySQL 4.4 - MySQL 로그 파일(log file) (0) | 2023.03.18 |
RealMySQL 4.3 - MyISAM 스토리지 엔진 아키텍처 (0) | 2023.03.18 |
RealMySQL 4.2 - InnoDB 스토리지 엔진 아키텍쳐 (2) (0) | 2023.02.19 |
RealMySQL 4.2 - InnoDB 스토리지 엔진 아키텍쳐 (1) (0) | 2023.02.19 |