MySQL 엔진
- 커넥션 핸들러: 클라이언트로부터 접속 및 쿼리 요청을 처리
- SQL 파서 및 전처리기: 문장 분석
- 옵티마이저: 쿼리 최적화
- 서버에 하나만 존재
스토리지 엔진
- 실제 데이터를 디스크 스토리지에 저장 하거나 읽는 역할
- 여러 개의 엔진을 동시에 사용 가능
- 성능 향상을 위해 키 캐시(MyISAM)나 버퍼 풀(InnoDB)과 같은 기능을 내장한다.
- 핸들러 API를 만족하면 누구든지 스토리지 엔진을 구현해서 MySQL 서버에 추가해서 사용할 수 있다.
- 핸들러 API: MySQL 엔진의 쿼리 실행기가 스토리지 엔진에 쓰기 또는 읽기 요청(핸들러 요청)할 때 사용되는 API
스레딩 구조
- MySQL은 프로세스 기반이 아닌 스레드 기반으로 작동
- 포그라운드 스레드와 백그라운드 스레드로 구분
- 포그라운드 스레드 (클라이언트 스레드)
- MySQL 서버에 접속된 클라이언트의 수만큼 존재 (최소)
- SQL 쿼리 처리, 쿼리 파싱, 최적화, 실행 및 결과 반환
- 커넥션을 종료하면 담당 스레드는 스레드 캐시로 돌아간다.
- 스레드 캐시에 일정 개수 이상의 대기 중인 스레드가 있으면 캐시에 넣지 않고 스레드를 종료시킨다.
- 일정 개수의 스레드만 스레드 캐시에 존재하게 한다.
- 데이터를 MySQL의 데이터 버퍼나 캐시로부터 가져온다.
- 버퍼나 캐시에 없는 경우 직접 디스크의 데이터나 인덱스 파일로부터 읽어온다.
- 백그라운드 스레드
- 내부 작업을 처리하는 스레드
- 5.5 버전부터 쓰기와 데이터 읽기 스레드의 개수를 2개 이상 지정 가능
메모리 할당 및 구조
- 글로벌 메모리 영역
- MySQL 서버가 시작되면서 운영체제로부터 할당
- 클라이언트 스레드의 수와 무관하게 하나의 메모리 공간만 할당
- 모든 스레드에서 공유
- 로컬 메모리 영역(세션 메모리 영역)
- 쿼리를 처리하는 데 사용하는 메모리 영역
- 각 클라이언트 스레드별로 독립적으로 할당 (공유되지 않는다)
- 필요할 때만 공간 할당
플러그인
- 스토리지 엔진을 플러그인 형태로 지원
- 유연하고 확장성이 좋다
- 플러그인끼리는 서로 직접 통신 불가능 → 서버 코드를 통해 상호작용해야함
- 동일한 전역 심볼 공간을 공유해 변수나 함수 이름의 충돌 문제가 발생할 수 있다.
- 캡슐화가 되어있지 않아 안전하지 않음 (서버 변수나 함수를 직접 호출)
- 상호 의존 관계를 설정할 수 없어 초기화가 어려움
컴포넌트
- 8.0부터 지원
- 플러그인 시스템을 대체하기 위한 아키텍처
- 서비스라는 개념을 통해 상호작용
- 각 컴포넌트는 서비스를 제공하고 다른 컴포넌트의 서비스를 사용할 수 있다
- 자체 심볼 공간을 가져 이름 충돌 문제가 없다.
- 의존성을 명시적으로 선언하고 이를 기반으로 초기화 및 종료 순서를 자동으로 관리
쿼리 실행 구조
- 쿼리 파서
- 쿼리 문장을 토큰으로 분리해 트리 형태의 구조로 만들어 내는 작업
- 기본 문법 오류 확인
- 전처리기
- 파서 트리를 기반으로 쿼리 문장에 구조적인 문제점이 있는지 확인
- 테이블, 컬럼, 내장 함수 등의 개체와 매핑해 존재 여부, 접근 권한등을 확인하는 과정
- 옵티마이저
- 실행 엔진
- 핸들러에게 작업을 요청하고 받은 결과를 다른 핸들러의 요청으로 연결하는 역할
- 핸들러(스토리지 엔진)
- 실행 엔진의 요청에 따라 데이터를 디스크로 저장하고 읽어오는 역할
스레드 풀
- CPU의 코어 개수 만큼 스레드 그룹을 생성한다.
- 특정 개수 이상으로 스레드가 생성되는 것을 제한
- CPU가 제한된 개수의 스레드 처리에만 집중할 수 있도록 한다.
- 서버의 자원 소모를 줄인다.
- 불필요한 컨텍스트 스위치를 줄여 오버헤드를 낮출 수 있다.
- 주요 변수
- thread_pool_size: 스레드 그룹의 개수, CPU 코어와 개수를 맞추는 것을 권장
- thread_pool_oversubscribe: 스레드 그룹당 동시에 실행할 수 있는 추가 스레드 수 (기본값 3)
- 값이 너무 크면 스케줄링해야 할 스레드가 많아져 비효율적으로 작동할 수 있다.
- thread_pool_max_threads: 최대 허용 스레드 수
- thread_pool_stall_limit: 쿼리 실행 중 정체(stall) 상태 감지 (밀리초, 기본값 6000)
- 정의된 시간 동안 작업을 끝내지 못할 경우 새로운 스레드를 생성하여 스레드 그룹에 추가
- 모든 스레드풀이 작업을 처리중인 경우 정의된 시간 동안 기다려야 새로 들어온 요청을 처리 가능
- thread_pool_idle_timeout: 유휴 스레드 제거 시간(초, 기본값 60)
메타데이터 트랜잭션 지원
- 메타데이터(데이터 딕셔너리): 테이블의 구조 정보와 스토어드 프로그램 등의 정보
- 5.7버전까지 테이블의 구조를 파일에 저장하고 일부 스토어드 프로그램 파일 기반으로 관리했다
- 파일 기반의 메타데이터는 트랜잭션을 지원하지 않는다.
- 테이블의 생성 또는 변경 도중에 서버가 비정상적으로 종료되면 일관되지 않은 상태로 남는 문제가 있다.
- 8.0 버전부터 메타데이터와 시스템 테이블 모두 트랜잭션 기반의 InnoDB 스토리지 엔진에 저장
- 변경 작업 비정상적으로 종료되더라도 일관성을 보장한다.
- mysql.ibd 이름의 스페이스에 저장
- information_schema DB의 TABLES와 COLUMNS 등의 뷰를 통해 조회할 수 있다.
- InnoDB 외의 스토리지 엔진을 사용하는 테이블들은 SDI 파일을 사용한다.
- 시스템 테이블: MySQL 서버가 작동하는 데 기본적으로 필요한 테이블(인증, 권한 관련 등)