MySQL 엔진 아키텍처

hs·2025년 11월 2일

MySQL 엔진

  • 커넥션 핸들러: 클라이언트로부터 접속 및 쿼리 요청을 처리
  • SQL 파서 및 전처리기: 문장 분석
  • 옵티마이저: 쿼리 최적화
  • 서버에 하나만 존재

스토리지 엔진

  • 실제 데이터를 디스크 스토리지에 저장 하거나 읽는 역할
  • 여러 개의 엔진을 동시에 사용 가능
  • 성능 향상을 위해 키 캐시(MyISAM)나 버퍼 풀(InnoDB)과 같은 기능을 내장한다.
  • 핸들러 API를 만족하면 누구든지 스토리지 엔진을 구현해서 MySQL 서버에 추가해서 사용할 수 있다.
  • 핸들러 API: MySQL 엔진의 쿼리 실행기가 스토리지 엔진에 쓰기 또는 읽기 요청(핸들러 요청)할 때 사용되는 API

스레딩 구조

  • MySQL은 프로세스 기반이 아닌 스레드 기반으로 작동
  • 포그라운드 스레드와 백그라운드 스레드로 구분
  • 포그라운드 스레드 (클라이언트 스레드)
    • MySQL 서버에 접속된 클라이언트의 수만큼 존재 (최소)
    • SQL 쿼리 처리, 쿼리 파싱, 최적화, 실행 및 결과 반환
    • 커넥션을 종료하면 담당 스레드는 스레드 캐시로 돌아간다.
    • 스레드 캐시에 일정 개수 이상의 대기 중인 스레드가 있으면 캐시에 넣지 않고 스레드를 종료시킨다.
      • 일정 개수의 스레드만 스레드 캐시에 존재하게 한다.
    • 데이터를 MySQL의 데이터 버퍼나 캐시로부터 가져온다.
      • 버퍼나 캐시에 없는 경우 직접 디스크의 데이터나 인덱스 파일로부터 읽어온다.
  • 백그라운드 스레드
    • 내부 작업을 처리하는 스레드
    • 5.5 버전부터 쓰기와 데이터 읽기 스레드의 개수를 2개 이상 지정 가능

메모리 할당 및 구조

  • 글로벌 메모리 영역
    • MySQL 서버가 시작되면서 운영체제로부터 할당
    • 클라이언트 스레드의 수와 무관하게 하나의 메모리 공간만 할당
    • 모든 스레드에서 공유
  • 로컬 메모리 영역(세션 메모리 영역)
    • 쿼리를 처리하는 데 사용하는 메모리 영역
    • 각 클라이언트 스레드별로 독립적으로 할당 (공유되지 않는다)
    • 필요할 때만 공간 할당

플러그인

  • 스토리지 엔진을 플러그인 형태로 지원
  • 유연하고 확장성이 좋다
  • 플러그인끼리는 서로 직접 통신 불가능 → 서버 코드를 통해 상호작용해야함
  • 동일한 전역 심볼 공간을 공유해 변수나 함수 이름의 충돌 문제가 발생할 수 있다.
  • 캡슐화가 되어있지 않아 안전하지 않음 (서버 변수나 함수를 직접 호출)
  • 상호 의존 관계를 설정할 수 없어 초기화가 어려움

컴포넌트

  • 8.0부터 지원
  • 플러그인 시스템을 대체하기 위한 아키텍처
  • 서비스라는 개념을 통해 상호작용
    • 각 컴포넌트는 서비스를 제공하고 다른 컴포넌트의 서비스를 사용할 수 있다
  • 자체 심볼 공간을 가져 이름 충돌 문제가 없다.
  • 의존성을 명시적으로 선언하고 이를 기반으로 초기화 및 종료 순서를 자동으로 관리

쿼리 실행 구조

  • 쿼리 파서
    • 쿼리 문장을 토큰으로 분리해 트리 형태의 구조로 만들어 내는 작업
    • 기본 문법 오류 확인
  • 전처리기
    • 파서 트리를 기반으로 쿼리 문장에 구조적인 문제점이 있는지 확인
    • 테이블, 컬럼, 내장 함수 등의 개체와 매핑해 존재 여부, 접근 권한등을 확인하는 과정
  • 옵티마이저
    • 쿼리를 최적화하는 역할
  • 실행 엔진
    • 핸들러에게 작업을 요청하고 받은 결과를 다른 핸들러의 요청으로 연결하는 역할
  • 핸들러(스토리지 엔진)
    • 실행 엔진의 요청에 따라 데이터를 디스크로 저장하고 읽어오는 역할

스레드 풀

  • CPU의 코어 개수 만큼 스레드 그룹을 생성한다.
    • 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 서버가 작동하는 데 기본적으로 필요한 테이블(인증, 권한 관련 등)
profile
sh

0개의 댓글