mysql, mysql 엔진의 구조와 동작 방식

MySQL의 전체 구조

  • MySQL 서버는 크게 MySQL 엔진과 스토리지 엔진으로 구분한다.
    • MySQL 엔진: 클라이언트의 접속, 쿼리요청을 처리하는 커넥션 핸들러와 SQL 파서 및 전처러기, 쿼리 최적화 실행을 위한 옵티마이저
    • 스토리지 엔진: 실제 데이터를 디스크 스토리지에 저장하거나 읽음

MySQL 스레딩 구조

  • MySQL 서버는 프로세스 기반이 아닌 스레드 기반으로 작동.
  • 포그라운드와 백그라운드로 구분.
  • MySQL 엔터프라이즈 혹은 Percona Server 플러그인으로 스레드 풀을 선택할 수 있음. 다만, 저자의 경험 상 스레드풀로 인한 성능 개선은 드물다고 함.

포그라운드 스레드(클라이언트 스레드)

  • 포그라운드 스레드는 각 클라이언트 사용자가 요청하는 쿼리 문장을 처리.
  • 포그라운드 스레드는 MySQL 서버에 접속된 클라이언트의 수만큼 존재.
  • 클라이언트 사용자가 작업을 마치고 커넥션을 종료하면, 해당 커넥션을 담당하던 스레드는 thread_cache_size 변수에 따라 다시 스레드 캐시로 되돌아 가거나 제거됨.
  • 읽기: 데이터를 우선적으로 버퍼 혹은 캐시로부터 가져온다. 없을 경우, 직접 디스크의 데이터나 인덱스 파일로부터 데이터를 읽는다.
  • 쓰기: InnoDB 기준으로 지연된 쓰기를 지원하며 버퍼나 캐시에 반영한다. 디스크에 저장은 백그라운드 스레드가 처리한다.

백그라운드 스레드

  • MyISAM에 대비하여 InnoDB의 백그라운드 스레드가 담당하는 업무가 확장되었다. 로그 스레드와 쓰기 쓰레드가 주요 백그라운드 스레드.
  • 읽기는 절대 지연될 수 없으므로 포그라운드가 처리한다. 쓰기의 경우 지연(버퍼링) 가능하며 MyISAM과 달리 InnoDB는 해당 기능을 제공한다.

메모리 할당 및 사용 구조

  • MySQL의 메모리는 글로벌 영역과 로컬(커넥션) 영역으로 구분한다.

글로벌 메모리 영역

  • 글로벌 메모리 영역은 단 하나의 공간만 할당 된다.
  • 필요에 따라 하나 이상 할당될 수 있더라도 모든 스레드에 공유된다.
  • 대표적인 글로벌 메모리 영역은 다음과 같다.
    • 테이블 캐시
    • InnoDB 버퍼 풀
    • InnoDB 어댑티브 해시 인덱스
    • InnoDB 리두 로그 버퍼
  • 글로벌 메모리 영역을 설정할 수 있으며 이는 최대치를 설정하는 것과 같다. 왜냐하면 실제 할당량이나 할당 방식은 운영체제의 처리 방식에 따라 결정되기 때문이다.

로컬(커넥션, 세션) 메모리 영역

  • 클라이언트 스레드가 쿼리를 처리하는데 사용하는 영역.
  • 로컬 메모리 영역은 각 클라이언트 스레드별로 독립적으로 할당되며 절대 서로 공유되지 않는다.

플러그인 스토리지 엔진 모델

  • MySQL에 존재하는 독특한 구조 중 하나.
  • 전문 검색 엔진을 위한 검색어 파서, 사용자 인증을 위한 Native Authentication 등 다양한 기능이 플러그인이 내장되어 있음.
  • 필요에 따라 사용자 플러그인을 개발하여 사용 가능.
  • 스토리지 엔진 역시 플러그인 형태로 동작.
    • MySQL의 처리 과정은 스토리지 엔진과 관계 없이 거의 동일하게 처리됨.
    • MySQL 엔진 영역과 스토리지 엔진의 영역을 구분하는 것은 MySQL 관리에 중요.
  • 플러그인의 몇 가지 단점을 보완하기 위한 아키텍처로 컴포넌트가 있음.

쿼리 실행 구조

  • 쿼리 파서: 쿼리 문장을 토큰으로 분리하여 트리 형태의 구조로 만드는 작업. 문법 오류 검토.
  • 전처리기: 쿼리 문장의 구조적인 문제를 확인. 테이블 이름, 칼럼 이름, 내장 함수, 접근 권한을 검토.
  • 옵티마이저: 쿼리 문장을 저렴한 비용으로 가장 빠르게 처리하기 위하여 어떻게 할지 결정하는 역할. DBMS의 두뇌 역할.
  • 실행 엔진: 옵티마이저가 결정한 실행 계획에 따라 핸들러에게 데이터를 요청하고 처리하는 역할.
  • 핸들러(스토리지 엔진): 실행 엔진의 요청에 따라 데이터를 디스크로 읽고 저장하는 역할.

트랜잭션을 지원하는 메타데이터

  • MySQL 5.7 이전에는 메타데이터를 파일 기반으로 관리하며 트랜잭션을 지원하지 않음. 비정상적인 서버 종료에서 파일과 데이터 간 일관성이 깨지는 경우가 있었음.
  • 8.0 이후 테이블의 구조 정보나 스토어드 프로그램의 코드 관련 정보는 모두 InnoDB 테이블에 저장하도록 개선. 이로 인하여 스키마 변경 작업 도중 서버가 비정상적으로 종료되더라도 스키마 변경은 완전한 성공 혹은 실패를 보장할 수 있게 됨.
  • 시스템 테이블과 데이터 딕셔너리 정보는 통째로 mysql.ddb라는 테이블 스페이스에 저장 및 관리.

쿼리 캐시

  • SQL의 실행 결과를 메모리에 캐시하고, 동일 SQL 쿼리가 실행되면 테이블을 읽지 않고 즉시 결과를 반환.
  • 다만, 성능 및 버그 문제로 8.0 이후 제거.

RealMySQL 8.0, 4장을 참고하여 작성하였습니다.