MySQL 엔진 아키텍처

Matthew Woo·2023년 1월 8일
0

Computer Science

목록 보기
11/12

RealMySQL 책의 [4.1 MySQL 엔진 아키텍처] 를 읽고 요약한 글 입니다.

Mysql 아키텍처

MySQL 엔진

  • 커넥션 핸들러(클라이언트의 접속 & 쿼리 처리), SQL파서, 전처리기, 옵티마이저

스토리지 엔진

  • 실제 데이터를 디스크에 저장, 읽어오는 부분 전담. 성능 항샹을 위해 키 캐시, 버퍼풀과 같은 기능을 내장하고 있다.

Mysql 엔진에서 스토리지 엔진에 read/write 요청을 할 때는 Handler API 로 호출한다.

이 API가 어떻게 호출되고 있는지는 SHOW GLOBAL STATUS LIKE 'Handler%'; 로 확인해볼 수 있다.

RealMysql1.0 챕터 4. 아키텍처 부분을 보면 저자는 MYSQL이 다른 DBMS에 비해 구조가 상당히 독특하다고 이로 인한 장단점이 있다고 한다.
어떤 부분이 독특한걸까?

MySQL 스레딩 구조

Mysql 서버(Mysql 엔진 + 스토리지 엔진)는 스레드 기반으로 동작.

Foreground, Background 스레드로 구분.

  • Foreground thread

    • 사용자 요청을 처리, 접속된 클라이언트 수 만큼 존재.
    • 커넥션 종료되면 스레드 캐시로 돌아감. 이미 일정 수가 스레드 캐시에 있으면 종료시킴
    • 데이터를 버퍼 or 캐시에서 가져오며 없을 경우는 직접 데이터나 인덱스 파일에서 데이터를 읽어옴.
    • MyISAM은 디스크까지 쓰기작업도 Foreground thread 가 진행.
  • Background thread

    • 로그를 디스크로 기록
    • InnoDB 버퍼 풀의 데이터를 디스크에 기록
    • 인서트 버퍼(보조 인덱스 update 시 발생하는 random IO를 막기 위한 버퍼) 병합
    • 데이터를 버퍼로 읽어오기
    • 잠금, 데드락 모니터링

메모리 할당 및 사용 구조

크게 글로벌 메모리, 로컬 메모리 영역으로 구분된다.

  • 글로벌 메모리 영역

    • 클라이언트 수와 무관하게 할당
    • 모든 스레드에 의해 공유
    • 시스템 변수 설정만큼 운영체제로부터 할당받음
    • 테이블 캐시, InnoDB 버퍼 풀, InnoDB 어댑티브 해시 인덱스, InnoDB 리두 로그 버퍼 가 글로벌 메모리 영역에 속함
  • 로컬(세션) 메모리 영역

    • 클라이언트가 쿼리 처리에 사용하는 메모리 영역
    • 클라이언트 별로 할당. 공유되지 않는 영역
    • 정렬 버퍼, 조인 버퍼, 바이너리 로그 캐시, 네트워크 버퍼
    • 커넥션, 결과 버퍼는 커넥션이 열려있는 동안 계속 할당된 상태로 남아있음. 소트, 조인 버퍼는 쿼리 실행 시에만 할당

플러그인, 컴포넌트

인증, 전문 검색 파서, 쿼리 재작성, 커넥션 제어, 비밀번호 검증 과 같은 다양한 플러그인을 지원함

플러그인은 다음과 같은 단점이 존재.

  • 플러그인은 오직 Mysql 서버와 인터페이스할 수 있어 플러그인끼리는 통신 불가능
  • Mysql 서버의 변수나 함수를 직접 호출하여 안전하지 않음(캡슐화 안됨)
  • 플러그인 간에 상호 의존 관계 설정이 불가능하여 초기화가 어려움

Mysql 8.0 부터는 플로그인 아키텍처를 대체하기 위해 컴포넌트 아키텍처를 지원함

쿼리 실행 구조

  • 쿼리 파서
    사용자 요청의 문장을 토큰으로 분리해 트리 구조 형태로 만들어내는 작업. 문법 오류는 여기서 캐치 됨

  • 전처리기
    위 과정에서 만들어진 트리 기반으로 문제점 있는 지 확인. 테이블, 컬럼 이름 내장 함수 등을 매핑하여 해당 요소의 존재 여부, 접근 권한 확인 등을 확인함

  • 옵티마이저

사용자 요청으로 들어온 쿼리를 저렴한 비용으로 처리할 수 있도록 담당한다.

  • 실행 엔진

쿼리 실행을 담당. 손발 과 같음.

-	실행 예시 (Group By가 처리 되는 과정)

1. 실행 엔진이 handler에 임시 테이블 만들도록 요청
2. where 절에 일치하는 데이터를 handler에 요청
3. 읽어 온 레코드를 임시테이블에 저장하도록 handler에 요청
4. 임시 테이블에서 필요한 방식으로 데이터 읽어 오도록 handler에 다시 요청
5. 실행 엔진이 결과를 사용자나 다른 모듈에 넘김

스레드 풀

Mysql 엔터프라이즈 의 경우 스레드 풀을 제공.

사용자의 요청을 처리하는 스레드 개수를 줄여서 동시 처리 요청이 많아도 제한 된 개수의 스레드로 처리량을 높이기 위함.
스레드 풀이 실제 서비스에서 눈의 띄는 성능 향상을 보여준 경우는 드물다.
CPU 시간을 제대로 확보하지 못하는 경우 쿼리 처리가 더 느려지는 사례도 발생 할 수 있음.
허나, 제한된 CPU 자원을 적절히 사용하고 불필요한 컨텍스트 스위칭 비용을 줄여서 오버헤드를 낮출 수 있다.

모든 스레드가 점유되어 있다면 스레드 풀이 새로운 스레드를 스레드풀에 추가 할지, 기다릴지 여부를 판단해야한다. 얼마의 밀리세컨드 만큼 기다릴지는 thread_pool_stall_limit 시스템 변수로 정의 되어 있다. 스레드 풀의 전체 개수는 thread_pool_max_threads 변수로 설정된다.

Percona Server의 스레드 풀 플러그인은 선순위 큐와 후순위 큐를 이용해 특정 트랜잭션, 쿼리를 우선적으로 처리하는 기능을 제공. 잠금이 빨리 해제되고 잠금 경합을 낮춰서 전체적인 처리 성능향상

트랜잭션 지원 메타데이터

Mysql 5.7 버전 까지는 테이블 구조 및 일부 저장 프로그램 또한 파일 기반으로 관련했다. 허나 이 데이터들은 변경 작업에 트랜잭션을 지원하지 않았기에 변경 과정에서 종료되면 데이터베이스 테이블이 깨지는 현상이 발생했다.

8.0 버전 부터는 테이블 구조 정보, 저장 관련 프로그램 관련 정보를 InnoDB 테이블에 저장하도록 함

profile
Code Everyday

0개의 댓글