난중일기/Back

[Real MySQL 8.0] 4장 - 아키텍처

모집사 2024. 2. 7. 23:50
728x90
반응형

MySQL 서버의 아키텍처 구성을 알아본다. MyISAM과 InnoDB 스토리지 엔진의 차이점에 초점을 맞추어 보았다.

 

  • MySQL 서버는 크게 MySQL엔진, 스토리지 엔진으로 구분된다.
    - MySQL 엔진 : 클라이언트로부터의 접속 및 쿼리 요청을 처리하는 커넥션 핸들러, SQL파서, 옵티마이저가 중심을 이룬다.
    - 스토리지 엔진 : 요청된 SQL문장으 분석하거나 최적화 하고, 실제 데이터를 디스크 스토리지에 저장하거나 데이터를 읽어오는 부분을 처리한다. MySQL엔진은 하나지만, 스토리지 엔진은 여러 개를 동시에 사용할 수 있다.

출처 : https://dev.mysql.com/doc/refman/8.0/en/pluggable-storage-overview.html

 

4.1 MySQL 엔진 아키텍처

  • 핸들러 API : MySQL엔진의 쿼리 실행기에서 데이터를 쓰거나 읽어야 할 때 각 스토리지 엔진에 쓰기 또는 읽기를 요청하는데, 이러한 요청을 핸들러 요청이라고 한다. 이 때 사용되는 API를 핸들러 API라고 한다.
  • MySQL 서버는 프로세스 기반이 아니라 스레드 기반으로 동작한다. 포그라운드 스레드와 백그라운드 스레드로 구분된다.
    (Percona MySQL 서버에서는 전통적인 스레드 풀 모델을 사용할 수도 있다.)
    • 포그라운드 스레드(클라이언트 스레드) : 데이터를 MySQL의 데이터 버퍼나 캐시로부터 가져오며, 버퍼나 캐시에 없는 경우에는 직접 디스크의 데이터나 인덱스 파일로부터 데이터를 가져와서 읽기 작업을 처리한다.
      - MyISAM : 디스크 쓰기 작업까지 포그라운드 스레드가 처리한다.
      - InnoDB : 데이터 버퍼나 캐시까지만 포그라운드 스레드가 처리하고, 나머지 버퍼로부터 디스크까지 기록하는 작업은 백그라운드 스레드가 처리한다.
    • 백그라운드 스레드 : 인서트 버퍼 병합 스레드, 로그를 디스크로 기록하는 스레드, InnoDB 버퍼 풀의 데이터를 디스크에 기록하는 스레드, 데이터를 버퍼로 읽어 오는 스레드, 잠금이나 데드락을 모니터링하는 스레드 등 InnoDB에서는 다양한 작업이 백그라운드로 처리된다.
  • MySQL에서 사용되는 메모리 공간은 글로벌 메모리 영역과 로컬 메모리 영역으로 나뉜다.
    • 글로벌 메모리 영역 : 클라이언트 스레드의 수와 무관하게 하나의 메모리 공간만 할당된다. 생성된 글로벌 영역이 여러개라고 하더라도 모든 스레드에 의해 공유된다.
      - 테이블 캐시, InnoDB버퍼 풀, InnoDB 어댑티브 해시 인덱스, InnoDB 리두 로그 버퍼
    • 로컬 메모리 영역(세션 메모리 영역) : 클라이언트 커넥션으로부터의 요청을 처리하기 위해 사용되는 메모리 영역. 로컬 메모리는 각 클라이언트 스레드별로 독립적으로 할당되며 절대 공유되어 사용되지 않는다. 각 쿼리의 용도별로 필요할 때만 공간이 할당되고 필요하지 않은 경우에는 MySQL이 메모리 공간을 할당조차도 하지 않을 수도 있다.
      - 정렬 버퍼, 조인 버퍼, 바이너리 로그 캐시, 네트워크 버퍼
  • MySQL 에서는 기본적으로 제공하는 스토리지 엔진 이외에도 사용자가 필요에 따라 직접 개발하는 것도 가능하다. 
  • MySQL 8.0부터는 기존의 플로그인 아키텍처를 대체하기 위해 컴포넌트 아키텍처가 지원된다.
  • 쿼리 실행 구조 - 쿼리 파서 -> 전처리기 -> 옵티마이저 -> 쿼리 실행기 -> 스토리지 엔진
    - 쿼리 파서 : 사용자 요청으로 들어온 쿼리 문장을 토큰으로 분리해 트리 형태의 구조로 만들어 내는 작업
    - 전처리기 : 각 토큰을 테이블 이름이나 칼럼 이름, 또는 내장 함수와 같은 개체를 매핑해 해당 객체의 존재 여부와 객체의 접근 권한 등을 확인하는 과정을 이 단계에서 수행한다.
    - 옵티마이저 : 사용자의 요청으로 들어온 쿼리 문장을 저렴한 비용으로 가장 빠르게 처리할지를 결정한다.
    - 실행 엔진 : 각 핸들러에게 요청해서 받은 결과를 또 다른 핸들러 요청의 입력으로 연결하는 역할
    - 핸들러 : 스토리지 엔진
  • 쿼리 캐시 : MySQL 8.0으로 업그레이드 되면서 쿼리 캐시는 MySQL 서버의 기능에서 완전히 제거되었다(관련 시스템 변수 포함).
  • 스레드 풀 : Percona Server의 스레드 풀은 플러그인 형태로 작동하도록 구현되어 있다. 스레드 풀은 내부적으로 사용자의 요청을 처리하는 스레드 개수를 줄여서 동시 처리되는 요청이 많다 하더라도 MySQL 서버의 cpu가 제한된 개수의 스레드 처리에만 집중할 수 있게 해서 서버의 자원 소모를 줄이는 것이 목적이다.
  • 트랜잭션 지원 메타데이터 : MySQL 8.0부터는 테이블이 깨지는 문제점을 해결하기 위해 테이블의 구조 정보나 스토어드 프로그램의 코드 관련 정보를 모두 InnoDB의 테이블에 저장하도록 개선됐다. 

