Contents
Real MySQL - 아키텍쳐
   May 18, 2023     3 min read

4장 아키텍쳐

⚓️서론

  • MySQL 서버
    • 머리 = MySQL 엔진
    • 손발 = 스토리지 엔지

MySQL 서버에서 기본으로 제공하는 InnoDB 스토리지 엔진, MyISAM 스토리지 엔진을 알아보자.


✅ MySQL 엔진아키텍쳐

MySQL 서버는 다른 DBMS에 비해 구조가 독특하다.

사용자의 입장에서 보면 거의 차이가 느껴지지 않지만 DBMS에서는 가질 수 없는 엄청난 혜택을 누릴 수 있으며,

반대로 다른 DBMS에서는 문제되지 않을 것들이 가끔 문제가 되기도 한다.

Untitled

➡️ MySQL 엔진

  • 커넥션 핸들러 : 클라이언트로부터의 접속 및 쿼리 요청을 처리
  • SQL 파서
  • SQL 전처리기
  • 옵티마이저 : 쿼리를 최적화해서 실행

➡️ 스토리지 엔진

  • 실제 데이터를 디스크 스토리지에 저장하는 작업 OR 디스크 스토리지로부터 데이터를 읽어오는 작업
  • MySQL 엔진은 하나, 스토리지 엔진은 여러 개를 동시에 사용할 수 있다.

  • 모든 읽기 작업이나 변경 작업은 정의된 스토리지 엔진이 처리한다.

mysql> CREATE TABLE test_table (fd1 INT, fd2 INT) ENGINE=INNODB;

  • 각 스토리지 엔진은 성능 향상을 위해..
    • MyISAM : 키 캐시을 내장
    • InnoDB : 버퍼 풀을 내장

➡️ 핸들러 API

MySQL 엔진의 쿼리 실행기에서 데이터를 쓰거나 읽어야 할 때는 각 스토리지 엔진에 쓰기 또는 읽기를 요청하는데, 이러한 요청을 핸들러(Handler) 요청이라 한다.

여기서 사용되는 API를 핸들러 API라고 한다.

  • 핸들러 목록
show global status like 'Handler%';

Untitled


✅MySQL 스레딩 구조

Untitled

➡️ 포그라운드(Foreground)

  • 최소한 MySQL 서버에 접속된 클라이언트의 수만큼 존재한다.(하나의 커넥션의 작업을 병렬로 처리할 수도 있다)
  • 주로 각 클라이언트 사용자가 요청하는 쿼리 문장을 처리한다.
  • 커넥션을 종료하면 커넥션을 담당하면 스레드는 다시 스레드 캐시(Thread cache)로 되돌아간다. 만약에 이미 스레드 캐시에 일정 개수 이상의 대기 중인 스레드가 있으면 스레드 캐시에 넣지 않고 스레드를 종료시켜 일정 개수의 스레드만 스레드 캐시에 존재하게 된다.
  • thread_cache_size 시스템 변수로 설정으로 최대 스레드 개수 설정 가능
  • 데이터를 MySQL의 데이터 버퍼나 캐시로부터 가져온다. 버퍼나 캐시가 없을 경우에는 직접 디스크의 데이터나 인덱스 파일로부터 데이터를 읽어와서 작업을 처리한다.
MyISAM 테이블InnoDB 테이블
디스크 쓰기 작업까지 포그라운드 스레드가 처리(지연된 쓰기 방식이 있지만 일반적인 방법이 아님)데이터 버퍼나 캐시까지만 포그라운드 스레드가 처리, 나머지 버퍼로부터 디스크까지 기록하는 작업은 백그라운드가 함
  • 🚨참고

    MySQL에서 사용자 스레드와 포그라운드 스레드는 똑같은 의미로 사용된다. 클라이언트가 MySQL 서버에 접속하게 되면 MySQL 서버는 그 클라이언트의 요청을 처리해 줄 스레드를 생성해 그 클라이언트에게 할당한다.

➡️ 백그라운드(Background)

 

  • InnoDB 작업이 백그라운드로 처리
    • 인서트 버퍼(Insert Buffer)를 병합하는 스레드
    • 로그를 디스크로 기록하는 스레드
    • InnoDB 버퍼 풀의 데이터를 디스크에 기록하는 스레드
    • 데이터를 버퍼로 읽어 오는 스레드
    • 잠금이나 데드락을 모니터링하는 스레드
  • 위 목록 중 가장 중요한 것을 뽑으면 로그 스레드(Log thread)쓰기 쓰레드(Write thread) 이다.
  • MySQL 5.5 버전부터 데이터 쓰기 스레드와 데이터 읽기 스레드의 개수를 2개 이상 지정 가능해졌다.
    • 시스템 변수 threadsinnodb_read_io_threads 로 스레드의 개수를 설정가능
    • 쓰기 스레드는 아주 많은 작업을 처리하기 때문에 일반적인 내장 디스크를 사용할 때는 2~4 정도 설정이 좋다.

✅메모리 할당 및 사용 구조

Untitled

➡️MySQL 메모리 공간

  1. 글로벌 메모리 영역
  2. 로컬 메모리 영역

MySQL 메모리 공간은 크게 글로벌 메모리 영역과 로컬 메모리 영역으로 나뉜다.

MySQL서버가 시작되면서 운영체제로부터 할당된다.

  • 할당 방법(운영 체제마다 다름)
    • 요청된 메모리 공간을 100% 할당해주는 방법
    • 요청된 메모리 공간만큼 예약이 되고 필요할 때마다 할당해주는 방법

➡️ 글로벌 메모리 영역

  • 클라이언트 스레드의 수와 무관하게 하나의 메모리 공간만 할당
    • 단, 필요에 따라 2개 이상의 메모리 공간을 할당 받을 수도 있음.
  • 모든 스레드에 의해 공유 된다.

  • 대표적인 글로벌 메모리 영역
    • 테이블 캐시
    • InnoDB 버퍼 풀
    • InnoDB 어댑티브 해시 인덱스
    • InnoDB 리두 로그 버퍼

➡️ 로컬 메모리 영역

  • 클라이언트 스레드가 쿼리를 처리하는 데 사용하는 메모리 영역
    • 클라이언트 메모리 영역, 세션 메모리 영역 ,커넥션 메모리 영역표현 할 수 있음
  • 스레드 공유 되지 않는다.
  • 각 쿼리의 용도별로 필요할 때만 공간이 할당되고 필요하지 않은 경우에는 MySQL이 메모리 공간을 할당조차도 하지 않을 수도 있다.
    • ex) 커넥션버퍼나 결과버퍼는 커넥션이 열려있는 동안 계속 할당된 상태로 남아있다
    • ex) 소트 버퍼나 조인 버퍼는 해당 쿼리를 실행하는 순간에만 할당하고 해제한다.
  • 대표적인 로컬 메모리 영역
    • 정렬 버퍼(Sort Buffer)
    • 조인 버퍼
    • 바이너리 로그 캐시
    • 네트워크 버퍼

📎참고