4.2 InnoDB 스토리지 엔진 아키텍처

  • InnoDB는 MySQL에서 사용할 수 있는 스토리지 엔진 중 거의 유일하게 레코드 기반의 잠금을 제공하며, 그 때문에 높은 동시성 처리가 가능하고 안정적이며 성능이 뛰어나다.
  • InnoDB의 모든 테이블은 기본적으로 프라이머리 키를 기준으로 클러스터링되어 저장된다. 쿼리의 실행 계획에서 프라이머리 키는 기본적으로 다른 보조 인덱스에 비해 비중이 높게 설정된다.
    (MyISAM 테이블에서는 프라이머리 키와 세컨더리 인덱스는 구조적으로 아무런 차이가 없다.)
  • InnoDB 스토리지 엔진은 외래 키를 지원한다.
    (MyISAM이나 MEMORY 스토리지 엔진에서는 지원하지 않는다.)
  • MVCC(Multi Version Concurrency Control) : 레코드 레벨의 트랜잭션을 지원하는 DBMS가 제공하는 기능. 하나의 레코드가 여러 버전으로 관리된다. 
    - 레코드가 변경되면 변경되기 이전 내역을 언두 영역에 백업 해 두었다가, 커밋되기 이전까지는 언두 영역의 내역이 조회된다.
    - 레코드가 롤백 되면 언두 영역의 내역을 다시 버퍼 풀로 복구한다.
    - 레코드가 커밋 되었다고 하더라도 언두 영역의 백업 데이터가 항상 삭제되는 것은 아니며, 언두 영역을 필요로 하는 트랜잭션이 하나도 없을 때 비로소 삭제된다.
  • InnoDB 스토리지 엔진은 데드락 감지 스레드를 가지고 있어서 주기적으로 잠금 대기를 검사해 교착 상태에 빠진 트랜잭션들을 찾아서 종료한다.
    - 레코드 레벨 뿐만 아니라 테이블 레벨의 잠금도 감지할 수 있도록 설정이 가능하며, 위 기능을 종료하는 설정도 가능하다.
  • InnoDB 데이터 파일은 MySQL 서버가 시작될 때 항상 자동 복구를 수행한다. 이 단계에서 자동으로 복구될 수 없는 손상이 있다면 자동 복구를 멈추고 MySQL 서버를 종료시킨다. 
    - innodb_force_recovery 시스템 변수를 0~6단계로 설정하여 서버를 시작할 수 있으나, 각 설정값 별로 특이사항을 명확히 인지하고 실행해야 한다.
  • InnoDB 버퍼 풀 : 디스크의 데이터 파일이나 인덱스 정보를 메모리에 캐시해 두는 공간. 이 공간에서 자주 사용하는 페이지를 가짐으로서 랜덤한 디스크 작업을 줄일 수 있다.
    • 버퍼 풀이라는 거대한 메모리 공간을 페이지 크기의 조각으로 쪼개어 InnoDB 스토리지 엔진이 데이터를 필요로 할 때 해당 데이터 페이지를 읽어서 각 조각에 저장한다.
    • 버퍼 풀의 페이지 크기 조각을 관리하기 위해 LRU(Least Recently Used) 리스트와 플러시(Flush) 리스트, 프리(Free) 리스트라는 3개의 자료 구조를 관리한다.
      - LRU : 디스크로부터 한 번 읽어온 페이지를 최대한 오랫동안 InnoDB 버퍼 풀의 메모리에 유지해서 디스크의 읽기를 최소화하는 것이 목적이다.
    • 리두 로그는 파일이 아니라 버퍼에 쓰이기 때문에 버퍼 풀과 리두로그는 밀접한 관계를 맺고 있다.
    • MySQL 서버를 재시작해야하는 경우 기존 버퍼 풀의 내용이 없으면 디스크에서 작업을 해야 하기 때문에 성능이 매우 하락할 수 있다. 그래서 MySQL 5.6 부터는 버퍼 풀 덤프 및 적재 기능이 도입되었다.
728x90
반응형